JAXB - Element is not turned to a class - java

I'm doing a conversion from maven to gradle,
the project I'm converting is currently using the maven plugin:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.11.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/schema</schemaDirectory>
</configuration>
</plugin>
the following element generates a SomeClass.class file in the target dir:
<xs:element name="SomeClass" type="SomeClassType">
<xs:annotation>
<xs:appinfo>
<meta:content-type>
application/xml;application/json;class=com.example
</meta:content-type>
</xs:appinfo>
<xs:documentation source="since">5.7</xs:documentation>
<xs:documentation xml:lang="en">
...
</xs:documentation>
</xs:annotation>
</xs:element>
For gradle I went for this plugin: https://github.com/jacobono/gradle-jaxb-plugin
which generates source files instead of .class files, which is fine, but it does not generate a class for that specific element
jaxb {
xsdDir = "${projectDir.path - rootDir.path}/src/main/resources/schema"
episodesDir = "${buildDir.path - rootDir.path}/schema/episodes"
xjc {
destinationDir = jaxbDstDir
producesDir = jaxbDstDir
}
}
with:
jaxb 'com.sun.xml.bind:jaxb-core:2.2.11'
jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.11'
jaxb 'com.sun.xml.bind:jaxb-impl:2.2.11'
the dependencies are the same as the maven plugin is using,
other classes are generated okay
Any ideas why?

Related

jaxb2-maven-plugin generating package-info.java with xmlns prefixes

I want to generate java classes with the jaxb2-maven-plugin. I am using the following configuration:
pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<id>SomeID</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<extension>true</extension>
<clearOutputDir>true</clearOutputDir>
<sources>
<source>src/main/xsd/schema.xsd</source>
</sources>
<noGeneratedHeaderComments>true</noGeneratedHeaderComments>
</configuration>
</execution>
</executions>
</plugin>
schema.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://my.target.namespace/uri"
xmlns="http://my.target.namespace/uri"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:h="http://my.uri.for.prefix.h"
xmlns:f="http://my.target.namespace/uri">
<xsd:import namespace="http://my.uri.for.prefix.h" schemaLocation="schema2.xsd"/>
<xsd:complexType name="FooType">
<xsd:sequence>
<xsd:element ref="h:something" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="FooType" type="FooType" />
</xsd:schema>
The Jaxb2 plugin is generating me the following package-info.java:
#javax.xml.bind.annotation.XmlSchema(namespace = "http://my.target.namespace/uri", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package ...;
But, what I want to get is this:
#javax.xml.bind.annotation.XmlSchema(namespace = "http://my.target.namespace/uri", xmlns = {
#XmlNs(prefix="f", namespaceURI="http://my.target.namespace/uri"),
#XmlNs(prefix="h", namespaceURI="http://my.uri.for.prefix.h")
}, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package ...;
import javax.xml.bind.annotation.XmlNs;
The prefixes are missing in my generated file. How to do that? I tried already to create a binding file but this didn't worked how I expected.
Please see this answer on how to solve this problem:
https://stackoverflow.com/a/10812236/1389219
The answer is very well written and easy to follow. Basically you will have to:
Drop jaxb2-maven-plugin in favour of maven-jaxb2-plugin.
Include the jaxb2-namespace-prefix dependency and provide the <arg>-Xnamespace-prefix</arg>.
Write a new bindings.xml file which is only a few lines long.
Your POM file will become more verbose, but it is worth it to have a package-info.java generated the way you require.
As a bonus, there are a heap of additional plugins and dependencies related to maven-jaxb2-plugin that provide extra features. One that I found helpful was jaxb2-rich-contract-plugin that gave the ability to generate builders and make the generated classes immutable*.
* Well, not strictly speaking immutable (as it just changes the setter methods to be package private), but enough to make them feel safer.

JAXB/Maven JAX-WS: global bindings.xml references particular WSDL

