EclipseLink MOXy:具有并发调用的间歇性NullPointerException / MarshalException

时间:2014-12-09 16:39:59

标签: spring hibernate java-ee cxf moxy

我有一组JAX-RS端点,可以从基于AngularJS的应用程序异步访问。

  

关于项目......

     
      
  • Apache CXF JAX-RS,非Spring Servlet实现:2.7.7
  •   
  • Hibernate JPA:4.3.5.Final
  •   
  • EclipseLink Moxy:2.5.1
  •   
  • Spring:4.2.1.RELEASE
  •   
  • Tomcat 7
  •   
     

MOXy目前通过注册来配置   JAX-RS的org.eclipse.persistence.jaxb.rs.MOXyJsonProvider类   应用程序,JPA实体中包含jaxb.properties文件   类'包;文件的内容:   javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

如果我自己访问一个端点,一切都按预期运行。

如果我通过基于Windows的localhost上的浏览器访问Angular客户端,一切都按预期运行。

但是,只要我在基于Linux的测试环境中测试应用程序,我有时会遇到异常,例如:

10:57:38.390 [tomcat-http--27] WARN  o.a.c.j.i.WebApplicationExceptionMapper - javax.ws.rs.WebApplicationException: javax.xml.bind.MarshalException
 - with linked exception:
[java.lang.NullPointerException]
        at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:842)
        at org.apache.cxf.jaxrs.utils.JAXRSUtils.writeMessageBody(JAXRSUtils.java:1317)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:282)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:155)
        at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
        at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:239)
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:167)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:211)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Caused by: javax.xml.bind.MarshalException
 - with linked exception:
[java.lang.NullPointerException]
        at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:457)
        at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:840)
        ... 33 more
Caused by: java.lang.NullPointerException
        at org.eclipse.persistence.internal.oxm.XMLCompositeObjectMappingNodeValue.marshal(XMLCompositeObjectMappingNodeValue.java:145)
        at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:102)
        at org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext.marshal(ObjectMarshalContext.java:59)
        at org.eclipse.persistence.internal.oxm.XPathNode.marshal(XPathNode.java:401)
        at org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(XPathObjectBuilder.java:240)
        at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:118)
        at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:1)
        at org.eclipse.persistence.internal.oxm.XMLCompositeCollectionMappingNodeValue.marshalSingleValue(XMLCompositeCollectionMappingNodeValue.java:328)
        at org.eclipse.persistence.internal.oxm.XMLCompositeCollectionMappingNodeValue.marshal(XMLCompositeCollectionMappingNodeValue.java:108)
        at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:149)
        at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:102)
        at org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext.marshal(ObjectMarshalContext.java:59)
        at org.eclipse.persistence.internal.oxm.XPathNode.marshal(XPathNode.java:401)
        at org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(XPathObjectBuilder.java:240)
        at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:118)
        at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:1)
        at org.eclipse.persistence.internal.oxm.XMLCompositeObjectMappingNodeValue.marshalSingleValue(XMLCompositeObjectMappingNodeValue.java:249)
        at org.eclipse.persistence.internal.oxm.XMLCompositeObjectMappingNodeValue.marshal(XMLCompositeObjectMappingNodeValue.java:150)
        at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:102)
        at org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext.marshal(ObjectMarshalContext.java:59)
        at org.eclipse.persistence.internal.oxm.XPathNode.marshal(XPathNode.java:401)
        at org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(XPathObjectBuilder.java:240)
        at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:118)
        at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:1)
        at org.eclipse.persistence.internal.oxm.XMLCompositeObjectMappingNodeValue.marshalSingleValue(XMLCompositeObjectMappingNodeValue.java:249)
        at org.eclipse.persistence.internal.oxm.XMLCompositeObjectMappingNodeValue.marshal(XMLCompositeObjectMappingNodeValue.java:150)
        at org.eclipse.persistence.internal.oxm.NodeValue.marshal(NodeValue.java:102)
        at org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext.marshal(ObjectMarshalContext.java:59)
        at org.eclipse.persistence.internal.oxm.XPathNode.marshal(XPathNode.java:401)
        at org.eclipse.persistence.internal.oxm.XPathObjectBuilder.buildRow(XPathObjectBuilder.java:240)
        at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:118)
        at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.buildRow(TreeObjectBuilder.java:1)
        at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:751)
        at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:571)
        at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshalStreamOrWriter(XMLMarshaller.java:1107)
        at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:919)
        at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:862)
        at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:455)
        ... 34 more

我能找到的有关我的问题的唯一相关信息在此相关的StackOverflow问题/答案中:Null pointer exception only on application startup org.eclipse.persistence.jaxb.JAXBMarshaller.marshal

在迁移我的项目以使用Spring进行Hibernate JPA EntityManager事务管理之前,这一切都没有开始。

我完全失败了。我可以重构我的客户端只发出同步调用,但即使这样,当多个用户同时尝试使用该应用程序时,仍会出现此问题。为什么MOXy以这种方式行为不端?在Angular客户端多次刷新之后,似乎这种情况似乎发生的次数减少了,所以" priming"系统看起来似乎有点准确地解释了发生了什么。但是,即使这样,这种行为也不一致!似乎没有办法可靠地预测何时会出现这种异常情况。

我是否需要做一些额外的工作,现在Spring正在管理事务,以便在快速连续地从并发线程调用时让MOXy正确初始化?

要点:

  • 访问单个JAX-RS RESTful端点(无论服务器环境如何)时从未发生过
  • 永远不会发生在基于Windows的localhost上
  • 有时会在基于Linux的测试服务器上发生,并且只有在同时访问多个端点时才会发生
    • 即使在这些条件下,有时根本不会发生
  • 仅在从手动/自定义应用程序管理的Hibernate EntityManager事务管理迁移到基于Spring的事务管理之后才开始发生

1 个答案:

答案 0 :(得分:1)

根据https://bugs.eclipse.org/bugs/show_bug.cgi?id=404951的错误报告,此问题的修复程序已签入2.5.x分支。我检查了稳定的MOXy版本,果然,几个月前发布了2.5.2版本。

我将项目从2.5.1切换到2.5.2,我不再遇到这个问题。

  

请注意localhost和测试服务器之间的不同行为......

     

我通过grunt-connect-proxy代理端点请求   我可以在使用时维护端点URL的相对路径   grunt-contrib-connect功能livereload

     

当我删除此中间代理和Angular客户端时   直接访问端点,我能够复制该问题   本地。