users@jaxb.java.net

Re: Having problems with duplicate names and types in first attempt using Spring 3.0 Jaxb2Marhaller

From: Wolfgang Laun <wolfgang.laun_at_gmail.com>
Date: Tue, 10 Jan 2012 08:39:24 +0100

Marshalling and unmarshalling puts some contraints and requirements on the
Java classes. "same name" and "must have a no-arg default constructor" are
just two examples.

The JAXB tutorial<http://jaxb.java.net/tutorial/section_5_1-Customizing.htm>should
get you started.

From a quick look at the error messages I get the impression that
refactoring might be one way to improve; other than this, annotation
parameters must be used to resolve ambiguities. Also, some Java API classes
aren't fit for (un)marshalling at all, and you'd be better off to avoid
them, although advanced techniques might get you around some of these
obstacles.

-W


On 10 January 2012 01:32, Stephan Zednik <zednis_at_rpi.edu> wrote:

> Problem: I get the following error message when trying to instantiate a
> org.springframework.oxm.jaxb.Jaxb2Marshaller.
>
> This is my first time trying to use JAXB so I am not sure what annotations
> I need for a basic setup, nor how to ensure my XML is mapped appropriately.
> It seems I am missing some annotations, so I added @XmlElement(name="")
> annotations to the class members, but that did not fix the problem.
>
> How should I correctly annotate GmlEnvelope? What annotations must I add
> to all my classes-to-be-bound? What setup (classes & annotations) would
> best bind to the provided example XML?
>
> I am also not sure my class organization fits the XML structure very
> well, and could use suggestions on improvement.
>
> Thanks,
> Stephan
>
> === TEST FAIL OUTPUT ===
>
> Tests in error:
>
> testUnmarshalling(edu.rpi.tw.mdsa.model.AnalysisSettingsUnmarshallerTest):
> Error creating bean with name 'analysisSettingsMarshaller' defined in class
> path resource [model-context.xml]: Invocation of init method failed; nested
> exception is org.springframework.oxm.UncategorizedMappingException: Unknown
> JAXB exception; nested exception is
> com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 8 counts
> of IllegalAnnotationExceptions
> sun.util.calendar.Era does not have a no-arg default constructor.
> this problem is related to the following location:
> at sun.util.calendar.Era
> at public sun.util.calendar.Era sun.util.calendar.CalendarDate.getEra()
> at sun.util.calendar.CalendarDate
> at sun.util.calendar.BaseCalendar$Date
> at sun.util.calendar.LocalGregorianCalendar$Date
> at private sun.util.calendar.LocalGregorianCalendar$Date
> edu.rpi.tw.mdsa.model.TimePeriod.startTime
> at edu.rpi.tw.mdsa.model.TimePeriod
> Two classes have the same XML type name "date". Use @XmlType.name and
> @XmlType.namespace to assign different names to them.
> this problem is related to the following location:
> at sun.util.calendar.BaseCalendar$Date
> at sun.util.calendar.LocalGregorianCalendar$Date
> at private sun.util.calendar.LocalGregorianCalendar$Date
> edu.rpi.tw.mdsa.model.TimePeriod.startTime
> at edu.rpi.tw.mdsa.model.TimePeriod
> this problem is related to the following location:
> at sun.util.calendar.LocalGregorianCalendar$Date
> at private sun.util.calendar.LocalGregorianCalendar$Date
> edu.rpi.tw.mdsa.model.TimePeriod.startTime
> at edu.rpi.tw.mdsa.model.TimePeriod
> Class has two properties of the same name "lowerLat"
> this problem is related to the following location:
> at public double edu.rpi.tw.mdsa.model.gis.GmlEnvelope.getLowerLat()
> at edu.rpi.tw.mdsa.model.gis.GmlEnvelope
> this problem is related to the following location:
> at private double edu.rpi.tw.mdsa.model.gis.GmlEnvelope.lowerLat
> at edu.rpi.tw.mdsa.model.gis.GmlEnvelope
> Class has two properties of the same name "lowerLon"
> this problem is related to the following location:
> at public double edu.rpi.tw.mdsa.model.gis.GmlEnvelope.getLowerLon()
> at edu.rpi.tw.mdsa.model.gis.GmlEnvelope
> this problem is related to the following location:
> at private double edu.rpi.tw.mdsa.model.gis.GmlEnvelope.lowerLon
> at edu.rpi.tw.mdsa.model.gis.GmlEnvelope
> Class has two properties of the same name "upperLat"
> this problem is related to the following location:
> at public double edu.rpi.tw.mdsa.model.gis.GmlEnvelope.getUpperLat()
> at edu.rpi.tw.mdsa.model.gis.GmlEnvelope
> this problem is related to the following location:
> at private double edu.rpi.tw.mdsa.model.gis.GmlEnvelope.upperLat
> at edu.rpi.tw.mdsa.model.gis.GmlEnvelope
> Class has two properties of the same name "upperLon"
> this problem is related to the following location:
> at public double edu.rpi.tw.mdsa.model.gis.GmlEnvelope.getUpperLon()
> at edu.rpi.tw.mdsa.model.gis.GmlEnvelope
> this problem is related to the following location:
> at private double edu.rpi.tw.mdsa.model.gis.GmlEnvelope.upperLon
> at edu.rpi.tw.mdsa.model.gis.GmlEnvelope
> Class has two properties of the same name "endTime"
> this problem is related to the following location:
> at public sun.util.calendar.LocalGregorianCalendar$Date
> edu.rpi.tw.mdsa.model.TimePeriod.getEndTime()
> at edu.rpi.tw.mdsa.model.TimePeriod
> this problem is related to the following location:
> at private sun.util.calendar.LocalGregorianCalendar$Date
> edu.rpi.tw.mdsa.model.TimePeriod.endTime
> at edu.rpi.tw.mdsa.model.TimePeriod
> Class has two properties of the same name "startTime"
> this problem is related to the following location:
> at public sun.util.calendar.LocalGregorianCalendar$Date
> edu.rpi.tw.mdsa.model.TimePeriod.getStartTime()
> at edu.rpi.tw.mdsa.model.TimePeriod
> this problem is related to the following location:
> at private sun.util.calendar.LocalGregorianCalendar$Date
> edu.rpi.tw.mdsa.model.TimePeriod.startTime
> at edu.rpi.tw.mdsa.model.TimePeriod
>
>
> Context:
>
> I would like to configure a JAXB Marshaller for the following XML for use
> in a Spring 3.0 enabled project.
>
> === Example XML ===
>
> <?xml version="1.0" encoding="UTF-8"?>
> <AnalysisSettings>
> <service id="urn:nasa:giovanni:latlonplot"/>
> <spatialExtent>
> <GeoBoundingBox>
> <south>20.0</south>
> <north>90.0</north>
> <west>0.0</west>
> <east>180.0</east>
> </GeoBoundingBox>
> </spatialExtent>
> <temporalExtent>
> <TimePeriod>
> <startTime>2008-01-01T00:00:00Z</startTime>
> <endTime>2008-01-31T00:00:00Z</endTime>
> </TimePeriod>
> </temporalExtent>
> <variables>
> <Variable>
> <dataset id="urn:nasa:modis:MYD08_D3.005"/>
> <parameter id="urn:nasa:modis:Optical_Depth_Land_And_Ocean_Mean"/>
> </Variable>
> <Variable>
> <dataset id="urn:nasa:modis:M0D08_D3.005"/>
> <parameter id="urn:nasa:modis:Optical_Depth_Land_And_Ocean_Mean"/>
> </Variable>
> </variables>
> </AnalysisSettings>
>
> I think this is the Spring 3.0 configuration I need:
>
> <bean id="analysisSettingsMarshaller" class=
> "org.springframework.oxm.jaxb.Jaxb2Marshaller">
> <property name="classesToBeBound">
> <list>
> <value>edu.rpi.tw.mdsa.model.AnalysisSettings</value>
> <value>edu.rpi.tw.mdsa.model.Service</value>
> <value>edu.rpi.tw.mdsa.model.SpatialExtent</value>
> <value>edu.rpi.tw.mdsa.model.gis.GmlEnvelope</value>
> <value>edu.rpi.tw.mdsa.model.TemporalExtent</value>
> <value>edu.rpi.tw.mdsa.model.TimePeriod</value>
> <value>edu.rpi.tw.mdsa.model.Variable</value>
> <value>edu.rpi.tw.mdsa.model.Variables</value>
> <value>edu.rpi.tw.mdsa.model.Parameter</value>
> <value>edu.rpi.tw.mdsa.model.Dataset</value>
> </list>
> </property>
> <property name="schema" value="classpath:schema/AnalysisSettings.xsd"
> />
> </bean>
>
> Note: not sure I need the SpatialExtent and TemporalExtent classes...
>
> === GmlEnvelope.java ===
>
> package edu.rpi.tw.mdsa.model.gis;
>
> import javax.xml.bind.annotation.XmlElement;
> import javax.xml.bind.annotation.XmlType;
>
> @XmlType(name="GeoBoundingBox")
> public class GmlEnvelope {
>
> @XmlElement(name="south")
> private double lowerLat;
>
>
> @XmlElement(name="west")
> private double lowerLon;
>
>
> @XmlElement(name="north")
> private double upperLat;
>
>
> @XmlElement(name="east")
> private double upperLon;
>
>
> public GmlEnvelope() { }
>
>
> public GmlEnvelope(double lowerLat, double lowerLon, double upperLat,
> double upperLon) {
> this.setLowerLat(lowerLat);
> this.setLowerLon(lowerLon);
> this.setUpperLat(upperLat);
> this.setUpperLon(upperLon);
> }
>
> public double getLowerLat() {
> return lowerLat;
> }
>
> public void setLowerLat(double lowerLat) {
> verifyLatitude(lowerLat);
> this.lowerLat = lowerLat;
> }
>
> public double getLowerLon() {
> return lowerLon;
> }
>
> public void setLowerLon(double lowerLon) {
> verifyLongitude(lowerLon);
> this.lowerLon = lowerLon;
> }
>
> public double getUpperLat() {
> return upperLat;
> }
>
> public void setUpperLat(double upperLat) {
> verifyLatitude(upperLat);
> this.upperLat = upperLat;
> }
>
> public double getUpperLon() {
> return upperLon;
> }
>
> public void setUpperLon(double upperLon) {
> verifyLongitude(upperLon);
> this.upperLon = upperLon;
> }
>
>
> private void verifyLatitude(double latitude) {
> if(latitude > 90 || latitude < -90){
> throw new RuntimeException("latitude value out of range: "+latitude);
> }
> }
>
>
> private void verifyLongitude(double longitude) {
> if(longitude > 180 || longitude < -180) {
> throw new RuntimeException("longitude value out of range: "+longitude);
> }
> }
> }
>
>
> === XSD ===
>
> <?xml version="1.0" encoding="utf-8"?>
> <xsd:schema attributeFormDefault="unqualified" elementFormDefault=
> "qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
> <xsd:element name="AnalysisSettings" type="AnalysisSettingsType" />
> <xsd:complexType name="AnalysisSettingsType">
> <xsd:sequence>
> <xsd:element name="service" type="serviceType" />
> <xsd:element name="spatialExtent" type="spatialExtentType" />
> <xsd:element name="temporalExtent" type="temporalExtentType" />
> <xsd:element name="variables" type="variablesType" />
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="variablesType">
> <xsd:sequence>
> <xsd:element maxOccurs="unbounded" name="Variable" type=
> "variableType" />
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="variableType">
> <xsd:sequence>
> <xsd:element name="dataset" type="datasetType" />
> <xsd:element name="parameter" type="parameterType" />
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="parameterType">
> <xsd:attribute name="id" type="xsd:anyURI" />
> </xsd:complexType>
> <xsd:complexType name="datasetType">
> <xsd:attribute name="id" type="xsd:anyURI" />
> </xsd:complexType>
> <xsd:complexType name="temporalExtentType">
> <xsd:sequence>
> <xsd:element name="TimePeriod" type="TimePeriodType" />
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="TimePeriodType">
> <xsd:sequence>
> <xsd:element name="startTime" type="xsd:dateTime" />
> <xsd:element name="endTime" type="xsd:dateTime" />
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="spatialExtentType">
> <xsd:sequence>
> <xsd:element name="GeoBoundingBox" type="GeoBoundingBoxType" />
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="GeoBoundingBoxType">
> <xsd:sequence>
> <xsd:element name="south" type="xsd:decimal" />
> <xsd:element name="north" type="xsd:decimal" />
> <xsd:element name="west" type="xsd:decimal" />
> <xsd:element name="east" type="xsd:decimal" />
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="serviceType">
> <xsd:attribute name="id" type="xsd:anyURI" />
> </xsd:complexType>
> </xsd:schema>
>