使用“不支持的javax.xml.parser.transform.Result参数”进行JAXB编组失败

时间:2012-05-03 05:00:38

标签: java jaxb spring-oxm

我使用Spring 3.1.1和他们的OXM东西,使用RestTemplate将请求发布到另一台服务器。我使用一个名为ClassTermCollection的类作为它的请求和响应方面,并且使用@XmlRootElement等进行了注释,并且直到今天一直工作正常。但突然我们在JAXB尝试创建请求时遇到以下错误(即,在对服务器进行http调用之前,在客户端抛出此错误)。

Google几乎没有透露这个特定错误的有用信息,而且 - 更糟糕的是 - Sun显然没有将源代码发送到抛出异常的类,使用JDK ......所以我甚至不能一直调试到这个根,以确切地确定发生了什么。

编辑:(请参阅stacktrace下面的其他评论)

[错误] org.springframework.http.converter.HttpMessageNotWritableException:无法写入[pmt.model.collections.ClassTermCollection@6576fac];嵌套异常是org.springframework.oxm.MarshallingFailureException:JAXB编组异常;嵌套异常是javax.xml.bind.MarshalException:不支持的javax.xml.parser.transform.Result参数 [错误]在org.springframework.http.converter.xml.MarshallingHttpMessageConverter.writeToResult(MarshallingHttpMessageConverter.java:134) [错误]在org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter.writeInternal(AbstractXmlHttpMessageConverter.java:66) [错误]在org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:179) [错误]在org.springframework.web.client.RestTemplate $ HttpEntityRequestCallback.doWithRequest(RestTemplate.java:588) [错误]在org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:436) [错误]在org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409) org.springframework.web.client.RestTemplate.postForObject [RestTemplate.java:287]的[错误] [错误]在com.pmt.fe.server.InvestmentServiceImpl.saveTerms(InvestmentServiceImpl.java:306) [错误]在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) [错误]在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [错误]在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke中的[错误](Method.java:601) [错误]:com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:569) [错误]:com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:551) [错误]在com.pmt.fe.server.RemoteServiceDispatcher.invokeAndEncodeResponse(RemoteServiceDispatcher.java:115) [错误]在com.pmt.fe.server.RemoteServiceDispatcher.processCall(RemoteServiceDispatcher.java:75) [错误],地址为com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248) [错误]:com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) [错误]在javax.servlet.http.HttpServlet.service(HttpServlet.java:637) [错误]在javax.servlet.http.HttpServlet.service(HttpServlet.java:717) [错误]在org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) [错误]在org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362) [错误]在org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) [错误]在org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) [错误]在org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729) [错误]在org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) [错误]在org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) [错误]在org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49) [错误]在org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) [错误]在org.mortbay.jetty.Server.handle(Server.java:324) [错误]在org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505) [错误]在org.mortbay.jetty.HttpConnection $ RequestHandler.content(HttpConnection.java:843) [错误]在org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647) [错误]在org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205) [错误]在org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380) [错误]在org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395) [错误]在org.mortbay.thread.QueuedThreadPool $ PoolThread.run(QueuedThreadPool.java:488) [错误]引起:org.springframework.oxm.MarshallingFailureException:JAXB编组异常;嵌套异常是javax.xml.bind.MarshalException:不支持的javax.xml.parser.transform.Result参数 [错误] org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:758) org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal的[错误](Jaxb2Marshaller.java:597) org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal的[错误](Jaxb2Marshaller.java:580) [错误]在org.springframework.http.converter.xml.MarshallingHttpMessageConverter.writeToResult(MarshallingHttpMessageConverter.java:131) [错误] ......还有36个 [ERROR]引起:javax.xml.bind.MarshalException:不支持的javax.xml.parser.transform.Result参数 [错误]在com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.createXmlOutput(MarshallerImpl.java:221) [错误],地址为com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236) org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal的[错误](Jaxb2Marshaller.java:593) [错误] ......还有38个

好的,在网上找到com.sun.xml.internal.bind.v2.runtime.MarshallerImpl的源代码1,现在我看到(有点)发生了什么。该代码查看Result实例,如果它是StreamResult(就像我的情况一样),它会尝试取消引用StreamResult的outputstream,writer和systemId字段,并使用这些值来构造Writer。如果所有这些都为null,则它会进入方法的底部并抛出不支持的格式"异常,正在这里发生。

在上面,在Spring org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter类中,我们到达这一行,构造StreamResult,将outputMessage.getBody()的结果传递给StreamResult构造函数。我在这里得到零,因此问题从下面冒出来。

    @覆盖     protected final void writeInternal(T t,HttpOutputMessage outputMessage)抛出IOException {         writeToResult(t,outputMessage.getHeaders(),new StreamResult(outputMessage.getBody()));     }

解决

有这个工作......我忘记了原来的所有细节;但这基本上是一个疯狂的情况,一个同事添加了一些子类化HttpClient类的代码,他的类没有完全符合接口的合同,并且当被我的代码调用时,它导致了这个错误。这是奇怪的情况之一,它看起来像一个JAXB错误,但事实证明它与JAXB完全无关。

2 个答案:

答案 0 :(得分:4)

您的问题是,当您实例化StreamResult时,您必须提供一种方法来存储将写入其中的数据。你应该做一些事情:

StreamResult res=new StreamResult(new ByteArrayOutputStream());

ByteArrayOutputStream将根据需要增长。

答案 1 :(得分:1)

查看Spring的源代码,Marshaller抱怨它不支持StreamResult对象。它肯定支持这个对象,但你可能遇到的是一个类加载问题,其中正在使用从错误的JAR或错误的类加载器加载的StreamResult。