Showing posts with label jaxb. Show all posts
Showing posts with label jaxb. Show all posts

Thursday, March 28, 2013

onliner - JAXBElement XJC Bindings and XMLRootElement creation for any schema

Some schema's do not get generated with the XMLRootElements which can get you into trouble marshalling Java 2 XML. See the error below
Caused by: javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "com.tibco.xmlns.applicationmanagement.ApplicationType" as an element because it is missing an @XmlRootElement annotation]
 at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:317)
 at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:243)
 at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:626)
 ... 25 more
Caused by: com.sun.istack.internal.SAXException2: unable to marshal type "com.tibco.xmlns.applicationmanagement.ApplicationType" as an element because it is missing an @XmlRootElement annotation
 at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:216)
 at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:286)
 at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:462)
 at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:314)
 ... 27 more
[ERROR] 
With the XJC bindings we can fix this however can be tedious going thru all the elements.... Boring.... so lets make a oneliner.... Here a one liner that will solve that and will generate the annotation section for your xcj.bindings or jaxb.bindings... Generating the XMLRootElement on bindings (requirements for perl will be XML::Simple see cpan)
perl -MXML::Simple -e 'BEGIN { use Data::Dumper; } $x=XMLin("./src/main/schema/5.5/ApplicationManagement.xsd");foreach (keys %{$x->{"complexType"}}) { printf "<jaxb:bindings node=\"xs:complexType[\@name=%c%s%c]\">
<annox:annotate><annox:annotate annox:class=\"javax.xml.bind.annotation.XmlRootElement\" name=\"%s\"/></annox:annotate></jaxb:bindings>\n",0x27,$_,0x27,$_ if $_; };'
Generates the output on the console:
<jaxb:bindings node="xs:complexType[=ActionType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="ActionType"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=ServiceType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="ServiceType"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=ServiceInstanceType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="ServiceInstanceType"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=anyObject]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="anyObject"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=ApplicationType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="ApplicationType"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=NVPairType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="NVPairType"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=RepoInstanceType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="RepoInstanceType"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=RemoteRepoInstanceType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="RemoteRepoInstanceType"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=EventType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="EventType"/></annox:annotate></jaxb:bindings>
<jaxb:bindings node="xs:complexType[=BWServiceType]"><annox:annotate><annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="BWServiceType"/></annox:annotate></jaxb:bindings>
Signings-MacBook-Pro:tibco-appmanage-schema $ 
THe end result as a XJC bindings file... which can be included in your XJC generation, in my case the maven plugin:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:annox="http://annox.dev.java.net"
  xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
  version="2.1">
  <jaxb:bindings schemaLocation="ApplicationManagement.xsd"
    node="/xs:schema">
    <jaxb:globalBindings generateIsSetMethod="true"
      collectionType="java.util.ArrayList">
    </jaxb:globalBindings>
    <jaxb:bindings node="xs:complexType[@name=ActionType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="ActionType" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=ServiceType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="ServiceType" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=ServiceInstanceType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="ServiceInstanceType" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=anyObject]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="anyObject" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=ApplicationType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="ApplicationType" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=NVPairType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="NVPairType" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=RepoInstanceType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="RepoInstanceType" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=RemoteRepoInstanceType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="RemoteRepoInstanceType" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=EventType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="EventType" />
      </annox:annotate>
    </jaxb:bindings>
    <jaxb:bindings node="xs:complexType[@name=BWServiceType]">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
          name="BWServiceType" />
      </annox:annotate>
    </jaxb:bindings>
  </jaxb:bindings>
</jaxb:bindings>
And the declaration of the maven plugin....
      <plugin>
        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>
        <version>0.8.3</version>
        <executions>
          <execution>
            <id>generate-domain1</id>
            <goals>
              <goal>generate</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <strict>true</strict>
          <schemaDirectory>src/main/schema/${schema.version}</schemaDirectory>
          <schemaIncludes>
            <value>scm-tibco-project.xsd</value>
          </schemaIncludes>
          <bindingIncludes>
            <include>xjc.bindings</include>
          </bindingIncludes>
          <verbose>true</verbose>
          <extension>true</extension>
          <args>
            <arg>-Xannotate</arg>
            <arg>-Xequals</arg>
            <arg>-XtoString</arg>
            <arg>-XhashCode</arg>
          </args>
          <generateDirectory>${project.build.directory}/generated-sources/xjc
          </generateDirectory>
          <plugins>
            <plugin>
              <groupId>org.jvnet.jaxb2_commons</groupId>
              <artifactId>jaxb2-basics</artifactId>
              <version>0.6.0</version>
            </plugin>
            <plugin>
              <groupId>org.jvnet.jaxb2_commons</groupId>
              <artifactId>jaxb2-basics-annotate</artifactId>
              <version>0.6.0</version>
            </plugin>
          </plugins>
        </configuration>
      </plugin>

Friday, August 17, 2012

Adding XmlRootElement

 
  <plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.7.4</version>
    <executions>
     <execution>
      <id>generate-domain1</id>
      <goals>
       <goal>generate</goal>
      </goals>
      <configuration>
       <strict>true</strict>
       <schemaDirectory>src/main/schema</schemaDirectory>
       <schemaIncludes>
        <value>*.xsd</value>
       </schemaIncludes>
       <bindingIncludes>
        <include>bindings.xjb</include>
       </bindingIncludes>
       <verbose>true</verbose>
       <extension>true</extension>
       <args>
        <arg>-Xannotate</arg>
       </args>
       <generateDirectory>${project.build.directory}/generated-sources/xjc</generateDirectory>
       <plugins>
        <plugin>
         <groupId>org.jvnet.jaxb2_commons</groupId>
         <artifactId>jaxb2-basics</artifactId>
         <version>0.6.0</version>
        </plugin>
        <plugin>
         <groupId>org.jvnet.jaxb2_commons</groupId>
         <artifactId>jaxb2-basics-annotate</artifactId>
         <version>0.6.0</version>
        </plugin>
       </plugins>
      </configuration>
     </execution>
    </executions>
   </plugin>

