Discussion:
Why would XJC not generate a class for a root element?
KARR, DAVID
2012-12-07 00:57:37 UTC
Permalink
I have a JAX-RS app that uses XJC to generate classes from 4 different schemas. All four xjc calls in the pom reference a binding file specific to that schema. All 4 schemas are pretty simple, along with very similar binding files, and the reference in the pom. They all define a single top-level "element" element, along with several complexType elements.

For some reason, the processing of one of those schemas is refusing to generate the class corresponding to the root element. I have a complexType that the element references, and it generated the class for that, but not for the element. The other three schemas get the generated class corresponding to the root element.

There are no processing errors.

I'd like to get a solution, but is there some additional debugging I can turn on that might give me some useful information?
Ladislav Lenčucha
2012-12-07 06:18:07 UTC
Permalink
Is the name of the root element and its complex type the same?

Xjc generates 1 class file for xsd document named after the root element
and then separate file for each complexType. If the complextType name is
the same as root element name, the root element file is overwritten..
--
S pozdravom
Ladislav Lenčucha
Post by KARR, DAVID
I have a JAX-RS app that uses XJC to generate classes from 4 different
schemas. All four xjc calls in the pom reference a binding file specific
to that schema. All 4 schemas are pretty simple, along with very similar
binding files, and the reference in the pom. They all define a single
top-level "element" element, along with several complexType elements.
For some reason, the processing of one of those schemas is refusing to
generate the class corresponding to the root element. I have a complexType
that the element references, and it generated the class for that, but not
for the element. The other three schemas get the generated class
corresponding to the root element.
There are no processing errors.
I'd like to get a solution, but is there some additional debugging I can
turn on that might give me some useful information?
KARR, DAVID
2012-12-07 15:04:15 UTC
Permalink
-----Original Message-----
Sent: Thursday, December 06, 2012 10:18 PM
Subject: Re: Why would XJC not generate a class for a root element?
Is the name of the root element and its complex type the same?
Xjc generates 1 class file for xsd document named after the root element
and then separate file for each complexType. If the complextType name is
the same as root element name, the root element file is overwritten..
I never do that. My type names always end with "Type".

The base name of my schema file name is the same as the root element, and the type of the root element has "Type" appended to the name. XJC generated the class for the "Type", but not the root element.
Post by KARR, DAVID
I have a JAX-RS app that uses XJC to generate classes from 4
different
Post by KARR, DAVID
schemas. All four xjc calls in the pom reference a binding file
specific
Post by KARR, DAVID
to that schema. All 4 schemas are pretty simple, along with very
similar
Post by KARR, DAVID
binding files, and the reference in the pom. They all define a
single
Post by KARR, DAVID
top-level "element" element, along with several complexType elements.
For some reason, the processing of one of those schemas is refusing
to
Post by KARR, DAVID
generate the class corresponding to the root element. I have a
complexType
Post by KARR, DAVID
that the element references, and it generated the class for that, but
not
Post by KARR, DAVID
for the element. The other three schemas get the generated class
corresponding to the root element.
There are no processing errors.
I'd like to get a solution, but is there some additional debugging I
can
Post by KARR, DAVID
turn on that might give me some useful informat
Ladislav Lenčucha
2012-12-07 15:22:51 UTC
Permalink
In that case, it would be really useful to know which jaxb version you use
and to see the relevant parts of your Xsd..
--
S pozdravom
Ladislav Lenčucha
Post by KARR, DAVID
-----Original Message-----
Sent: Thursday, December 06, 2012 10:18 PM
Subject: Re: Why would XJC not generate a class for a root element?
Is the name of the root element and its complex type the same?
Xjc generates 1 class file for xsd document named after the root element
and then separate file for each complexType. If the complextType name is
the same as root element name, the root element file is overwritten..
I never do that. My type names always end with "Type".
The base name of my schema file name is the same as the root element, and
the type of the root element has "Type" appended to the name. XJC
generated the class for the "Type", but not the root element.
Post by KARR, DAVID
I have a JAX-RS app that uses XJC to generate classes from 4
different
Post by KARR, DAVID
schemas. All four xjc calls in the pom reference a binding file
specific
Post by KARR, DAVID
to that schema. All 4 schemas are pretty simple, along with very
similar
Post by KARR, DAVID
binding files, and the reference in the pom. They all define a
single
Post by KARR, DAVID
top-level "element" element, along with several complexType elements.
For some reason, the processing of one of those schemas is refusing
to
Post by KARR, DAVID
generate the class corresponding to the root element. I have a
complexType
Post by KARR, DAVID
that the element references, and it generated the class for that, but
not
Post by KARR, DAVID
for the element. The other three schemas get the generated class
corresponding to the root element.
There are no processing errors.
I'd like to get a solution, but is there some additional debugging I
can
Post by KARR, DAVID
turn on that might give me some useful information?
KARR, DAVID
2012-12-07 16:44:33 UTC
Permalink
-----Original Message-----
Sent: Friday, December 07, 2012 7:23 AM
Subject: Re: Why would XJC not generate a class for a root element?
In that case, it would be really useful to know which jaxb version you use
and to see the relevant parts of your Xsd..
I appear to have version 2.1.13 of jaxb-impl and jaxb-xjc.

