Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB getting Object "" is found in an IDREF property but this object doesnt have an ID

Here is a test case using a file from SCORM for imsmanifest,xml. This XML has been in use for about 5 or more years, and being a standard I don't want to change it unless required to get this to work.

You can find the xsd file here

The error occurs between <organizations default="CYBER4.ORG"> and <organization identifier="CYBER4.ORG">

In my project, this is the entry from my pom.xml for my jaxb version

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.11</version>
</dependency>

to generate the Java code I ran (this is the install of xjc for Ubuntu 14.04)

$ xjc -version
xjc 2.2.4-2
$ xjc -verbose -p org.cyber4.scorm2004.xml.manifest.imscp imscp_v1p2.xsd

The output generates (amongst other things)

public class OrganizationsType {

    @XmlAttribute(name = "default")
    @XmlIDREF
    @XmlSchemaType(name = "IDREF")
    protected Object _default;

}

and

public class OrganizationType {

    @XmlAttribute(name = "identifier", required = true)
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlID
    @XmlSchemaType(name = "ID")
    protected String identifier;

}

This is the test code

package org.cyber4.scorm2004.build;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.cyber4.scorm2004.xml.manifest.imscp.ManifestMetadataType;
import org.cyber4.scorm2004.xml.manifest.imscp.ManifestType;
import org.cyber4.scorm2004.xml.manifest.imscp.ObjectFactory;
import org.cyber4.scorm2004.xml.manifest.imscp.OrganizationType;
import org.cyber4.scorm2004.xml.manifest.imscp.OrganizationsType;
import org.cyber4.scorm2004.xml.manifest.imscp.ResourcesType;

//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;

public class TestSCORMBuilder {

    public static void main(String args[]) {

        try {

            ObjectFactory objectFactory = new ObjectFactory(); 

            /*
             *  <metadata />
             */
            ManifestMetadataType metadataType = objectFactory.createManifestMetadataType();

            /*
             *  <organizations default="CYBER4.ORG">
             *      <organization identifier="CYBER4.ORG" /> 
             *  </organizations>
             */

            // https://java.net/jira/browse/JAXB-872
            OrganizationsType organizationsType = objectFactory.createOrganizationsType();
            organizationsType.setDefault("CYBER4.ORG");

            OrganizationType organizationType = objectFactory.createOrganizationType();
            organizationType.setIdentifier("CYBER4.ORG");

            organizationsType.getOrganization().add(organizationType);

            /*
             * <resources />
             */
            ResourcesType resourcesType = objectFactory.createResourcesType();

            /*
             * <manifest>
             * <metadata/ >
             *  <organizations default="CYBER4.ORG">
             *      <organization identifier="CYBER4.ORG" /> 
             *  </organizations>
             * <resources />
             * <manifest>
             */

            ManifestType manifestType = objectFactory.createManifestType();

            manifestType.setMetadata(metadataType);
            manifestType.setOrganizations(organizationsType);
            manifestType.setResources(resourcesType);

            JAXBContext context = JAXBContext.newInstance("org.cyber4.scorm2004.xml.manifest.imscp");

            Marshaller marshaller = context.createMarshaller();

            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
                    "http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd");

            marshaller.marshal(objectFactory.createManifest(manifestType), System.out);

        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

}

When I run the code I get this error

javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: Object "CYBER4.ORG" is found in an IDREF property but this object doesnt have an ID.]
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:95)
    at org.cyber4.scorm2004.build.TestSCORMBuilder.main(TestSCORMBuilder.java:73)
Caused by: com.sun.istack.internal.SAXException2: Object "CYBER4.ORG" is found in an IDREF property but this object doesnt have an ID.
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:237)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.errorMissingId(XMLSerializer.java:1045)
    at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor$IDREFTransducedAccessorImpl.print(TransducedAccessor.java:275)
    at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor$IDREFTransducedAccessorImpl.print(TransducedAccessor.java:254)
    at com.sun.xml.internal.bind.v2.runtime.property.AttributeProperty.serializeAttributes(AttributeProperty.java:86)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeAttributes(ClassBeanInfoImpl.java:360)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:678)
    at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:143)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:343)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:685)
    at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:143)
    at com.sun.xml.internal.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:145)
    at com.sun.xml.internal.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:115)
    at com.sun.xml.internal.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:317)
    at com.sun.xml.internal.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:324)
    at com.sun.xml.internal.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:60)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:483)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:308)
    ... 3 more

If I comment out line 37

organizationsType.setDefault("CYBER4.ORG");

it generates this XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<manifest xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd">
    <metadata/>
    <organizations>
        <organization identifier="CYBER4.ORG"/>
    </organizations>
    <resources/>
</manifest>

but it's missing the

 default="CYBER4.ORG"

in <organizations> which is required for imsmanifest.xml to be valid.

This looks like this bug but I want to be sure I haven't missed anything.

like image 363
Jim Richards Avatar asked Aug 10 '14 02:08

Jim Richards


1 Answers

default should not contain the id of the object you want to reference, but an object with the same id than the object you want to reference.

Try to replace :

organizationsType.setDefault("CYBER4.ORG");    

with :

OrganizationType o = new OrganizationType()   
o.setIdentifier("CYBER4.ORG");    
organizationsType.setDefault(o);    

If organizationType has already been set you can maybe also try :

organizationsType.setDefault(organizationType);    
like image 51
Julien R Avatar answered Nov 03 '22 10:11

Julien R