26

I have a JAX-WS-driven web service whose WSDL we generate a web service client from in another Maven module (which I'll call ws-consumer).

For better or worse, we copy the "published WSDLs" (the version of the WSDL & XSDs that the service held/generated at point of release) to our src/wsdl folder of ws-consumer and then use jaxws-maven-plugin from org.jvnet to generate a client using jaxws:wsimport with the following (truncated) configuration:

    <plugin>
        <groupId>org.jvnet.jax-ws-commons</groupId>
        <artifactId>jaxws-maven-plugin</artifactId>
        <version>2.1</version>
        <executions>
            <execution>
                <!--phase>generate-sources</phase -->
                <goals>
                    <goal>wsimport</goal>
                </goals>
                <configuration>
                    <wsdlDirectory>src/main/resources/META-INF/wsdl/</wsdlDirectory>
                    <wsdlFiles>
                        <wsdlFile>MyWS/MyWS.wsdl</wsdlFile>
                    </wsdlFiles>
                </configuration>
            </execution>
        </executions>
    </plugin>

Now, the generated client code has the following annotations applied at the class level:

@WebServiceClient(name = "MyWS", targetNamespace = "http://myws/blah", wsdlLocation = "**file:/C:/some/absolute/path/src/main/resources/META-INF/wsdl/MyWS/MyWS.wsdl"**)

emphasis mine

As you can hopefully see, the wsdlLocation attribute value has a hard-coded absolute path that is going to be incorrect when the service is deployed.

Is there any way I can "control" this by setting it to just META-INF/wsdl/MyWS/MyWS.wsdl or some other value?

Alex
  • 8,093
  • 6
  • 49
  • 79

5 Answers5

17

It is possible with the Codehaus plugin:

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>jaxws-maven-plugin</artifactId>
   <version>1.9</version>
   <executions>
     <execution>
       <goals>
         <goal>wsimport</goal>
       </goals>
     </execution>
   </executions>
   <configuration>
     <keep>true</keep>
     <verbose>true</verbose>
     <wsdlDirectory>../wscontract/src/main/resources/wsdl</wsdlDirectory>
     <wsdlLocation>wsdl/MaintainAddress.wsdl</wsdlLocation>
     <sourceDestDir>src/main/java</sourceDestDir>
     <bindingDirectory>.</bindingDirectory>
     <bindingFiles>
       <bindingFile>jaxb/xsdbindings.xml</bindingFile>
       <bindingFile>jaxb/wsdlbindings.xml</bindingFile>
     </bindingFiles>
   </configuration>
</plugin>

Perhaps the plugin you are using has a similar option or perhaps you can consider switching.

You can also provision your WSDL explicitly, in which case this property is ignored, though that may not be appropriate in a container-managed application.

Sample code here.

McDowell
  • 107,573
  • 31
  • 204
  • 267
  • This was basically the answer. jaxws-maven-plugin provides wsdlLocation which can wildcard but override the generated WebServiceClient.wsdlLocation value. Thanks! – Alex Mar 21 '12 at 15:48
  • 1
    @McDowell - I think the codehaus plugin was migrated to jax-ws-commons. Per http://jax-ws-commons.java.net/jaxws-maven-plugin/ : `This plugin contains Maven adapter for JAX-WS's toolset. The original version of this was developed in the codehaus mojo project, but as of March 2007, the project is moved to jax-ws-commons.` – Cheeso Mar 12 '13 at 21:54
  • @atc what did you put in wsdlLocation ? Since we also tried to locate it to the folder where our WSDL is, via 1) add src/main/wsdl and in this case : we have WSDL file (Soap_1.wsdl) in WEB-INF/classes in generated WAR 2) just put the Soap_1.wsdl. But again it's not working. How did you fix it in your case ? – Simeon Angelov May 30 '13 at 07:57
  • Any idea how to handle multiple wsdl file imports? – demaniak May 25 '15 at 07:07
  • 1
    @demaniak `org.jvnet.jax-ws-commons:jaxws-maven-plugin:2.3` derived from the Codehas plugin documents how to use the wsimport goal with multiple WSDLs at https://jax-ws-commons.java.net/jaxws-maven-plugin/examples/using-wsdlLocation.html – McDowell Jun 02 '15 at 15:31
  • 3
    @SimeonAngelov this is really working, but only if you put a preceding "/" into wsdlLocation. So when wsdlDirectory contains "src/main/resources/wsdl", wsdlLocation needs "/wsdl/SoapService.wsdl" – jonashackt May 19 '16 at 15:11
  • @jonashackt how can i set in android backend module which will be deployed to appengine? am getting this error `javax.xml.ws.WebServiceException: Cannot find './src/main/java/webapp/WEB-INF/Checkout.wsdl' wsdl. Place the resource correctly in the classpath.` – Edijae Crusar Jan 14 '17 at 22:04
  • @gikarasojo-kinene What´s the Android backend build with? How do you develop your backend? Does it work on your local machine? Do you have a CI server, where it is also working? And last but not least: is your wsdl placed in `/src/main/java/webapp/WEB-INF/Checkout.wsdl`? Maybe worth another so question? Don´t know, if that one fits well here... – jonashackt Jan 24 '17 at 07:35
  • @jonashackt i ended up setting the remote wsdl location `https://www.xxx.xx?Checkout.wsdl` not my local wsdl location in `/src/main/java/webapp/WEB-INF/Checkout.wsdl` and it worked – Edijae Crusar Jan 24 '17 at 09:06
  • Non of the above worked for me. Instead I used: file:[absolute_path]. – Simon Jul 12 '21 at 14:45
