SDK + Jaxb serialization issues

skillfulwolverineΛογισμικό & κατασκευή λογ/κού

2 Δεκ 2013 (πριν από 3 χρόνια και 6 μήνες)

158 εμφανίσεις

SDK + Jaxb serialization issues

JaxB Marshaller writes out the XML declaration

Every time toXML is called,
an

XML declaration
(
<?xml version="1.0" encoding="UTF
-
8"
standalone="yes"?>
)
is written out.

Not a bug, but would be nice to make that optional so the
marshaller could be used in situations where the XML it generates will be wrapped by another XML
element (CQL query results, for example).

Sample Code

ApplicationService

service =
ApplicationServi
ceProvider.
getApplicationService
();


String hql =
"From "

+
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project.
class
.getName()
;
// + " p left join fetch p.employeeCollection as
ec
";


List<Object> params =
new

ArrayList<
Object>();


HQLCriteria criteria =
new

HQLCriteria(hql, params);


List<?> results = service.query(criteria);


for

(Object o : results) {


System.
out
.println(
"object class of type "

+
o.getClass().getName());


Marshaller marshaller =
new

JAXBMarshaller(
true
);


String text = marshaller.toXML(o);


System.
out
.println(text);


}

Output

object class of type
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.
Project$$EnhancerByCGLI
B$$88480071

<?xml version="1.0" encoding="UTF
-
8" standalone="yes"?>

<ns2:Project name="Project_Name1" id="1"
xmlns:ns2="gme://caCORE.caCORE/3.2/gov.nih.nci.cacoresdk.domain.manytomany.bi
directional"/>

… snip 9 more …

done

JaxB
Marsha
ller

doesn’t serialize explicitly fetched data

Sample Code

ApplicationService

service =
ApplicationServiceProvider.
getApplicationService
();


String hql =
"From "

+
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project.
class
.getName()
+

" p left join fetch p.employeeCollection"
;


List<Object> params =
new

ArrayList<Object>();


HQLCriteria criteria =
new

HQLCriteria(hql, params);


List<?> results = service.query(criteria);


for

(Object o : result
s) {


System.
out
.println(
"object class of type "

+
o.getClass().getName());


Marshaller marshaller =
new

JAXBMarshaller(
true
);


String text = marshaller.toXML(o);


System.
out
.println(text);


}

Output

object class of type
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project$$EnhancerByCGLI
B$$88480071

<?xml version="1.0" encoding="UTF
-
8" standalone="yes"?>

<ns2:Project name="Project_Name1" id="1"
xmlns:ns2="gme://caCORE.caCO
RE/3.2/gov.nih.nci.cacoresdk.domain.manytomany.bi
directional"/>

… snip 9 more …

done


Pojos with populated associations cause ClassCastException after
passing through XMLUtility.convertFromProxy

Sample Code


ApplicationService service =
Applicat
ionServiceProvider.
getApplicationService
();


String hql =
"From "

+
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project.
class
.getName()
+
" p left join fetch p.employeeCollection"
;


List<Object> params =
new

ArrayList<Object
>();


HQLCriteria criteria =
new

HQLCriteria(hql, params);


List<?> results = service.query(criteria);


for

(Object o : results) {


System.
out
.println(
"object class of type "

+
o.getClass().getName());


Marshaller marshaller =
new

JAXBMarshaller(
true
);


String text = marshaller.toXML(o);


System.
out
.println(text);


Object nonProxy = XMLUtility.
convertFromProxy
(o,
true
);


System.
ou
t
.println(
"non proxy class of type "

+
nonProxy.getClass().getName());


text = marshaller.toXML(nonProxy);


System.
out
.println(text);


}


System.
out
.println(
"done"
);

Output

object class of type
gov.nih.nc
i.cacoresdk.domain.manytomany.bidirectional.Project$$EnhancerByCGLI
B$$72548c5b

15:21:24,485 DEBUG [JAXBCollectionObjectAdapter] Marshal source is null;
returning null

<?xml version="1.0" encoding="UTF
-
8" standalone="yes"?>

