wsimport - how to generate service endpoint classes and JAXB classes in separate projects/folders
Asked Answered
S

4

12

We are using a top-down approach for a project with multiple web services (multiple WSDL's). Each web service needs to be set up as a separate project and deployed as a separate war.

The problem is that the WSDL's share a few common .xsd files. Currently if we run wsimport for each WSDL, the common JAXB classes are being duplicated in each web service project.

Ideally we would want to generate the JAXB classes separately in a common shared project, and then reuse the JAXB classes project in each of the web service projects, but wsimport does not provide the option to skip the JAXB class generation OR to specify a different location for the JAXB classes.

Any thoughts on how I can share the JAXB classes between different JAX-WS web service endpoints?

Spalding answered 21/11, 2011 at 12:18 Comment(3)
I think (but I may be wrong on this) that both options you ask are not possible.The JAXB generation can not be skipped since the web service depends on the various stubs in order to be generated.Also the specification of a different directory would not be an option due to all the imports.My best guess is that you have to refactor the code yourself (manually) for this.But I may be wrong. Let's see if someone knows this for sureHillaryhillbilly
@ChrisAldrich Am using IBM RAD 7.5.5 for this projectSpalding
@user384706 Thanks for your input. I too could not find a way to specify a different location for jax-ws source and jaxb classes source. The last resort would be to manually move / rearrange the generated source code.Spalding
L
15

I know that this question is very old, but I wanted to share the answer for those that are looking. I know it took me a while to find the answer.

As of JAXB 2.1 RI, there's a feature called "episodes" that you can use to facilitate this.

Let's say you have a schema called myschema.xsd. Then you would want to call the following:

xjc -episode myschema.episode myschema.xsd

This also works if you are compiling multiple xsd files using a single call. The call will produce the bindings as well as the myschema.episode file.

The episode file is a special bindings file. You can then use this file with wsimport, like so:

wsimport mywsdl.wsdl -b myschema.episode

wsimport will now use the previously generated JAXB files, and will generate anything that is missing.

See this page for more information.

Lossa answered 30/4, 2012 at 21:30 Comment(0)
O
8

You can achieve this using JAXB/JAX-WS customization. Suppose you have XSD types embedded into WSDL. Then your customization will look like:

<jaxws:bindings version="2.0"
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="../wsdl/some.wsdl">

    <jaxws:package name="org.company.project.ws" />

    <!-- XSD types customization within WSDL -->
    <jaxb:bindings node="//xsd:schema">
        <jaxb:schemaBindings>
            <jaxb:package name="org.company.project.beans" />
        </jaxb:schemaBindings>
    </jaxb:bindings>
</jaxws:bindings>

The above configuration refers the following project directory structure:

+-- binding
|   +-- jaxws-binding.xml
+-- wsdl
|   +-- some.wsdl
+-- src
    ...

If you use org.codehaus.mojo:jaxws-maven-plugin plugin, then you need to specify <bindingDirectory>binding</bindingDirectory>.

In case your XSD is external to WSDL, then you need to specify customizations separately:

+-- binding
|   +-- jaxb-binding.xml
|   +-- jaxws-binding.xml
+-- wsdl
    ...

Then jaxb-binding.xml will look like:

<jaxb:bindings version="1.0"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <jaxb:bindings schemaLocation="my.xsd" node="//xsd:schema">
        <jaxb:schemaBindings>
            <jaxb:package name="org.company.project.beans" />
        </jaxb:schemaBindings>
    </jaxb:bindings>
</jaxb:bindings>
  • For Ant build you simply generate two jars for different packages.
  • As I personally do not know any way to create two JAR artefacts from one Maven project :) then the most simple solution would be for you to generate JAXB classes from XSD in project-beans project and in project-ws project remove generated JAXB classes after wsimport run (you can use ant plugin for that).
Operator answered 21/11, 2011 at 15:46 Comment(2)
Very helpful, especially that you need a separate bindings file for an imported schema. Thank you!Kyd
Very useful, I solved "A class/interface with the same name is already in use" with this solution.Constitutionalism
M
1

Usually what I've seen using the IBM Rational toolset:

Generate all the JAXB and service classes and store them with the service project. Then regenerate the JAXB and service client classes and store them in a client project.

Yes, this is duplication. But I think the reasoning behind it is that it separates the concerns of service providers and service consumers. From a toolset perspective, how do you know if your client is .NET, C++, or Java? Or vice versa. If you are a client, how do you know if the provider is .NET, C++, or Java, etc? You don't. Thus IBM provides this way of separation of concerns.

Now the downside to that is that you have duplicate code, if you happen to have the source for both the service provider and the consumer. This can be a pain to maintain.

So perhaps it would be best to generate the service and the client into a Java project (not a J2EE project or a web project) and make a jar out of it. This way, all the JAXB classes are there (and only once). The WSDL is there (once). The service is there once and can be deployed to the server in either an EAR or WAR. And the client exists in case you want to give that to someone to consume your service. If your client allows for dynamic creation based on the WSDL location, even better.

I've got a post that may help you with that from a wizard driven perspective. It is more related to security, but you may find some helpful tips from it.

Mongrelize answered 21/11, 2011 at 15:34 Comment(0)
W
0

If you're using maven, you can use a plug-in to do that.
Using the JAXB XJC Maven 2 Plugin

Willem answered 21/11, 2011 at 13:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.