Hi.
There seems to be a bug with missing object reporting.
When trying to marshall an object with a missing field, an illegal
attribute exception is thrown:
java.lang.IllegalArgumentException: _object parameter must not be null
at
javax.xml.bind.helpers.ValidationEventLocatorImpl.<init>(ValidationEventLocatorImpl.java:120)
at
com.sun.xml.bind.util.ValidationEventLocatorExImpl.<init>(ValidationEventLocatorExImpl.java:27)
at com.sun.xml.bind.serializer.Util.createMissingObjectError(Util.java:31)
at
test.impl.runtime.SAXMarshaller.reportMissingObjectError(SAXMarshaller.java:444)
at test.impl.runtime.SAXMarshaller.childAsURIs(SAXMarshaller.java:412)
However, when looking at the code, I don't think this is the intended
behavious. In the SAXMarshaller, when an object is missing, you want to
report a missing object error:
public void childAsURIs( JAXBObject o, String fieldName ) throws
SAXException {
if(o==null) {
reportMissingObjectError(fieldName);
return;
}
JAXBObject oldTarget = currentTarget;
currentTarget = o;
owner.context.getGrammarInfo().castToXMLSerializable(o).serializeURIs(this);
currentTarget = oldTarget;
}
In reportMissingObjectError(...) you simply want to report a new missing
object error which is created in an utility class:
public void reportMissingObjectError(String fieldName) throws
SAXException {
reportError(Util.createMissingObjectError(currentTarget,fieldName));
}
But what I think is not expected is that Util.createMissingObjectError
will throw an illegal attribute exception. I conclude this, while
reportError method seems to be allowing not to throw any exception if
ValidationEventHandler is provided:
public void reportError( ValidationEvent ve ) throws
AbortSerializationException {
ValidationEventHandler handler;
try {
handler = owner.getEventHandler();
} catch( JAXBException e ) {
throw new AbortSerializationException(e);
}
if(!handler.handleEvent(ve)) {
if(ve.getLinkedException() instanceof Exception)
throw new
AbortSerializationException((Exception)ve.getLinkedException());
else
throw new AbortSerializationException(ve.getMessage());
}
}
Now, if hanlder handles event ans says missing object is no problem for
marshalling, the marshalling will go on. As far as I understand, this is
the intended behavious, not the IllegalArgumentException.
I've debugged a bit and seem to have found a source of the problem. When
you call
Util.createMissingObjectError(currentTarget,fieldName)
currentTarget is null. As far as I understood, currentTarget is the
object that is currently marshalled, NOT the value of the property.
Therefore currentTarget should NOT be null. However, for the root object
you do not assign currentTarget of the SAXMarshaller - only for the
sub-objects. That is why we get illegal argument exception rather than a
ValidationEvent.
The solution is to assign currentTarget somehow. This could be done, for
instance, when constructing SAXMarshaller in MarshallerImpl.write(...):
SAXMarshaller serializer = new
SAXMarshaller(writer,prefixMapper,this, (JAXBObject) obj);
SAXMarshaller's constructor could then be:
public SAXMarshaller( ContentHandler _writer, NamespacePrefixMapper
prefixMapper, MarshallerImpl _owner, JAXBObject _rootTarget ) {
this.writer = _writer;
this.owner = _owner;
this.nsContext = new NamespaceContextImpl(
prefixMapper!=null?prefixMapper:defaultNamespacePrefixMapper);
this.currentTarget = _rootTarget;
}
Sorry I don't have a build of JAXB RI set up and can't test my proposal.
If you agree with me that it is a bug, I can file an issue on dev.java.net.
Bye.
/lexi
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
For additional commands, e-mail: users-help_at_jaxb.dev.java.net