<ns2:Project

name="Project_Name1" id="1"
xmlns:ns2="gme://caCORE.caCORE/3.2/gov.nih.nci.cacoresdk.domain.manytomany.bi
directional"/>


15:21:24,491 DEBUG [BaseCastorFieldHandler] domainClassName:
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project

15:21:24,49
1 DEBUG [BaseCastorFieldHandler] *** Converting from proxy
object:
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project$$EnhancerByCGLI
B$$72548c5b

15:21:24,492 DEBUG [BaseCastorFieldHandler] *** setterMethod Name:
setEmployeeCollection; paramete
r type: interface java.util.Collection

15:21:24,508 DEBUG [BaseCastorFieldHandler] *** setterMethod Name: setName;
parameter type: class java.lang.String

15:21:24,508 DEBUG [BaseCastorFieldHandler] *** setterMethod Name: setId;
parameter type: class java
.lang.Integer

non proxy class of type
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project

15:21:24,511 DEBUG [JAXBCollectionObjectAdapter] In JAXB Collection Object
adapter marshall: java.util.ArrayList

15:21:24,511 DEBUG [
JAXBCollectionObjectAdapter] java.util.ArrayList is
initialized as a ListProxy; converting and returning as a HashSet

15:21:24,512 DEBUG [JAXBCollectionObjectAdapter] java.util.ArrayList is
initialized; returning it unmodified

15:21:24,514 ERROR [JAXBMarsh
aller]
JAXBException

caught marshalling
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project

javax.xml.bind.MarshalException


-

with linked exception:

[
com.sun.xml.bind.api.AccessorException
:
java.lang.ClassCastException
:
java.util.ArrayList canno
t be cast to java.util.HashSet]


at
com.sun.xml.bind.v2.runtime.MarshallerImpl.write(
MarshallerImpl.java:320
)


at
com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(
MarshallerImpl.java:246
)


at
javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(
Abstract
MarshallerImpl.
java:96
)


at
gov.nih.nci.system.client.util.xml.JAXBMarshaller.toXML(
JAXBMarshaller.java:6
8
)


at
gov.nih.nci.system.client.util.xml.JAXBMarshaller.toXML(
JAXBMarshaller.java:5
3
)


at test.SerializeTest.main(
SerializeTest.java:33
)

Caused by:
co
m.sun.xml.bind.api.AccessorException
:
java.lang.ClassCastException
: java.util.ArrayList cannot be cast to
java.util.HashSet


at
com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(
XMLSerializer.java:240
)


at
com.sun.xml.bind.v2.runtime.XMLSerializer.repo
rtError(
XMLSerializer.java:255
)


at
com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(
ClassBeanInfoImpl
.java:324
)


at
com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(
XMLSerializer.ja
va:587
)


at

com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(
ClassBeanInfoImpl
.java:312
)


at
com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(
XMLSerializer.java:488
)


at
com.sun.xml.bind.v2.runtime.MarshallerImpl.write(
MarshallerImpl.java:317
)


... 5
more

Caused by:
com.sun.xml.bind.api.AccessorException
:
java.lang.ClassCastException
: java.util.ArrayList cannot be cast to
java.util.HashSet


at
com.sun.xml.bind.v2.runtime.reflect.AdaptedAccessor.get(
AdaptedAccessor.java:
74
)


at
com.sun.xml.bind.v2.runti
me.property.SingleElementNodeProperty.serializeBody(
SingleElementNodeProperty.java:126
)


at
com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(
ClassBeanInfoImpl
.java:322
)


... 9 more

Caused by:
java.lang.ClassCastException
: java.util.ArrayList can
not be cast
to java.util.HashSet


at
gov.nih.nci.system.client.util.xml.JAXBCollectionObjectAdapter.marshal(
JAXBCo
llectionObjectAdapter.java:30
)


at
gov.nih.nci.system.client.util.xml.JAXBCollectionObjectAdapter.marshal(
JAXBCo
llectionObjectAdapter.java:13
)