13

Use wsdlLocation with the jaxws-maven-plugin from org.jvnet.jax-ws-commons:

<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.3</version>
<executions>
    <execution>
        <goals>
            <goal>wsimport</goal>
        </goals>
    </execution>
</executions>
<configuration>
    <wsdlDirectory>src/main/resources/wsdl</wsdlDirectory>
    <wsdlFiles>
        <wsdlFile>arsdev.wsdl</wsdlFile>
    </wsdlFiles>
    <wsdlLocation>wsdl/*</wsdlLocation>
    <!-- Keep generated files -->
    <keep>true</keep>
    <packageName>jaxws.remedy.client.generated</packageName>
    <!-- generated source files destination -->
    <sourceDestDir>target/generated-code/src</sourceDestDir>
</configuration>
</plugin>
Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265
Dean Schulze
  • 9,633
  • 24
  • 100
  • 165
1

I voted up for @dean-schulze answer, as it's appropriate for the case of org.jvnet.jax-ws-commons:jaxws-maven-plugin plugin.

It may also be interesting to display help locally with CLI, like this :

mvn jaxws:help -Dgoal=wsimport -Ddetail

As said in the previous answer, we can use the wsdlLocation parameter, described here :

wsdlLocation
  @WebService.wsdlLocation and @WebServiceClient.wsdlLocation value.
  Can end with asterisk in which case relative path of the WSDL will be
  appended to the given wsdlLocation.

  Example:

   ...
   <configuration>
   <wsdlDirectory>src/mywsdls</wsdlDirectory>
   <wsdlFiles>
   <wsdlFile>a.wsdl</wsdlFile>
   <wsdlFile>b/b.wsdl</wsdlFile>
   <wsdlFile>${basedir}/src/mywsdls/c.wsdl</wsdlFile>
   </wsdlFiles>
   <wsdlLocation>http://example.com/mywebservices/*</wsdlLocation>
   </configuration>
   ...
  wsdlLocation for a.wsdl will be http://example.com/mywebservices/a.wsdl
  wsdlLocation for b/b.wsdl will be
  http://example.com/mywebservices/b/b.wsdl
  wsdlLocation for ${basedir}/src/mywsdls/c.wsdl will be
  file://absolute/path/to/c.wsdl


  Note: External binding files cannot be used if asterisk notation is in
  place.

The -wsdllocation option is also documented on the wsimport command from the JDK :

But it just says (see @WebServiceClient javadoc) :

Specifies the @WebServiceClient.wsdlLocation value.
Guillaume Husta
  • 4,049
  • 33
  • 40
0

@dean-schultze answer is correct except it hasn't been updated to reflect the comment by @jonashackt which is that wsdlLocation needs to be prefixed with a slash to be relative to the base. i.e.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <wsdlDirectory>src/main/resources/wsdl</wsdlDirectory>
                <wsdlFiles>
                    <wsdlFile>some.wsdl</wsdlFile>
                </wsdlFiles>
                <wsdlLocation>/wsdl/*</wsdlLocation>
                <packageName>com.example.generated</packageName>
                <sourceDestDir>target/generated-sources/</sourceDestDir>
            </configuration>
        </execution>
    </executions>
</plugin>

Also updated the groupId to codehaus. Stack overflow wouldn't let me edit the original post to try to correct it

MitchBroadhead
  • 811
  • 14
  • 23
-1

Version 1.12 doesn't recognize <wsdlLocation>. It complains:

 No WSDLs are found to process, Specify atleast one of the following parameters: wsdlFiles, wsdlDirectory or wsdlUrls.

Version 1.9 (as in your example) just ignores everything and doesn't produce any code.

Something must have changed.

Dean Schulze
  • 9,633
  • 24
  • 100
  • 165
  • One of the `wsdlFiles`, `wsdlDirectory` or `wsdlUrls` parameters is **required**, since those parameters specify the "physical" location of one or more WSDL files. `wsdlLocation` is used for the value of the `@WebServiceClient.wsdlLocation` annotation **only**. – Florian Wolters Mar 31 '16 at 13:32
  • @FlorianWolters how can i set wsdl file location url in android backend module? i have tried to place it in `src\main\java\webapp` and even `....\webapp\WEB-INF` directory but i get this error `javax.xml.ws.WebServiceException: Cannot find './src/main/java/webapp/WEB-INF/Checkout.wsdl' wsdl. Place the resource correctly in the classpath.` – Edijae Crusar Jan 14 '17 at 22:08
  • @gikarasojo kinene I have no experience with Android development, but if you are using Maven, than the procedure should be the same. I assume you want to create a JAX-WS client? I recommend reading (and looking at the source code) of the following article: https://docs.oracle.com/javaee/7/tutorial/jaxws001.htm. – Florian Wolters Jan 15 '17 at 13:18