How to generate a Java class which implements Serializable interface from xsd using JAXB?
Asked Answered
A

7

48

I would like to introduce caching into an existing Spring project which uses JAXB to expose WebServices. Caching will be done on the level of end points. In order to do that classes generated from XSD using JAXB need to implement Serializable interface and override Object's toString() method.

How to instruct the xjc tool using XSD to generate source with needed properties?

Accalia answered 3/10, 2009 at 15:1 Comment(2)
One of possibilities is to use JAXB plugins (jaxb2-commons.dev.java.net)Dennet
@Dennet and how exactly is this done with jaxb2-commons?Curcio
H
80

Serializable

Use xjc:serializable in a custom bindings file to add the java.io.Serializable interface to your classes along with a serialVersionUID:

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
            xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
            xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
            xsi:schemaLocation="
http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
  <globalBindings>
    <serializable uid="1" />
  </globalBindings>
</bindings> 

toString()

Use a superclass (see xjc:superClass) from which all your bound classes will inherit. This class won’t be generated by xjc so you are free to create it as you please (here with a toString() implementation):

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
                xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
                xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
                xsi:schemaLocation="
http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
    version="2.1">
    <globalBindings>
        <serializable uid="1" />
        <xjc:superClass name="the.package.to.my.XmlSuperClass" />
    </globalBindings>
</bindings>
Harim answered 3/10, 2009 at 15:23 Comment(9)
Thanks for the great answer. Would you use apache commons lang ToStringBuilder's toString builder based on reflection?Prepotency
Yes, it's a good choice in your case (actually, I don't think you have many other options).Harim
Actually, there is: Pojomatic (pojomatic.sourceforge.net/pojomatic/index.html)Prepotency
@Pascal: I believe, in the example one need to say <xjc:serializable ...>, as the default namespace is different from xjc.Dennet
After applying <xjc:superClass...> I've got @XmlValue is not allowed on a class that derives another class. The solution is: add @javax.xml.bind.annotation.XmlTransient annotation to base class (see here: sites.google.com/site/codingkb/java-2/jaxb/jaxb-4)Dennet
Is there a way to tell xjc that only some of the classes extend XMLSuperClass?Wes
For more information about how to use a bindings file in maven, see https://mcmap.net/q/357307/-prefixing-jaxb-generated-classes.Spurgeon
I had to put the answer in a bindings.xml file and add jaxb: in front of the tags (e.g: jaxb:bindings) and xjc:serializable and ran this in the console: xjc -extension -d out -b bindings.xml yourSchema.xsdChemosynthesis
You don't need extensionBindingPrefixes="xjc"?Usurp
C
10

This worked for me:

<?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="1337"/>
    </jaxb:globalBindings>
</jaxb:bindings>
Colvin answered 22/11, 2013 at 11:27 Comment(0)
C
5

Another way to generate toString() method - JAXB2 Basics Plugins. This way looks better because doesn't use reflection. Example how to do it with maven below.

<build>
    <plugins>
        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.8.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <schemaDirectory>
                    ${project.basedir}/src/main/resources
                </schemaDirectory>
                <generateDirectory>
                    ${project.basedir}/src/main/java
                </generateDirectory>
                <extension>true</extension>
                <args>
                    <arg>-XtoString</arg>
                </args>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics</artifactId>
                        <version>0.6.4</version>
                    </plugin>
                </plugins>
            </configuration>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>org.jvnet.jaxb2_commons</groupId>
        <artifactId>jaxb2-basics-runtime</artifactId>
        <version>0.6.4</version>
    </dependency>
</dependencies>

As the result you'll get such code.

public String toString() {
    final ToStringStrategy strategy = JAXBToStringStrategy.INSTANCE;
    final StringBuilder buffer = new StringBuilder();
    append(null, buffer, strategy);
    return buffer.toString();
}

public StringBuilder append(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) {
    strategy.appendStart(locator, this, buffer);
    appendFields(locator, buffer, strategy);
    strategy.appendEnd(locator, this, buffer);
    return buffer;
}

public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) {
    {
        String theName;
        theName = this.getName();
        strategy.appendField(locator, this, "name", buffer, theName);
    }
    {
        String theBank;
        theBank = this.getBank();
        strategy.appendField(locator, this, "bank", buffer, theBank);
    }
    return buffer;
}
Caseinogen answered 9/12, 2012 at 12:14 Comment(0)
D
2

i use this code and is work for me

<?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="1"/><!--If you Forgot this line your class did not be serializable--!>
    </jaxb:globalBindings>
</jaxb:bindings>
Dejected answered 24/9, 2014 at 5:35 Comment(0)
O
1

in order to get interface Serializable add following binding information to the xsd-file:

<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"> <xs:annotation> <xs:appinfo> <jaxb:globalBindings optionalProperty="primitive"> <jaxb:serializable/> </jaxb:globalBindings> </xs:appinfo> </xs:annotation> <xs:element name="myXsdElement"> ..... </xs:element> </xs:schema>

Onehorse answered 1/9, 2016 at 15:23 Comment(0)
N
1

And here is a sample using CXF 3.1.10. Remember to include compile group: 'org.apache.cxf.xjc-utils', name: 'cxf-xjc-runtime', version: '3.1.0'

<jxb:bindings 
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">

<jxb:bindings schemaLocation="META-INF/wsdl/xsd2.xsd">

        <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                <jxb:serializable uid="1"/>
              </jxb:globalBindings>
Numerology answered 28/2, 2017 at 5:8 Comment(0)
L
1

What worked for my project based on jaxb2-maven-plugin:2.5.0 plugin:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>2.5.0</version>
    <executions>
        <execution>
            <id>schema_variations-scopes</id>
            <goals>
                <goal>xjc</goal>
            </goals>
            <configuration>
                ...
                <xjbSources>
                    <xjbSource>src/main/resources/xjc/bindings.xjb</xjbSource>
                </xjbSources>
            </configuration>
        </execution>
    </executions>
</plugin>

and placing bindings.xml file under the path: src/main/resources/xjc/bindings.xjb

<jxb:bindings version="1.0"
              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 
    <jxb:globalBindings generateIsSetMethod="true">
        <xjc:serializable uid="12343"/>
    </jxb:globalBindings>
</jxb:bindings>

Liability answered 10/4 at 9:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.