JAXB, XJC -> create multiple class files - java

I'm using JAXB and XJC for first time.
I would like to generate Java classes from XML file so I use this online helper to generate schema from XML file.
After that I just use this command line to generate Java classes :
xjc myschema.xsd
it's work but I receive only one Java file and many static classes inside it. Is this possible to generate many java files that contain only one classe per file please ?
Thank you

By default JAXB (JSR-222) will create static inner classes for nested complex types to prevent class name conflicts. You can use an external binding file to disable this behaviour.
binding.xml
A binding file allows you to customize how Java classes are generated from an XML schema.
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:globalBindings localScoping="toplevel"/>
</jaxb:bindings>
XJC Call
The -b option is used with the XJC command to specify a binding file.
xjc -b binding.xml myschema.xsd
For More Information
http://blog.bdoughan.com/2011/07/jaxb-xjc-and-nested-classes.html

Related

jaxb - xsd to java class for specified node

I have an XSD file with many ComplexType defined in it. I'm using XJC to generate java classes from the XSD file. It will generate classes for all the CompleXType node defined in the schema file. Is there any way I can use a filter in xjc command so that I can get classes of the specified ComplexType only, Instead of generating classes for the whole XSD file?
You can use binding files to somewhat achieve that:
Use <jaxb:schemaBindings map="false" ... /> to disable generation for the whole namespace/schema
Use <jaxb:class ref="com.acme.foo.Ignore"/> to map "unwanted" classes to some (existing) com.acme.foo.Ignore class.

JAXB episode compilation with include does not work

I have 2 schemas A, B. I'm reusing some A elements in B.
I do not use namespaces.
I'm using
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.9.0</version>
I have have defined an inclusion of schema A in schema B as:
<xs:include schemaLocation="classpath:my.schema.A.xsd"/>
and the catalog as
REWRITE_SYSTEM "classpath:my.schema.A.xsd" "maven:my.schema:schema-a!/A.xsd"
The jaxb configuration goes:
<configuration>
<generatePackage>my.schema.b</generatePackage>
<schemaIncludes>
<includes>B.xsd</includes>
</schemaIncludes>
<episodes>
<episode>
<groupId>my.schema</groupId>
<artifactId>schema-a</artifactId>
</episode>
</episodes>
<catalog>src/main/catalog/catalog.cat</catalog>
</configuration>
The issue is that whenever I specify the episode dependency the schema does not generate any classes even though it contains some B elements I want to generate the classes for.
[INFO] Parsing input schema(s)...
[INFO] Compiling input schema(s)...
[INFO] Cleaning package directories.
[INFO] Finished execution.
When I remove the episode it works well and generates classes for schema A as well - which I indeed want to avoid.
Do you have any suggestions?
A sample was published in Jaxb episodic compilation
Ok, I've checked your example. The problem is that you don't use namespaces.
Check your META-INF/sub-jaxb.episode file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="2.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxb:bindings scd="x-schema::">
<jaxb:schemaBindings map="false">
<jaxb:package name="schema.episode.a"/>
</jaxb:schemaBindings>
<jaxb:bindings scd="person">
<jaxb:class ref="schema.episode.a.Person"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
You see this <jaxb:bindings scd="x-schema::"> and then <jaxb:schemaBindings map="false">. This basically tells XJC "don't map anything in the empty namespace". Since your second schema (b.xsd) also does not use namespaces, when you use a.xsd's episode file (binding above), you suppress generation of code for b.xsd as well.
To sum it up, when using episodes/separate schema compilation you can't put schemas with one namespace into different episodes. This is exactly the issue with include.
This is not a bug in the maven-jaxb2-plugin. I would not also call it a bug in XJC. It's just how episodes work by default.
See my pull request here, it demonstrates episodic compilation, when namespaces are handled accordingly.
Author of the maven-jaxb2-plugin here.
My guess would be that your episode says something like "don't compile namespaces A and B". Please check the binding file inside META-INF in your JAR.
This is pretty advanced usage, there's quite a number of points where this can go wrong. You use:
catalogs
Maven artifact-based schema resolution
episodes
Catalogs and episodes are XJC features, Maven resolution comes from the maven-jaxb2-plugin.
We should try to single out what fails:
Try it just with episodes - extract your schemas and compile "as is", without catalogs and resolver
Just catalogs - extract schema and rewrite to local dirs instead of maven:
Try maven:my.schema:schema-a!/A.xsd as schema location without episodes and catalogs
Obviously another three combinations to try.
If you provide a sample project, I'll investigate (but not within the next 10 days). The best would be to file an issue. I'll be moving the plugin to GitHub so this would be a good place:
https://github.com/highsource/maven-jaxb2-plugin

