1

I have several web services I need to integrate with, and I can do this by building web service clients using the wsimport plugin for Maven. The web services in question all reference enterprise-common schema files, so generating a separate client results in duplicate code, where each web service client jar contains an implementation of the same schema.

I wanted to reduce this redundant code, so my first thought was to build a stand-alone jar just with the common code generated from the common schema. The problem here is that when I use maven to generate a web service client from a WSDL, it will still build code for all schemas references by the WSDL - how do I tell maven to not generate code for the common schema files, because the code is already in a referenced library?

I did try this:

<resources>
    <resource>
        <directory>${basedir}/wsdl</directory>
        <excludes>
            <exclude>**/my_schema.xsd</exclude>
        </excludes>
    </resource>
</resources>

But wsimport still generates code for my_schema.xsd even though I created a dependency for the jar that already contains this code:

<dependencies>
    <dependency>
        <artifactId>MyCommonCode</artifactId>
        <groupId>com.myCompany</groupId>
        <version>1.0.0</version>
    </dependency>
</dependencies>
FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
  • Have you done a filter with exclude? or will this not work in your case for some reason – greedybuddha Jun 07 '13 at 16:22
  • @greedybuddha: Yes, I updated with an example of my test. – FrustratedWithFormsDesigner Jun 07 '13 at 16:38
  • If they're all generating in the same place and they end up generating redundant code, don't they all end up overwriting each other without any duplicate code in the end? – Daniel Kaplan Jun 07 '13 at 18:19
  • Also, if you were using wsimport from the command line, how could you avoid this? – Daniel Kaplan Jun 07 '13 at 18:20
  • @tieTYT: I think that would probably be true if all clients were all generated in the same maven project. The layout between maven projects and web service clients is mostly 1:1 (I think the reason was that not all applications need all of the clients, so it was decided to make them more modular). I don't know how I'd avoid this if I were using wsimport from the command line. – FrustratedWithFormsDesigner Jun 07 '13 at 18:24
  • Have a look at [http://stackoverflow.com/questions/17019797/compiling-multiple-wsdls-that-share-a-common-schema][1] [1]: http://stackoverflow.com/questions/17019797/compiling-multiple-wsdls-that-share-a-common-schema – awsome Jun 10 '13 at 10:28

1 Answers1

1

The solution I'm trying out uses episodes. In the POM file for the common schema, I have something like this:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>1.5</version>
<executions>
    <execution>
        <goals>
            <goal>xjc</goal>
         </goals>
         <configuration>
           <bindingDirectory>${basedir}/src/bindings</bindingDirectory>
               <!-- The schema directory or xsd files. --> 
               <schemaDirectory>${basedir}/src/schema</schemaDirectory>
               <!-- The working directory to create the generated java source files. -->
               <outputDirectory>${build.directory}/generated-sources/jaxb</outputDirectory>
               <arguments>-episode "${build.directory}/generated-sources/myCommonSchema.episode"</arguments>
         </configuration>
     </execution>
 </executions>
</plugin>

The key here is <arguments>-episode "${build.directory}/generated-sources/myCommonSchema.episode"</arguments> - this generates an episode file (named "myCommonSchema.episode" in the specified directory). The next step is to copy the episode file to the web service that depends on the common schema, and reference it as a binding file like this:

<plugin>
    <groupId>org.jvnet.jax-ws-commons</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.2</version>
    <executions>
        <execution>
            <id>MyService</id>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>

                <bindingDirectory>${basedir}/src/</bindingDirectory>
                <bindingFiles>
                    <bindingFile>myCommonSchema.episode</bindingFile>
                </bindingFiles>
                <wsdlDirectory>${basedir}/src/wsdl/MyWebService</wsdlDirectory>
                <wsdlFiles>
                    <wsdlFile>MyWebService.wsdl</wsdlFile>
                </wsdlFiles>
                <wsdlLocation>META-INF/wsdl/MyWebService/MyWebService.wsdl</wsdlLocation>
                <sourceDestDir>${project.build.directory}/generated-sources/wsimport</sourceDestDir>
                <verbose>true</verbose>
                <xdebug>true</xdebug>
                <extension>true</extension>
                <xjcArgs>
                    <xjcArg>-Xannotate</xjcArg>
                </xjcArgs>
            </configuration>
        </execution>

I'm still testing with this, but it seems to work. The only awkward part is moving the episode file to the other clients, but there's probably a way to automate that.

FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
  • Did the episode stuff work for you? All I get is that an element has not been found within the imported schema. I have even added the episode stuff into the normal bindings file, as soon as I use `` it starts to fail. – Michael-O Feb 25 '14 at 21:10
  • @Michael-O: Yeah, works for me. Maybe there's a problem with the way the episode file is being created? – FrustratedWithFormsDesigner Feb 25 '14 at 21:23
  • 1
    File is generated by `JAXB`, I have no control over. I stuck with https://java.net/jira/browse/JAX_WS-368 and https://java.net/jira/browse/JAXB-514. What a pain in the ass. – Michael-O Feb 28 '14 at 20:02