Customizing and enhancing JAXB classes generated during the WSDL-to-Java process
If you're using JAXB databinding for your SOAP services, CXF's wsdl2java tool provides considerable flexibility in customizing the JAXB-generated Java classes, in general, those which map to the SOAP request and response objects. I'll be showing how this configuration can be added using a wsdl2java run on the eBay WSDL (download). (Not covered in this entry, but if you also or alternatively wish to modify the JAX-WS artifacts (i.e., the port and service classes) consult the wsdl2java command-line options and/or use a JAX-WS binding file.) The tutorial source code can be obtained from GitHub by using the "Clone or Download" button on the project site.
Four methods of configuring JAXB are discussed:
For ease of reference the pom.xml holding many of these customizations is shown below:
There are several command-line options that can modify the generated JAXB objects without need for binding files or custom plugins, calling "xjc -help" at a command line that has the Java SDK in the classpath will give provide a complete list. Command-line options include specifying binding customization files, episode files (although they have limitations with wsdl2java), and changing the desired package name (
-p) for the generated Java classes (this can also be done with binding files, as will be shown later.) Other options include the ability to add SAX Locator information (-XLocator), the @Generated annotation (-mark-generated) and the synchronized keyword (-Xsync-methods) to the exposed methods of the JAXB classes. You can see this configuration done in the pom.xml above via
extraargs elements added to the cxf-codegen-plugin configuration. Note the desired options can either be placed on one line or split into multiple lines.
Command-line option inheritance: The CXF Maven plugin provides an ability via the defaultOptions element to declare settings common for all WSDLs being processed within submodules. Unfortunately an extraargs or xjcArgs element declared at the WSDL level will override all other XJC settings defined at the higher level, so if you do a WSDL-level override of XJC arguments you will also need to include the non-overridden XJC settings present at the higher level.
Customization of the XML Schema-to-Java binding process is covered in Chapter 7 of the JAXB 2.2 specification. The binding customization schema (download) provides a formal definition of the allowed customization elements, however JAXB provides extensions that again can be listed via
xjc -help via command line. The sample binding file referenced by the cxf-codegen-plugin configuration is below. Note that the
#types1 suffix to the
schemaLocation attribute refers to the 1-based count of the xsd:schema element within the wsdl:types section. The JAXB compiler will usually give a helpful error message if the node syntax is incorrectly given.
In addition to the JAXB configuration given in the pom.xml, the above binding file will make the following changes to the generated Java classes:
jaxb:schemaBindings, specifies the Java package that the classes will be a part of. (If not specified, package names derived from the Schema namespaces are used.)
MyRenamedCatalogProductTypewill be the generated Java class for element
CatalogProductType, and gives the class-level JavaDoc comment to be used for it.
errorValueproperty and renames a member variable from the
paramIDspecified in the schema to
You can inspect the changes made by running
mvn clean install on the project and then looking at the generated classes in the target/generated-sources folder.
jaxb:javaType, used in changing the mapping between the schema type and the resulting Java object generated, for example switching from XMLGregorianCalendar to java.util.Date for XML date/time types.
Third party products such as the CXF XJC Extensions and Aleksei Valikov's JAXB2 Basics allow for additional customizations besides the functionality provided by JAXB, such as adding toString() and hashCode() methods to the generated classes. Mr. Valikov provides a wiki page and sample project for integrating JAXB Basics with CXF. (CXF also provides a JAXB wrapper that allows its plugins to be used for pure databinding--i.e., non-JAX-WS--purposes.) The pom.xml for this sample uses plugins from both these libraries, as explained in its comments. Note in the case of the JAXB2 Basics configuration the need to include the jaxb2-basics dependency within the codegen plugin and also jaxb2-basics-runtime as a compile-scope dependency as the plugin generates references to classes provided by the latter that will be needed when running the client.
Checking the source code within the CXF XJC and JAXB2 Basics plugins can provide guidance, in particular the source for any plugins that provide functionality similar to what you are looking for. As with these third party plugins, within the pom.xml you'll probably need to add a new dependency for your plugin to the CXF codegen plugin, and if your plugin generates references to classes that will subsequently be needed at runtime, dependencies to the SOAP client as well.