How to avoid the need to specify the WSDL location in a CXF or JAX-WS generated webservice client?
I finally figured out the right answer to this question today.
<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>
<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${project.basedir}/src/main/resources/wsdl/FooService.wsdl</wsdl>
<wsdlLocation>classpath:wsdl/FooService.wsdl</wsdlLocation>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
Notice that I have prefixed the value in wsdlLocation
with classpath:
. This tells the plugin that the wsdl will be on the classpath instead of an absolute path. Then it will generate code similar to this:
@WebServiceClient(name = "FooService",
wsdlLocation = "classpath:wsdl/FooService.wsdl",
targetNamespace = "http://org/example/foo")
public class Foo_Service extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://org/example/foo", "Foo");
public final static QName FooSOAPOverHTTP = new QName("http://org/example/foo", "Foo_SOAPOverHTTP");
static {
URL url = Foo_Service.class.getClassLoader().getResource("wsdl/FooService.wsdl");
if (url == null) {
java.util.logging.Logger.getLogger(Foo_Service.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "classpath:wsdl/FooService.wsdl");
}
WSDL_LOCATION = url;
}
Note that this only works with version 2.4.1 or newer of the cxf-codegen-plugin.
We use
wsdlLocation = "WEB-INF/wsdl/WSDL.wsdl"
In other words, use a path relative to the classpath.
I believe the WSDL may be needed at runtime for validation of messages during marshal/unmarshal.
For those using org.jvnet.jax-ws-commons:jaxws-maven-plugin
to generate a client from WSDL at build-time:
- Place the WSDL somewhere in your
src/main/resources
- Do not prefix the
wsdlLocation
withclasspath:
- Do prefix the
wsdlLocation
with/
Example:
- WSDL is stored in
/src/main/resources/foo/bar.wsdl
- Configure
jaxws-maven-plugin
with<wsdlDirectory>${basedir}/src/main/resources/foo</wsdlDirectory>
and<wsdlLocation>/foo/bar.wsdl</wsdlLocation>