Unsupported binding namespace while generating class files using xjc

I tried googling without any help. Apologies if there are any duplicates.
I have the following schema header for the file common.xsd
<xs:schema xmlns="http://www.vmware.com/vcloud/v1.5"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:meta="http://www.vmware.com/vcloud/meta"
jaxb:version="2.0"
jaxb:extensionBindingPrefixes="meta"
elementFormDefault="qualified"
targetNamespace="http://www.vmware.com/vcloud/v1.5"
version="1.0">
I am trying to generate class files using xjc command.
xjc -version
xjc version "JAXB 2.1.10 in JDK 6"
JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB 2.1.10 in JDK 6)
I am getting this error.
[info] [ERROR] Unsupported binding namespace "http://www.vmware.com/vcloud/meta". Perhaps you meant "http://java.sun.com/xml/ns/jaxb/xjc"?
[info] line 21 of file:/Users/kcherivirala/vmware/dev/corp/zephyr/services/networkservice/app/vcd-schema/src/main/xsd/vcloud/common.xsd
Any leads on this would be of great help.
The problem is here:
jaxb:extensionBindingPrefixes="meta"
jaxb:extensionBindingPrefixes declares prefixes of the vendor customization namespaces. See this link.
The JAXB RI provides additional customizations that are not defined by
the JAXB specification. Note the following:
These features may only be used when the JAXB XJC binding compiler is
run in the -extension mode.
All of the JAXB RI vendor extensions are defined in the
"http://java.sun.com/xml/ns/jaxb/xjc" namespace.
The namespaces containing extension binding declarations are specified
to a JAXB processor by the occurrence of the global attribute
#jaxb:extensionBindingPrefixes within an instance of
element. The value of this attribute is a whitespace-separated list of
namespace prefixes. For more information, please refer to section
6.1.1 of the JAXB Specification.
You only need this when you customize the binding. For instance you may use xjc:superClass to customize to extend a common super class. In this case, xjc would be in jaxb:extensionBindingPrefixes.
If you just compile your schema, the prefix of your schema will most definitely NOT be in jaxb:extensionBindingPrefixes. So, XJC just complained it was there but was not a binding extension.

XSD to Java custom datatype

I have xsd which contain the following: type="EAIschema:eCodes" where eCodes is another schema. When I compile it using xjc it returns:
"Cannot resolve the name 'EAIschema:eCodes' to a(n) 'type definition' component"
I want to know how to solve this problem
I'm not 100% sure about the error message, but it looks to me as if the JAXB classes for the other XSD were missing. If your XSD uses data structures of the other XSD then your JAXB classes will need those JAXB classes.
Solution: generate/ add the JAXB classes for the other XSD to your classpath.
If those classes are in a separate JAR, make sure it contains an episode file.
When the XJC tool is converting the XML schema(s) to Java classes it will automatically pull in imported/included schemas based on their system id. It those schemas are not available at the specified system id (or its not specified) then you could use an XML catalog.
For More Information
http://blog.bdoughan.com/2011/10/jaxb-xjc-imported-schemas-and-xml.html

superclass missing during xjc class generation;hierarchy inconsistency error

I am a JAXB newbie. For a project, I was given the binding file with the xsd so that I can use the schema classes.
The Jaxb binding file(mainbindings.xjb) looks like this:
<jxb:bindings version="2.0">
<jxb:bindings schemaLocation="main.xsd" node="/xsd:schema">
<jxb:globalBindings fixedAttributeAsConstantProperty="true" collectionType="com.example.Impl" choiceContentProperty="false" typesafeEnumMemberName="generateName" enableFailFastCheck="false" generateIsSetMethod="true" underscoreBinding="asWordSeparator">
<xjc:serializable uid="100"/>
<xjc:superClass name="com.example.mySuperClass"/>
<jxb:javaType name="java.util.Calendar" xmlType="xsd:dateTime" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime"/>
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>
I generated the classes using without xjc compiler errors:
xjc -b mainbindings.xjb -b main.xsd -extension
From this site, I learn that the compiler doesn't generate the superclass:
http://blog.frankel.ch/customize-your-jaxb-bindings
However, when I copy these classes under an eclipse project, I see the following error on most every class:
The hierarchy of the type is inconsistent
I googled for this error and found from this site (http://java.syntaxerrors.info/index.php?title=Inconsistent_hierarchy) that if the superclass doesn't exist then this error pops up.
I tried a refresh as suggested here but the errors still exist.
Also, if the xjc doesn't generate a superclass, how else can this be resolved without me manually creating a random superclass?
Thanks in advance
That extension is intended to have your generated classes extend an existing class. You will need to provide this class. BTW - How are you currently trying to use this extension?

Categories