Here is a slightly translated version of the relevant schema:
-------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.bar.com/automation/foo/schema/config/v1.0"
xmlns:tns="http://www.bar.com/automation/foo/schema/config/v1.0"
elementFormDefault="qualified">
<complexType name="fooConfigType">
<sequence>
<element name="workflowDefinitions" type="tns:workflowDefinitionsType"/>
<element name="channelDefinitions" type="tns:channelDefinitionsType"/>
</sequence>
<attribute name="apiversion" type="string" use="required"/>
</complexType>
<complexType name="workflowDefinitionsType">
<sequence>
<element name="workflowDefinition" type="tns:workflowDefinitionType" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="channelDefinitionsType">
<sequence>
<element name="channelDefinition" type="tns:channelDefinitionType" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="workflowDefinitionType">
<sequence>
<element name="queryFragment" minOccurs="1" />
<element name="queryOrder" minOccurs="1" type="int" />
</sequence>
<attribute name="id" type="ID" use="required" />
<attribute name="name" type="string" use="required" />
<attribute name="label" type="string" use="required" />
<attribute name="order" type="int" use="required" />
<attribute name="render" type="boolean" use="required" />
</complexType>
<complexType name="channelDefinitionType">
<sequence>
<element name="services" minOccurs="1">
<complexType>
<sequence>
<element name="service" type="tns:serviceType" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</sequence>
<attribute name="name" type="string" use="required"/>
</complexType>
<complexType name="workflowAndThresholdsType">
<sequence>
</sequence>
<attribute name="workflow" type="IDREF" use="required"/>
<attribute name="yellow" type="float" use="required"/>
<attribute name="orange" type="float" use="required"/>
<attribute name="red" type="float" use="required"/>
</complexType>
<complexType name="serviceType">
<sequence>
<element name="handlers" minOccurs="1">
<complexType>
<sequence>
<element name="handler" type="string" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
<element name="perfThresholds" type="tns:perfThresholdsType" minOccurs="1"/>
<element name="workflows" minOccurs="1">
<complexType>
<sequence>
<element name="workflow" type="tns:workflowAndThresholdsType" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</sequence>
<attribute name="id" type="ID" use="required"/>
<attribute name="label" type="string" use="required"/>
<attribute name="order" type="int" use="required"/>
</complexType>
<complexType name="perfThresholdsType">
<attribute name="yellow" type="int" use="required"/>
<attribute name="orange" type="int" use="required"/>
<attribute name="red" type="int" use="required"/>
</complexType>
<element name="fooConfig" type="tns:fooConfigType" />
</schema>
-------------------------------

Here's a small excerpt of "mvn -X", when it was parsing this schema and generating the code for it:
----------------------------
parsing a schema...
compiling a schema...
[INFO] generating code
unknown location

