I've got a maven project that will consume a number of webservices. The application will be packaged as a WAR. So far the clients' code has been generated with cxf-codegen-plugin
, in the generate-sources
phase. By default, generated sources are placed into target/generated-sources/cxf
, and after compile
, they are compiled and mixed up with the application classes in target/classes
. Both the generated and application classes can share the first level packages.
I'd like each of the clients to be packaged in its own JAR inside WEB-INF/lib
in the WAR file. I found out about -clientjar
, but it only generates the .jar
files and places them into target/generated-sources/cxf
, and the JARs also end up in target/classes
along with the compiled classes, which is pointless.
I suppose the compile
plugin at some point is compiling the generated sources into target/classes
, and possibly another phase is also moving the JARs there. Would it be possible to have Maven avoid compiling those generated sources (or even have cxf-codegen-plugin
generate no sources at all, only the JARs), and compile the application classes against the JARs generated by CXF?
I know it would be possible to achieve this by defining a multimodule project with a jar packaging module for each webservice, but I'd like to avoid this option. There can be a large number of webservices and it would not be suitable to maintain an independent module for each one. With -clientjar
I'm already forced to define a <wsdlOption>
for each WSDL in order to provide the JAR name for each WSDL (it's not possible to let cxf-codegen-plugin
just scan src/main/resources/wsdl
or <wsdlRoot>
).
Of course the client JARs could be generated outside Maven and installed to a local repository, and be defined as dependencies in the project, but I'd like to know if it's possible to do this in a single Maven build.
With assemblies I'd probably sort out how to place the JAR files generated by -clientjar
into WEB-INF/lib
but there would still be an issue with the generated classes inside the WAR.
I don't have a deep knowledge of the Maven build lifecycle and its possibilities, any suggestions or pointers are very much welcome.
This is the approach I took. It isn't exactly what I wanted, there's still lots of manual work to do with every WSDL file and is far from the solution I had in mind (having Maven automatically create individual JAR artifacts for every wsdl in the project and using them as dependency).
Specifically, for each WSDL, this approach needs :
pom.xml
containing a distinct artifact nameI ended up creating an aggregator (multimodule) Maven project, having one module for each WebService Client, that will produce a JAR artifact with the generated WS client classes (following Maven's convention of one artifact per POM).
For convenience, the plugin that will take care of the WebService client classes generation is defined only once in the main pom.xml
, and this POM is the parent of the WS client generation POMs. It is important to note the difference between aggregator and parent POMs. Both concepts are used together in this approach.
There's also a module for the main webapp. Its pom.xml
specifies dependencies for each of the WS client JAR artifacts.
This is the outline of the project's directory tree:
| pom.xml
+-- WSClient1
| | WebService1.wsdl
| | pom.xml
+-- WSClientN
| | WebServiceN.wsdl
| | pom.xml
\---MyWebapp
| src
| pom.xml
The aggregator POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.myproject</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>Aggregator POM</name>
<properties>
<!-- CXF version used for cxf-codegen-plugin -->
<cxf.version>2.7.10</cxf.version>
</properties>
<modules>
<!-- WS Client Modules -->
<module>WSClient1</module>
<module>WSClientN</module>
<!-- WAR Module -->
<module>MyWebapp</module>
</modules>
<!-- Project configuration every child POM will inherit -->
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<!-- WSDL files will be at each project's root level -->
<wsdlRoot>.</wsdlRoot>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Each one of the WS client POMs is extremely simple, just an artifact name and specify the parent:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.myproject</groupId>
<artifactId>wsclient1</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>WebService1 client</name>
<parent>
<groupId>com.example.myproject</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
</parent>
</project>
The webapp's POM doesn't need to be a child of the parent POM because it won't be using the cxf-codegen-plugin
, and includes <dependency>
s for each one of the WS client artifacts:
<dependency>
<groupId>com.example.myproject</groupId>
<artifactId>wsclient1</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.example.myproject</groupId>
<artifactId>wsclientN</artifactId>
<version>1.0.0</version>
</dependency>