4

I'm working on an implementation that will use a wsdl that I have gotten from a vendor. Our project is running on Spring and CXF, and I'd like to create a jar that will allow me to access this vendor's wsdl services, but I'm running into classpath issues.

Using CXF's wsdl2java I am able to generate code that acts like this:

WSDL_LOCATION = new URL("file:SomeService.wsdl");

The service requires the wsdl to be in the classpath, but I would like to bundle it in the jar so that it is distributable as a stand-alone jar. Using the wsdl2java tool, I am able to specify the string in the URL instantiation to whatever I would like. However, I have not found a combination of a custom string and wsdl file location inside the jar that works.

The only way I have gotten this to work as I want is to put the wsdl file in the same folder that the SomeService.class is and use the following line:

WSDL_LOCATION = TrackService.class.getResource("TrackService_v4.wsdl");

However, this has the downside of me having to manually edit the java code and compile it myself. This is undesirable because we would eventually like to make this process part of our maven build and have wsdl2java do the generation and compilation by itself automatically.

I am OK with the wsdl being anywhere in the jar, but I don't know what to pass in to wsdl2java to have it reference a file inside the jar.

Does anyone have any suggestions or experience doing this?

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
Andre Azzolini
  • 95
  • 1
  • 1
  • 6

3 Answers3

3

You need to specify the classpath wsdl location as follows to generate the stubs that uses ClassLoader to load this wsdl as classpath resource:

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>2.4.3</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-bindings-soap</artifactId>
            <version>2.4.3</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
                <sourceRoot>${project.build.directory}/generated-sources/cxf
                </sourceRoot>
                <wsdlOptions>
                    <wsdlOption>
                        <wsdl>${basedir}/yourWSDL.wsdl</wsdl>
                        <extraargs>
                            <extraarg>**-wsdlLocation**</extraarg>
                            <extraarg>**classpath:yourWSDL.wsdl**</extraarg>
                        </extraargs>
                    </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Alexis Pigeon
  • 7,423
  • 11
  • 39
  • 44
Srimathi
  • 247
  • 1
  • 4
  • This makes sense. I'm no longer actively working on the project where I needed this functionality, but I'll accept your answer as it seems to reasonably solve the problem. Thanks! – Andre Azzolini Jan 31 '13 at 18:08
3

I've run into the same issue - I've got the following workaround but I'm still searching for something cleaner.

  1. Keep your wsdls in src/main/resources/wsdl

  2. Do the following when you create your TrackService:

    URL wsdlUrl = TrackService.class.getResource( "/wsdl/TrackService_v4.wsdl" ); TrackService service = new TrackService( wsdlUrl );

The ideal solution would be to pass the location as a <wsdlLocation/> element into the CXF wsdl2java plugin. Then your client code could call the default constructor. However the stub code that is generated does not allow you to specify a wsdl file that is on the classpath.

mtpettyp
  • 5,533
  • 1
  • 33
  • 33
  • For me, the ideal solution would be that someone using a JAR I make that provides a stub for a WSDL wouldn't have to know ANYTHING about the WSDL file. I agree with your workaround (It's the same thing I mentioned in my post), but I don't want to have to specify anything about the .wsdl file outside of the JAR. – Andre Azzolini Feb 27 '11 at 23:19
  • This gives the reasons why you need to package the wsdl files -http://jax-ws.java.net/faq/index.html#wsdl_at_runtime. At least they're looking into making it a little cleaner in the future. – mtpettyp Feb 28 '11 at 02:11
2

The CXF Documentation solves it in the same way:

 URL wsdl = getClass().getResource("wsdl/greeting.wsdl");
 SOAPService service = new SOAPService(wsdl, serviceName);

Another option provided is the JaxWsProxyFactoryBean:

JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
proxyFactory.setServiceClass(MyService.class);
proxyFactory.setWsdlLocation("/wsdl/MyService.wsdl");

If you also need to adjust the endpoint URL then you could add:

proxyFactory.setAddress("http://192.168.0.2:6666/");
rob2universe
  • 7,059
  • 39
  • 54