com\bar\foo\domain\config\ChannelDefinitionType.java
com\bar\foo\domain\config\ChannelDefinitionsType.java
com\bar\foo\domain\config\ObjectFactory.java
com\bar\foo\domain\config\PerfThresholdsType.java
com\bar\foo\domain\config\ServiceType.java
com\bar\foo\domain\config\FooConfigType.java
com\bar\foo\domain\config\WorkflowAndThresholdsType.java
com\bar\foo\domain\config\WorkflowDefinitionType.java
com\bar\foo\domain\config\WorkflowDefinitionsType.java
com\bar\foo\domain\config\package-info.java
-----------------------------

It generated "FooConfigType.java", but not "FooConfig".

And here is my plugin reference. Note that I am processing 3 other schemas besides this one, but they are all going into different packages. I'm using a locally-built version of the "element wrapper plugin".
-------------------------------------
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-xjc-plugin</artifactId>
<version>2.6.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>xsdtojava</goal>
</goals>
<configuration>
<extensions>
<extension>JAXBXMLElementWrapperPlugin:JAXBXMLElementWrapperPlugin:1.0.0</extension>
</extensions>
<xsdOptions>
<xsdOption>
<xsd>${basedir}/src/main/resources/schema/serviceCallResults.xsd</xsd>
<packagename>com.bar.foo.domain.serviceCallResults</packagename>
<extension>true</extension>
<extensionArgs>
<extensionArg>-Xxew</extensionArg>
<extensionArg>-summary ${basedir}/target/xew-summary.txt</extensionArg>
<extensionArg>-instantiate lazy</extensionArg>
</extensionArgs>
</xsdOption>
<xsdOption>
<xsd>${basedir}/src/main/resources/schema/dataProblems.xsd</xsd>
<packagename>com.bar.foo.domain.dataProblems</packagename>
<extension>true</extension>
<extensionArgs>
<extensionArg>-Xxew</extensionArg>
<extensionArg>-summary ${basedir}/target/xew-summary.txt</extensionArg>
<extensionArg>-instantiate lazy</extensionArg>
</extensionArgs>
</xsdOption>
<xsdOption>
<xsd>${basedir}/src/main/resources/schema/serviceAutoRateCallResults.xsd</xsd>
<packagename>com.bar.foo.domain.autorate</packagename>
<extension>true</extension>
<extensionArgs>
<extensionArg>-Xxew</extensionArg>
<extensionArg>-summary ${basedir}/target/xew-summary.txt</extensionArg>
<extensionArg>-instantiate lazy</extensionArg>
</extensionArgs>
</xsdOption>
<xsdOption>
<xsd>${basedir}/src/main/resources/schema/fooConfig.xsd</xsd>
<packagename>com.bar.foo.domain.config</packagename>
<extension>true</extension>
<extensionArgs>
<extensionArg>-Xxew</extensionArg>
<extensionArg>-summary ${basedir}/target/xew-summary.txt</extensionArg>
<extensionArg>-instantiate lazy</extensionArg>
</extensionArgs>
</xsdOption>
</xsdOptions>
</configuration>
</execution>
</executions>
</plugin>
----------------------
Post by KARR, DAVID
-----Original Message-----
Sent: Thursday, December 06, 2012 10:18 PM
Subject: Re: Why would XJC not generate a class for a root element?
Is the name of the root element and its complex type the same?
Xjc generates 1 class file for xsd document named after the root element
and then separate file for each complexType. If the complextType
name
Post by KARR, DAVID
is
the same as root element name, the root element file is
overwritten..
Post by KARR, DAVID
I never do that. My type names always end with "Type".
The base name of my schema file name is the same as the root element,
and
Post by KARR, DAVID
the type of the root element has "Type" appended to the name. XJC
generated the class for the "Type", but not the root element.
Post by KARR, DAVID
I have a JAX-RS app that uses XJC to generate classes from 4
different
Post by KARR, DAVID
schemas. All four xjc calls in the pom reference a binding file
specific
Post by KARR, DAVID
to that schema. All 4 schemas are pretty simple, along with very
similar
Post by KARR, DAVID
binding files, and the reference in the pom. They all define a
single
Post by KARR, DAVID
top-level "element" element, along with several complexType
elements.
Post by KARR, DAVID
Post by KARR, DAVID
For some reason, the processing of one of those schemas is
refusing
Post by KARR, DAVID
to
Post by KARR, DAVID
generate the class corresponding to the root element. I have a
complexType
Post by KARR, DAVID
that the element references, and it generated the class for that,
but
Post by KARR, DAVID
not
Post by KARR, DAVID
for the element. The other three schemas get the generated class
corresponding to the root element.
There are no processing errors.
I'd like to get a solution, but is there some additional
debugging I
Post by KARR, DAVID
can
Post by KARR, DAVID
turn on that might give me s
KARR, DAVID
2012-12-07 18:37:23 UTC
Permalink
-----Original Message-----
From: KARR, DAVID
Sent: Thursday, December 06, 2012 4:58 PM
Subject: Why would XJC not generate a class for a root element?
I have a JAX-RS app that uses XJC to generate classes from 4 different
schemas. All four xjc calls in the pom reference a binding file
specific to that schema. All 4 schemas are pretty simple, along with
very similar binding files, and the reference in the pom. They all
define a single top-level "element" element, along with several
complexType elements.
For some reason, the processing of one of those schemas is refusing to
generate the class corresponding to the root element. I have a
complexType that the element references, and it generated the class for
that, but not for the element. The other three schemas get the
generated class corresponding to the root element.
There are no processing errors.
I'd like to get a solution, but is there some additional debugging I
can turn on that might give me some useful information?
Hmph. I've got it to work, but I'd like to understand better why I had to do what I did.