XJC XmlRootElement and SOAPAction, WebServiceTemplate spring-ws

If you want to create client stubs by means of spring-ws and you do not have the notation of the @Endpoint and @Payload definitions it is sometimes problematic getting the right SOAPAction and XmlRootElement defined.

The first try you can generate with the xjc:simple binding
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.0" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:annox="http://annox.dev.java.net"
jaxb:extensionBindingPrefixes="xjc annox">
<jaxb:globalBindings>
 <xjc:simple />
</jaxb:globalBindings>
 
<!-- FILE: PickupAudit.xsd --> 

 <jaxb:bindings schemaLocation="PickupAudit.xsd" node="/xs:schema">
   <jaxb:bindings node="xs:complexType[@name='PickupAudit']">
      <annox:annotate>
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="PickupAudit" />
      </annox:annotate>
    </jaxb:bindings>
   <jaxb:bindings node="xs:complexType[@name='PickupAuditType']">
      <annox:annotate>
    <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="PickupAudit" />
      </annox:annotate>
    </jaxb:bindings>
  </jaxb:bindings>

</jaxb:bindings>


Generating the @XmlRootElement("something")
<plugin>
 <groupId>org.jvnet.jaxb2.maven2</groupId>
 <artifactId>maven-jaxb2-plugin</artifactId>
 <version>0.7.4</version>
 <executions>
  <execution>
   <id>generate-domain1</id>
   <goals>
    <goal>generate</goal>
   </goals>
   <configuration>
    <strict>true</strict>
    <schemaDirectory>src/main/schema</schemaDirectory>
    <schemaIncludes>
     <value>*.xsd</value>
    </schemaIncludes>
    <bindingIncludes>
     <include>bindings.xjb</include>
    </bindingIncludes>
    <verbose>true</verbose>
    <extension>true</extension>
    <args>
     <arg>-Xannotate</arg>
    </args>
    <generateDirectory>${project.build.directory}/generated-sources/xjc</generateDirectory>
    <plugins>
     <plugin>
      <groupId>org.jvnet.jaxb2_commons</groupId>
      <artifactId>jaxb2-basics</artifactId>
      <version>0.6.0</version>
     </plugin>
     <plugin>
      <groupId>org.jvnet.jaxb2_commons</groupId>
      <artifactId>jaxb2-basics-annotate</artifactId>
      <version>0.6.0</version>
     </plugin>
    </plugins>
   </configuration>
  </execution>
 </executions>
</plugin>

Friday, June 3, 2011

Maven XJC generation XMLSchemaType for date / dateTime missing

I've noticed a mishap with the xsd:date and xsd:dateTime conversions to Java objects. There are posts out there to avoid it or just modify the generated code but thats not what I want.

With the xsd defined as:

The 1.1 version of the com.sun.tools.xjc.maven2:maven-jaxb-plugin will not generate the XMLSchemaType "dateTime" however the 1.1.1 version does generate the correct XMLSchemaType.

By comparison if you choose to use the org.jvnet.jaxb2.maven2:maven-jaxb2-plugin it will generate the XMLSchemaType.

Here the comparison between 1.1 and 1.1.1 of the com.sun.tools.xjc.maven2:maven-jaxb-plugin.



<plugin>
                <groupId>com.sun.tools.xjc.maven2</groupId>
                <artifactId>maven-jaxb-plugin</artifactId>
                <version>1.1.1</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <removeOldOutput>true</removeOldOutput>
                    <schemaDirectory>src/main/schema/</schemaDirectory>
                    <includeSchemas>
                        <includeSchema>**/*.xsd</includeSchema>
                    </includeSchemas>
                    <strict>true</strict>
                    <verbose>false</verbose>
                    <extension>true</extension>
                    <readOnly>yes</readOnly>
                </configuration>
            </plugin>

Thursday, October 21, 2010

JAXB Serializable Binding with Maven

Generating the classes from a xsd where the classes implement the java.io.Serializable interface for serialization between nodes.

.   ---> pom.xml
./.settings
./src
./src/main
./src/main/binding
    ---> binding.xjb
./src/main/java
./src/main/java/com
./src/main/java/META-INF
./src/main/resources
    ---> my.xsd

The maven plugin configuration in the pom.xml
<plugins>
            <plugin>
                <groupid>org.jvnet.jaxb2.maven2</groupid>
                <artifactid>maven-jaxb2-plugin</artifactid>
                <version>0.7.4</version>
                <configuration>
                    <extension>true</extension>
                    <args>
                        <arg>-Xfluent-api</arg>
                    </args>
                    <schemadirectory>src/main/resources</schemadirectory>
                    <bindingdirectory>src/main/binding</bindingdirectory>
                    <plugins>
                        <plugin>
                            <groupid>net.java.dev.jaxb2-commons</groupid>
                            <artifactid>jaxb-fluent-api</artifactid>
                            <version>2.1.8</version>
                        </plugin>
                    </plugins>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>

The content of the binding.xjb
<jxb:bindings 
    version="1.0" 
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    jxb:extensionBindingPrefixes="xjc">
    <jxb:bindings>
        <jxb:globalBindings>
            <xjc:serializable/>
        </jxb:globalBindings>
    </jxb:bindings>
</jxb:bindings>

The result:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "application", propOrder = {
"name",
"version",
"state",
"serverName"
})
public class Application
implements Serializable
{

@XmlElement(required = true)
protected String name;
@XmlElement(required = true)
protected String version;
@XmlElement(required = true)
protected String state;