I'm using Maven JAXWS plugin and bindings.xml file to override a Java type for a JAXB class field generated from a WSDL, but have a problem when generating Java classes from multiple WSDLs with the JAX-WS Maven plugin.
My project structure is:
- src
- jaxws
- bindings.xml
- main
- resources
- wsdl
- Wsdl1.wsdl
- Wsdl1.xsd
- Wsdl2.wsdl
- Wsdl2.xsd
Wsdl1.wsdl references Wsdl1.xsd, Wsdl2.wsdl references Wsdl2.xsd, the two WSDLs and XSD have nothing in common. The WSDLs and XSDs cannot be modified by me.
I want to override the Java type of a particular field (departureDate) in a particular type (Flight) in Wsdl2.xsd.
My bindings.xml is
<bindings version="2.0" extensionBindingPrefixes="xjc"
xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<globalBindings>
<xjc:javaType name="org.joda.time.LocalDate" xmlType="xs:date"
adapter="my.LocalDateAdapter"/>
<xjc:javaType name="org.joda.time.DateTime" xmlType="xs:dateTime"
adapter="my.DateTimeAdapter"/>
</globalBindings>
<bindings schemaLocation="../main/resources/wsdl/Wsdl2.xsd" node="/xs:schema">
<bindings node="//xs:complexType[#name='Flight']//xs:element[#name='departureDate']">
<xjc:javaType name="org.joda.time.LocalDateTime"
adapter="my.LocalDateTimeAdapter"/>
</bindings>
</bindings>
</bindings>
My Maven configuration is
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlDirectory>${basedir}/src/main/resources/wsdl</wsdlDirectory>
</configuration>
</execution>
</executions>
</plugin>
When I build the module with that configuration, JAX-WS processes the WSDLs one by one, but uses the same bindings.xml for each of them. That way, it fails during processing of Wsdl1 due to the reference to Wsdl2.xsd in bindings.xml.
[INFO] --- jaxws-maven-plugin:2.2:wsimport (default) # my-backend ---
[INFO] Processing: file:/D:/dev/Projects/my-api/my-backend/src/main/resources/wsdl/Wsdl1.wsdl
[INFO] jaxws:wsimport args: [-keep, -s, D:\dev\Projects\my-api\my-backend\target\generated-sources\wsimport, -encoding, UTF-8, -Xnocompile, -b, D:\dev\Projects\my-api\my-backend\src\jaxws\bindings.xml, file:/D:/dev/Projects/my-api/my-backend/src/main/resources/wsdl/Wsdl1.wsdl]
parsing WSDL...
[ERROR] "file:/D:/dev/Projects/my-api/my-backend/src/main/resources/wsdl/Wsdl2.xsd"
is not a part of this compilation. Is this a mistake for "file:/D:/dev/Projects/my-api/my-backend/src/main/resources/wsdl/Wsdl1.wsdl#types?schema1"?
line 11 of file:/D:/dev/Projects/my-api/my-backend/src/jaxws/bindings.xml
If I select just Wsdl2.wsdl for processing by the JAX-WS plugin, then all works fine.
<configuration>
<wsdlDirectory>${basedir}/src/main/resources/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>Wsdl2.wsdl</wsdlFile>
</wsdlFiles>
</configuration>
How can I solve this issue?
Create one execution of wsimport for all the WSDLs except Wsdl2.wsdl and another execution for Wsdl2.wsdl. This way you can have different configurations for each execution and specify the jaxb bindings for each differently.

Can't use jaxb bindings on individual xsd elements

I'm using jaxb to generate java source code from an xsd file.
I want to be able to specify which packages the sources are generated in on a per element basis, however whenever I generate sources I get the following error:
[ERROR] ****/src/main/xjb/common.xjb[8,24]
com.sun.istack.SAXParseException2: compiler was unable to honor this schemaBinding customization. It is attached to a wrong place, or its inconsistent with other bindings.
My bindings file common.xjb is attempting to place the element with the name (attribute value) 'api' in the package 'com.myxml.common.api':
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="../xsd/common/common.xsd" node="/xs:schema">
<jxb:bindings node="//xs:element[#name='api']">
<jxb:schemaBindings>
<jxb:package name="com.myxml.common.api" />
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
My xsd file common.xsd is:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.1" xml:lang="en">
<xs:element name='api'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
And I'm using the following Maven plugin to get everything going:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>schema00-generate</id>
<phase>generate-sources</phase>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<schemaFiles>common/common.xsd</schemaFiles>
<bindingFiles>common.xjb</bindingFiles>
<bindingDirectory>${project.basedir}/src/main/xjb</bindingDirectory>
</configuration>
</execution>
</executions>
</plugin>
Why am I getting this error and how can I resolve it? I don't have any other bindings in use at this stage that I'm aware of.
Elements from the same namespace cannot be mapped to different packages so the package cannot be defined for anything other than the top level

jaxb doesn't generate enums with base integer

I have following xsd:
<xs:simpleType name="resultcode">
<xs:restriction base="xs:integer">
<xs:enumeration value="0" id="Approved_no_error">
<xs:annotation>
<xs:appinfo>
<jxb:typesafeEnumMember name="Approved_no_error"/>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
JAX-B just does nothing, no errors, no warnings just doesn't generate this class. If change base from xs:integer to xs:string then it's ok. But I need exactly integer values.
I generate classes with maven:
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>AuthGateway</id>
<goals>
<goal>xjc</goal>
</goals>
And question 2. JAX-B and IDE (IDEA) doesn't allow whitespaces in id attrribute. Why?
<xs:enumeration value="0" id="Approved_no_error"> - ok
<xs:enumeration value="0" id="Approved no error"> - not ok
Is it correct behaviour?
You can use an external binding file to get the behaviour that you are looking for:
JAXB enumeration with numeric values
http://blog.bdoughan.com/2011/08/jaxb-and-enums.html

control schema file name created by jaxb schemagen maven plugin (maven-jaxb-schemagen-plugin)

I don't seem to be able to work out how to get control the file name of the XSD file created by maven-jaxb-schemagen-plugin. The documentation is a bit sparse.
<groupId>com.sun.tools.jxc.maven2</groupId>
<artifactId>maven-jaxb-schemagen-plugin</artifactId>
<version>1.2</version>
<configuration>
<project>${project}</project>
<destdir>${project.build.directory}/generated-resources/schemas</destdir>
<srcdir>${project.build.sourceDirectory}/my/jaxb/bean/package</srcdir>
<verbose>true</verbose>
</configuration>
It always seems to create a file called schema1.xsd
You need to add schema elements which describe which file should contain the elements of each namespace you have:
<configuration>
[...]
<schemas>
<schema>
<namespace>http://www.example.invalid/2001/05/27/wibble</namespace>
<file>wibble.xsd</file>
</schema>
</schemas>
<configuration>
Assuming you have set the namespace of you components
#XmlRootElement(name = "wobble", namespace="http://www.example.invalid/2001/05/27/wibble")

Categories

Resources