Previously, my schema declared the root element and the type of the root element separately, with a reference from the former to the latter. I was reading an old blog entry from Kohsuke (http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html) that talked about possibly using the "xjc:simple" experimental feature in the binding, but it gave me the idea to change the definition so that the type of the root element was declared inline in the element, instead of being standalone. That fixes the problem. It doesn't generate the class for the Type (which I don't need), but it does for the element, which I do need.
Ladislav Lenčucha
2012-12-07 19:28:08 UTC
Permalink
In your case the answer is simple - it is the way jaxb works. It is a
matter of optimization and xml -> java mapping.

Why do you need fooConfig anyway? Imagine 2 scenarios:
1. you have fooConfig root element that is a complexType
2. you have fooConfig root element that is of type fooConfigType

What will happen when you try to unmarshal a xml file?
1. In first case, instance of class named after root element (fooConfig)
will be created, because there is no other way for jaxb to include the
nested elements in java as a class (xsd element without type, declared as
complexType, is in fact handled as anonymous/noname type and these are not
available in java).
2. In 2nd case, instance of object named after root element type
(fooConfigType) will be created, because in fact you don't need wrapper
class - fooConfig from first scenario would extend fooConfigType without
any addition (ok, maybe @XmlRootElement annotation could be added).

If you'd like to force jaxb to create root element type class and also root
element class or you simple want to understand why it doesn't make sense to
create root element class when it is of named type, declare fooConfig as
follows:
<xs:element name="fooConfig">
<xs:complexType>
<xs:complexContent>
<xs:extension base="tns:fooConfigType" />
</xs:complexContent>
</xs:complexType>
</xs:element>

