Reputation: 43
I am trying to generate a Java class containing the methods toString, equals and hashCode from an XSD file. I got toString working, but I am not able to figure out how to get the CXF plugin to generate the equals and the hashCode methods.
This is my XSD file :
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/messagedefinitions"
xmlns="http://www.example.com/messagedefinitions">
<xs:element name="Message">
<xs:complexType>
<xs:sequence>
<xs:element name="status" type="Status"/>
<xs:element name="id" type="Identifier"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="Status">
<xs:restriction base="xs:string">
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Identifier">
<xs:restriction base="xs:int"/>
</xs:simpleType>
</xs:schema>
My working POM (what does not work is commented out) :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>xsd-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>xsd-demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cxf.version>2.6.1</cxf.version>
<cxf.xjc.plugin.version>2.6.1</cxf.xjc.plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-tools-common</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>xjc-utils</artifactId>
<type>pom</type>
<version>${cxf.xjc.plugin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>${cxf.xjc.plugin.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-plugin</artifactId>
<version>${cxf.xjc.plugin.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>xsdtojava</goal>
</goals>
<configuration>
<sourceRoot>${basedir}/target/generated-sources</sourceRoot>
<xsdOptions>
<xsdOption>
<extension>true</extension>
<xsd>${basedir}/src/main/resources/xsd/Message.xsd</xsd>
<bindingFile>${basedir}/src/main/resources/bindings.xml</bindingFile>
<extensionArgs>
<arg>-Xts:style:multiline</arg>
<!--<arg>-Xequals</arg>-->
<!--<arg>-XhashCode</arg>-->
</extensionArgs>
</xsdOption>
</xsdOptions>
<extensions>
<extension>org.apache.cxf.xjcplugins:cxf-xjc-ts:${cxf.xjc.plugin.version}</extension>
<!--<extension>org.apache.cxf.xjcplugins:cxf-xjc-XhashCode:${cxf.xjc.plugin.version}-->
<!--</extension>-->
<!--<extension>org.apache.cxf.xjcplugins:cxf-xjc-Xequals:${cxf.xjc.plugin.version}-->
<!--</extension>-->
</extensions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The bindings file :
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:version="2.1">
<jaxb:globalBindings>
<xjc:serializable uid="1234"/>
</jaxb:globalBindings>
</jaxb:bindings>
If I un-comment the commented-out lines for the Xequals I get this error :
[ERROR] Failed to execute goal org.apache.cxf:cxf-xjc-plugin:2.6.1:xsdtojava (generate-sources) on project xsd-demo: Could not download extension artifact: Requested download does not exist. Could not find artifact org.apache.cxf.xjcplugins:cxf-xjc-Xequals:jar:2.6.1 in central (http://repo1.maven.org/maven2)
Fine, I realise that the artifact does not exist, but I do not know then how to configure the CXF plugin to generate the equals and hashCode methods. Do you know how I can configure the CXF plugin to generate the equals and hashCode methods ? Thanks in advance for any help.
Upvotes: 2
Views: 8633
Reputation: 476
This download (zip) is a stand-alone Maven project to demonstrate the configuration of the Maven cxf-xjc-plugin from Apache CXF together with the XJC HiSrc BasicJAXB Plugins. Specifically, it configures the following XJC plugins:
Note: After extracting the download to your local folder, you can run the tests and/or the demo using:
mvn -Ptest clean test
mvn -Pexec compile exec:java
Business Model
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/messagedefinitions"
xmlns="http://www.example.com/messagedefinitions"
>
<xs:element name="Message">
<xs:complexType>
<xs:sequence>
<xs:element name="status" type="Status"/>
<xs:element name="id" type="Identifier"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="Status">
<xs:restriction base="xs:string">
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Identifier">
<xs:restriction base="xs:int"/>
</xs:simpleType>
</xs:schema>
By default, XJC generates a JAXB class for each of the above elements using the Object
hashCode, equals and toString methods. At this level, objects are compared by object id. To compare/evaluate the JAXB generated Message
objects by value, the HiSrc BasicJAXB Plugins are configured as <extensionArgs>
in the cxf-xjc-plugin.
<extensionArgs>
<extensionArg>-no-header</extensionArg>
<extensionArg>-XhashCode</extensionArg>
<extensionArg>-Xequals</extensionArg>
<extensionArg>-XtoString</extensionArg>
<extensionArg>-XfluentAPI</extensionArg>
<extensionArg>-XfluentAPI-fluentMethodPrefix=use</extensionArg>
</extensionArgs>
For unit testing, the -XfluentAPI plugin, is also activated, to facilitate the setting of a test instance of the Message
object.
final Object object = getUnmarshaller().unmarshal(sample);
if ( object instanceof Message )
{
Message msi1 = (Message) object;
Message msi2 = OF.createMessage()
.useStatus("PASS")
.useId(1001);
getLogger().debug("MSI1: {}", msi1);
getLogger().debug("MSI2: {}", msi2);
assertEquals(msi1, msi2, "Unmarshaled and Fluent MSIs are equal.");
}
The cxf-xjc-plugin
above explicitly declares several dependencies (not shown) to resolve JAR conflicts between the CXF product and the HiSrc product. Because these products are produced by independent teams, some version conflicts are likely. The download (zip) contains a tool, named ReadJarManifest.java to identify and resolve conflicts. The conflicts have been resolved in the download
sample.
Generate build.log
mvn -Dorg.slf4j.simpleLogger.log.org.apache.cxf.maven_plugin.XSDToJavaMojo=DEBUG -Ptest clean test >build.log
ReadJarManifest.java
Read JAR Manifest from a JAR file or a LOG file.
Usage:
javac ReadJarManifest.java
java ReadJarManifest [jarfile | stdin]
Example:
java ReadJarManifest <build.log
Note: The ReadJarManifest.java tool catches most issues but can also report false conflicts. In this example, the conflict percentage is falsely high because two non-conflicting jars have the same version number but different yet similar names.
Conflict%: 89
file:/home/rick/.m2/repository/org/glassfish/jaxb/txw2/4.0.5/txw2-4.0.5.jar
file:/home/rick/.m2/repository/org/glassfish/jaxb/xsom/4.0.5/xsom-4.0.5.jar
Disclaimer: I am the maintainer of the HiSrc projects.
Upvotes: 0
Reputation: 19
Surely too late for you...but...
I managed to generate hashcode and equals with the plugin cxf-xjc-plugin (as in the question) with org.jvnet.jaxb2_commons:jaxb2-basics:0.7.0
You need org.jvnet.jaxb2_commons:jaxb2-basics:0.7.0 to generate the methods (equals, hashcode) and org.jvnet.jaxb2_commons:jaxb2-basics-runtime:0.7.0 for compilation dependencies
The use of antrun is ugly but i need it to generate a directory for my episode The use of build-helper-maven-plugin is to add generated directory to classpath in eclipse I use a binding file (change it if necessary)
<dependencies>
<dependency>
<groupId>org.apache.cxf.xjcplugins</groupId>
<artifactId>cxf-xjc-ts</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>generate-resources</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo message="Creating directories" />
<mkdir dir="./target/generated/src/main/resources/bindings/" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/target/generated/src/main/java/</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-resource</id>
<phase>generate-sources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>
${basedir}/target/generated/src/main/resources/bindings/</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-plugin</artifactId>
<configuration>
<extensions>
<extension>org.apache.cxf.xjcplugins:cxf-xjc-dv:3.0.3</extension>
<extension>org.apache.cxf.xjcplugins:cxf-xjc-ts:3.0.3</extension>
<extension>org.jvnet.jaxb2_commons:jaxb2-basics:0.7.0</extension>
</extensions>
</configuration>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>xsdtojava</goal>
</goals>
<configuration>
<xsdOptions>
<xsdOption>
<extension>true</extension>
<xsd>${basedir}/src/main/resources/schemas/FluxExportDenormalized.xsd</xsd>
<bindingFile>${basedir}/src/main/resources/bindings/binding.xjb</bindingFile>
<extensionArgs>
<extensionArg>-Xdv</extensionArg>
<extensionArg>-episode</extensionArg>
<extensionArg>${basedir}/target/generated/src/main/resources/bindings/FluxExportTarifDenormalized.episode</extensionArg>
<extensionArg>-Xts</extensionArg>
<extensionArg>-Xequals</extensionArg>
<extensionArg>-XhashCode</extensionArg>
</extensionArgs>
</xsdOption>
<xsdOption>
<extension>true</extension>
<xsd>${basedir}/src/main/resources/schemas/FluxExportNormalized.xsd</xsd>
<extensionArgs>
<extensionArg>-Xdv</extensionArg>
<extensionArg>-b</extensionArg>
<extensionArg>${basedir}/src/main/resources/bindings/binding.xjb</extensionArg>
<extensionArg>-b</extensionArg>
<extensionArg>${basedir}/target/generated/src/main/resources/bindings/FluxExportDenormalized.episode</extensionArg>
<extensionArg>-Xequals</extensionArg>
<extensionArg>-XhashCode</extensionArg>
</extensionArgs>
</xsdOption>
</xsdOptions>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.7.0</version>
</dependency>
</dependencies>
</plugin>
Maybe you need the lifecycle in eclipse to avoid red cross error:
<?xml version="1.0" encoding="UTF-8"?>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-plugin</artifactId>
<versionRange>[2.3.0,)</versionRange>
<goals>
<goal>xsdtojava</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<versionRange>[1.4,)</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
Upvotes: 1
Reputation: 3402
After reading this HOWTO, I got it to work like so:
<build>
<plugins>
<!-- Build WSDL resources (includes XSDs) -->
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<configuration>
<defaultOptions>
<extraargs>
<extraarg>-verbose</extraarg>
<extraarg>-xjc-Xequals</extraarg>
<extraarg>-xjc-XhashCode</extraarg>
</extraargs>
<bindingFiles>
<!-- Shared XSD file bindings -->
<bindingFile>${project.basedir}/src/main/resources/bindings.xjb</bindingFile>
</bindingFiles>
</defaultOptions>
<wsdlOptions>
<wsdlOption>
<wsdl>https://myserver.com/MyService?wsdl</wsdl>
<bindingFiles>
<!-- Specific WSDL file bindings -->
<bindingFile>${project.basedir}/src/main/resources/wsdl-bindings.xml</bindingFile>
</bindingFiles>
</wsdlOption>
</wsdlOptions>
</configuration>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<!-- The generated equals and hashCode methods require some runtime libraries. -->
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-runtime</artifactId>
</dependency>
</dependencies>
Unfortunately, for me, using the jvnet jaxws-maven-plugin is not an option, as our WSDL files are given to us by a 3rd party and they have issues (such as soap:body
elements within wsdl:fault
elements) which cause the standard plugin to choke.
Upvotes: 1
Reputation: 43
I was not able to get the cxf-xjc-plugin to generate the equals and hashCode methods from the XML schema files. I gave up on the cxf-xjc-plugin and turned to the maven-jaxb2-plugin instead. This is the plugin configuration I used :
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.3</version>
<executions>
<execution>
<id>generate</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<extension>true</extension>
<generatePackage>my.package.name</generatePackage>
<args>
<arg>-XtoString</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
</args>
<schemaDirectory>${basedir}/src/main/resources</schemaDirectory>
<schemaIncludes>
<include>xsd/*.xsd</include>
</schemaIncludes>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.4</version>
</plugin>
</plugins>
</configuration>
</execution>
</executions>
</plugin>
Upvotes: 2