Bundling wsdl in jar with CXF wsdl2java
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 wha开发者_运维知识库tever 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?
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>
I've run into the same issue - I've got the following workaround but I'm still searching for something cleaner.
Keep your wsdls in src/main/resources/wsdl
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.
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/");
精彩评论