and check fooConfig.java content.
--
S pozdravom
Ladislav Lenčucha
Post by KARR, DAVID
-----Original Message-----
From: KARR, DAVID
Sent: Thursday, December 06, 2012 4:58 PM
Subject: Why would XJC not generate a class for a root element?
I have a JAX-RS app that uses XJC to generate classes from 4 different
schemas. All four xjc calls in the pom reference a binding file
specific to that schema. All 4 schemas are pretty simple, along with
very similar binding files, and the reference in the pom. They all
define a single top-level "element" element, along with several
complexType elements.
For some reason, the processing of one of those schemas is refusing to
generate the class corresponding to the root element. I have a
complexType that the element references, and it generated the class for
that, but not for the element. The other three schemas get the
generated class corresponding to the root element.
There are no processing errors.
I'd like to get a solution, but is there some additional debugging I
can turn on that might give me some useful information?
Hmph. I've got it to work, but I'd like to understand better why I had to do what I did.
Previously, my schema declared the root element and the type of the root
element separately, with a reference from the former to the latter. I was
reading an old blog entry from Kohsuke (
http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html)
that talked about possibly using the "xjc:simple" experimental feature in
the binding, but it gave me the idea to change the definition so that the
type of the root element was declared inline in the element, instead of
being standalone. That fixes the problem. It doesn't generate the class
for the Type (which I don't need), but it does for the element, which I do
need.
KARR, DAVID
2012-12-07 19:39:31 UTC
Permalink
Good explanation. Hopefully this note will be a common search result.

Some comments inline.
-----Original Message-----
Sent: Friday, December 07, 2012 11:28 AM
Subject: Re: Why would XJC not generate a class for a root element?
In your case the answer is simple - it is the way jaxb works. It is a
matter of optimization and xml -> java mapping.
1. you have fooConfig root element that is a complexType
2. you have fooConfig root element that is of type fooConfigType
What will happen when you try to unmarshal a xml file?
1. In first case, instance of class named after root element
(fooConfig)
will be created, because there is no other way for jaxb to include the
nested elements in java as a class (xsd element without type, declared as
complexType, is in fact handled as anonymous/noname type and these are not
available in java).
2. In 2nd case, instance of object named after root element type
(fooConfigType) will be created, because in fact you don't need wrapper
class - fooConfig from first scenario would extend fooConfigType without
If you'd like to force jaxb to create root element type class and also root
element class or you simple want to understand why it doesn't make sense to
create root element class when it is of named type, declare fooConfig as
<xs:element name="fooConfig">
<xs:complexType>
<xs:complexContent>
<xs:extension base="tns:fooConfigType" />
</xs:complexContent>
</xs:complexType>
</xs:element>
and check fooConfig.java content.
Post by KARR, DAVID
-----Original Message-----
From: KARR, DAVID
Sent: Thursday, December 06, 2012 4:58 PM
Subject: Why would XJC not generate a class for a root element?
I have a JAX-RS app that uses XJC to generate classes from 4
different
Post by KARR, DAVID
schemas. All four xjc calls in the pom reference a binding file
specific to that schema. All 4 schemas are pretty simple, along
with
Post by KARR, DAVID
very similar binding files, and the reference in the pom. They all
define a single top-level "element" element, along with several
complexType elements.
For some reason, the processing of one of those schemas is refusing
to
Post by KARR, DAVID
generate the class corresponding to the root element. I have a
complexType that the element references, and it generated the class
for
Post by KARR, DAVID
that, but not for the element. The other three schemas get the
generated class corresponding to the root element.
There are no processing errors.
I'd like to get a solution, but is there some additional debugging
I
Post by KARR, DAVID
can turn on that might give me some useful information?
Hmph. I've got it to work, but I'd like to understand better why I
had to
Post by KARR, DAVID
do what I did.
Previously, my schema declared the root element and the type of the
root
Post by KARR, DAVID
element separately, with a reference from the former to the latter.
I was
Post by KARR, DAVID
reading an old blog entry from Kohsuke (
http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.ht
ml)
Post by KARR, DAVID
that talked about possibly using the "xjc:simple" experimental
feature in
Post by KARR, DAVID
the binding, but it gave me the idea to change the definition so that
the
Post by KARR, DAVID
type of the root element was declared inline in the element, instead
of
Post by KARR, DAVID
being standalone. That fixes the problem. It doesn't generate the
class
Post by KARR, DAVID
for the Type (which I don't need), but it does for the element,
Loading...