at
com.sun.xml.bind.v2.runtime.reflect.AdaptedAccessor.get(
AdaptedAccessor.java:
72
)


... 11 more

gov.nih.nci.system.client.util.xml.XMLUtilityException


at
gov.nih.nci.system.client.util.xml.JAXBMarshaller.toXML(
JAXBMarshaller.java:7
3
)


at
gov.nih.nci.sy
stem.client.util.xml.JAXBMarshaller.toXML(
JAXBMarshaller.java:5
3
)


at test.SerializeTest.main(
SerializeTest.java:33
)


Pojos with no populated associations cause schema validation to fail
after passing through XMLUtility.convertFromProxy

Sample Code

// get
a local
API

instance of the SDK


ApplicationService service =
ApplicationServiceProvider.
getApplicationService
();


String hql =
"From "

+
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project.
class
.getName()
;
// + " p left join fetch p.employeeCollection";


List<Object> params =
new

ArrayList<Object>();


HQLCriteria criteria =
new

HQLCriteria(hql, params);


List<?> results = service.query(criteria);


for

(Object o : r
esults) {


System.
out
.println(
"object class of type "

+
o.getClass().getName());


Marshaller marshaller =
new

JAXBMarshaller(
true
);


String text = marshaller.toXML(o);


System.
out
.println(text);


Object nonProxy = XMLUtility.
convertFromProxy
(o,
true
);


System.
out
.println(
"non proxy class of type "

+
nonProxy.getClass().getName());


text = marshaller.toXML(nonProxy);


System.
out
.println(te
xt);


}


System.
out
.println(
"done"
);

Output

object class of type
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project$$EnhancerByCGLI
B$$240de4ec

15:26:22,689 DEBUG [JAXBCollectionObjectAdapter] Marshal source is null;
returning null

<?xml version="1.0" encoding="UTF
-
8" standalone="yes"?>

<ns2:Project name="Project_Name1" id="1"
xmlns:ns2="gme://caCORE.caCORE/3.2/gov.nih.nci.cacoresdk.domain.manytomany.bi
directional"/>


15:26:22,692 DEBUG [BaseCastorFieldHandler] domainC
lassName:
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project

15:26:22,693 DEBUG [BaseCastorFieldHandler] *** Converting from proxy
object:
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project$$EnhancerByCGLI
B$$240de4ec

15:26:22,693
DEBUG [BaseCastorFieldHandler] *** setterMethod Name:
setEmployeeCollection; parameter type: interface java.util.Collection

15:26:22,693 DEBUG [ClassCache] fieldGenericType:
java.util.Collection<gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Em
ploy
ee>

15:26:22,694 DEBUG [DAO] ****** obj: class
gov.nih.nci.system.query.hibernate.HQLCriteria

15:26:22,694 INFO [DAO] HQL Query :select dest from
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project as src inner
join src.employeeCollection dest w
here src=?

15:26:22,707 DEBUG [ApplicationServiceImpl] response.getRowCount(): 1

15:26:22,725 DEBUG [BaseCastorFieldHandler] *** setterMethod Name: setName;
parameter type: class java.lang.String

15:26:22,725 DEBUG [BaseCastorFieldHandler] *** setterMeth
od Name: setId;
parameter type: class java.lang.Integer

non proxy class of type
gov.nih.nci.cacoresdk.domain.manytomany.bidirectional.Project

15:26:22,728 DEBUG [JAXBCollectionObjectAdapter] In JAXB Collection Object
adapter marshall: gov.nih.nci.system.cl
ient.proxy.ListProxy

15:26:22,728 DEBUG [JAXBCollectionObjectAdapter]
gov.nih.nci.system.client.proxy.ListProxy is initialized as a ListProxy;
converting and returning as a HashSet

15:26:22,731 ERROR [JAXBMarshaller]
JAXBException

caught marshalling
gov.ni
h.nci.cacoresdk.domain.manytomany.bidirectional.Project

javax.xml.bind.MarshalException


-

with linked exception:

[
org.xml.sax.SAXParseException
: cvc
-
complex
-
type.2.4.a: Invalid content was
found starting with element 'employeeCollection'. One of
'{"gme://
caCORE.caCORE/3.2/gov.nih.nci.cacoresdk.domain.manytomany.bidirectio
nal":employeeCollection}' is expected.]


at
com.sun.xml.bind.v2.runtime.MarshallerImpl.write(
MarshallerImpl.java:320
)


at
com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(
MarshallerImpl.
java:246
)


at
javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(
AbstractMarshallerImpl.
java:96
)


at
gov.nih.nci.system.client.util.xml.JAXBMarshaller.toXML(
JAXBMarshaller.java:6
8
)


at
gov.nih.nci.system.client.util.xml.JAXBMarshaller.toXML(
JAXBMarshaller.java:5
3
)


at test.SerializeTest.main(
SerializeTest.java:33
)

Caused by:
org.xml.sax.SAXParseException
: cvc
-
complex
-
type.2.4.a: Invalid
content was found starting with element 'employeeCollection'. One of
'{"gme://caCORE.caCORE/3.2/gov.nih.nci
.cacoresdk.domain.manytomany.bidirectio
nal":employeeCollection}' is expected.


at
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown
Source)


at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)


at org.apache.xerces.
impl.XMLErrorReporter.reportError(Unknown Source)


at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)


at
org.apache.xerces.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unk
nown Source)


at
org.apache.xerces.impl.xs.XMLSchemaV
alidator.reportSchemaError(Unknown
Source)


at
org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown
Source)


at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown
Source)


at
org.apache.xerces.jaxp.validation.ValidatorHand
lerImpl.startElement(Unknown
Source)


at
org.xml.sax.helpers.XMLFilterImpl.startElement(
XMLFilterImpl.java:527
)


at
com.sun.xml.bind.v2.runtime.output.SAXOutput.endStartTag(
SAXOutput.java:124
)


at

com.sun.xml.bind.v2.runtime.output.ForkXmlOutput.endStartTag(
ForkXmlOutput.ja
va:102
)


at
com.sun.xml.bind.v2.runtime.XMLSerializer.endAttributes(
XMLSerializer.java:30
0
)


at
com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(
XMLSerializer.java:6
78
)


at
com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(
SingleElementNodeProperty.java:150
)


at
com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(
ClassBeanInfoImpl
.java:322
)


at
com.sun.xml.bind.v2.runtime.XMLSerializer.ch
ildAsSoleContent(
XMLSerializer.ja
va:587
)


at
com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(
ClassBeanInfoImpl
.java:312
)


at
com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(
XMLSerializer.java:488
)


at
com.sun.xml.bind.v2.runtime.Marshalle
rImpl.write(
MarshallerImpl.java:317
)


... 5 more

gov.nih.nci.system.client.util.xml.XMLUtilityException


at
gov.nih.nci.system.client.util.xml.JAXBMarshaller.toXML(
JAXBMarshaller.java:7
3
)


at
gov.nih.nci.system.client.util.xml.JAXBMarshaller.toXML(
JAXBMars
haller.java:5
3
)


at test.SerializeTest.main(
SerializeTest.java:33
)

Note

Using
XMLUtility.
convertFromProxy
(o,
false
) works OK.

In the TestXMLClient.java, changing line 64 to read “boolean

validate = true;” causes several of the
tested classes to fail with a similar error message to the above.

JAXBCollectionObjectAdapter

This class seems to attempt to convert any collection into a HashSet. This might be problematic, since
the Collections
r
eturned by get*() methods of POJOs from the SDK’s query methods are List (ListProxy)
instances. This presents an impedance mismatch: Lists can contain duplicate objects, HashSet cannot. It
also makes the assumption that anything not an instance of ListPr
oxy is a HashSet and attempts to cast
it as such. The XMLUtilities.convertFromProxy method turns such things into ArrayLists, leading the
class cast exception mentioned earlier.

Could this class be refactored to simply deal with java.util.Collection inste
ad of HashSet?