1
votes

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>
1
Have you done a filter with exclude? or will this not work in your case for some reason - greedybuddha
@greedybuddha: Yes, I updated with an example of my test. - FrustratedWithFormsDesigner
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
Also, if you were using wsimport from the command line, how could you avoid this? - Daniel Kaplan
@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

1 Answers

1
votes

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.