Hi David,
JAXB should throw an UnmarshalException with a cause that is
IllegalArgumentException. So i think this is a bug in JAXB.
http://java.sun.com/javase/6/docs/api/javax/xml/bind/Unmarshaller.html#unmarshal%28java.io.InputStream%29
Do you know what version of JAXB you are using?
The Jersey code does the following:
public final Object readFrom(
Class<Object> type,
Type genericType,
Annotation annotations[],
MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream) throws IOException {
try {
return readFrom(type, mediaType, getUnmarshaller(type,
mediaType), entityStream);
} catch (UnmarshalException ex) {
throw new WebApplicationException(ex, 400);
} catch (JAXBException ex) {
throw new WebApplicationException(ex, 500);
}
}
protected Object readFrom(Class<Object> type, MediaType mediaType,
Unmarshaller u, InputStream entityStream)
throws JAXBException {
if (type.isAnnotationPresent(XmlRootElement.class))
return u.unmarshal(entityStream);
else
return u.unmarshal(new StreamSource(entityStream),
type).getValue();
}
So an UnmarshalException is wrapped around a WebApplicationException
which is then thrown and WebApplicationException can be trapped by an
ExceptionMapper.
Hmm... this is tricky. We could also catch any Exception when
unmarshallng but we do not know if that exception is related to a
server error or a client error. In such cases i think we have to
assume the former. Could you log an issue so we can also catch
Exception and re-throw as WebApplicationException(ex, 500)?
As a work around the only thing i can suggest is you register your own
JAXB provider and either copies or extends from:
http://fisheye4.atlassian.com/browse/jersey/trunk/jersey/jersey-core/src/main/java/com/sun/jersey/core/impl/provider/entity/XMLRootElementProvider.java?r=HEAD
and modify the readFrom method to trap IllegalArgumentException and
rethrow as WebApplicationException(ex, 500).
Paul.
On Jan 29, 2010, at 9:40 PM, David Johnson wrote:
> Hi,
>
> I've run into a case where an IllegalArgumentException is being
> generated
> from JAXB when Jersey is unmarshalling an XML request. The call
> stack is
> pasted at the end of this email. Although I'm not 100% sure, I
> believe the
> problem was caused by the client passing "{3}" as the value for a
> boolean
> XML attribute. I.e., a bug in the client code.
>
> My problem is that although I have implemented an ExceptionMapper to
> deal
> with exceptions, it is difficult at that level in the code to
> interpret
> IllegalArgumentException and to generate a proper response back to the
> client. Shouldn't Jersey catch this exception and wrap it in a
> WebApplicationException so an ExceptionMapper can have more context?
>
> java.lang.IllegalArgumentException: String "{3}" is not valid
> boolean value.
> at
> com
> .sun
> .xml.bind.DatatypeConverterImpl._parseBoolean(DatatypeConverterImpl.j
> ava:317)
> at
> com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl
> $14.parse(RuntimeBu
> iltinLeafInfoImpl.java:640)
> at
> com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl
> $14.parse(RuntimeBu
> iltinLeafInfoImpl.java:643)
> at
> com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor
> $CompositeTransducedAc
> cessorImpl.parse(TransducedAccessor.java:241)
> at
> com
> .sun
> .xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(Struct
> ureLoader.java:202)
> at
> com
> .sun
> .xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(
> UnmarshallingContext.java:481)
> at
> com
> .sun
> .xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(U
> nmarshallingContext.java:459)
> at
> com
> .sun
> .xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnec
> tor.java:148)
> at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown
> Source)
> at
> org
> .apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown
> Source)
> at
> org
> .apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown
> Source)
> at
> org.apache.xerces.impl.XMLDocumentFragmentScannerImpl
> $FragmentContentDispatc
> her.dispatch(Unknown Source)
> at
> org
> .apache
> .xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown
> Source)
> at org.apache.xerces.parsers.XML11Configuration.parse(Unknown
> Source)
> at org.apache.xerces.parsers.XML11Configuration.parse(Unknown
> Source)
> at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
> at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown
> Source)
> at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown
> Source)
> at
> com
> .sun
> .xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unmarsh
> allerImpl.java:211)
> at
> com
> .sun
> .xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unmarsha
> llerImpl.java:184)
> at
> javax
> .xml
> .bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshall
> erImpl.java:120)
> at
> javax
> .xml
> .bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshall
> erImpl.java:103)
> at
> com
> .sun
> .jersey.core.impl.provider.entity.XMLRootElementProvider.readFrom(XML
> RootElementProvider.java:112)
> at
> com
> .sun
> .jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(Abstr
> actRootElementProvider.java:105)
> at
> com
> .sun
> .jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.jav
> a:410)
> at
> com
> .sun
> .jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider
> $EntityInjectable.getValue(EntityParamDispatchProvider.java:137)
> at
> com
> .sun
> .jersey.server.impl.inject.InjectableValuesProvider.getInjectableValu
> es(InjectableValuesProvider.java:43)
> at
> com
> .sun
> .jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispa
> tchProvider
> $EntityParamInInvoker.getParams(AbstractResourceMethodDispatchPro
> vider.java:126)
> at
> com
> .sun
> .jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispa
> tchProvider
> $ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvi
> der.java:173)
> at
> com
> .sun
> .jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatche
> r.dispatch(ResourceJavaMethodDispatcher.java:67)
> at
> com
> .sun
> .jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.ja
> va:208)
> at
> com
> .sun
> .jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassR
> ule.java:75)
> at
> com
> .sun
> .jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathR
> ule.java:115)
> at
> com
> .sun
> .jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootReso
> urceClassesRule.java:67)
> at
> com
> .sun
> .jersey.server.impl.application.WebApplicationImpl._handleRequest(Web
> ApplicationImpl.java:771)
> at
> com
> .sun
> .jersey.server.impl.application.WebApplicationImpl.handleRequest(WebA
> pplicationImpl.java:736)
> at
> com
> .sun
> .jersey.server.impl.application.WebApplicationImpl.handleRequest(WebA
> pplicationImpl.java:727)
> at
> com
> .sun
> .jersey.spi.container.servlet.WebComponent.service(WebComponent.java:
> 368)
> at
> com
> .sun
> .jersey.spi.container.servlet.ServletContainer.service(ServletContain
> er.java:452)
> at
> com
> .sun
> .jersey.spi.container.servlet.ServletContainer.service(ServletContain
> er.java:633)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
>
>
> Thanks,
> David Johnson
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>