users@jaxb.java.net

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

From: Stephan Zednik <zednis_at_rpi.edu>
Date: Mon, 9 Jan 2012 17:32:38 -0700

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>