How to avoid the need to specify the WSDL location in a CXF or JAX-WS generated webservice client? How to avoid the need to specify the WSDL location in a CXF or JAX-WS generated webservice client? java java

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 with classpath:
  • 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>