【问题标题】:EclipseLink MOXy: Intermittent NullPointerException / MarshalException with concurrent callsEclipseLink MOXy:具有并发调用的间歇性 NullPointerException / MarshalException
【发布时间】:2014-12-09 16:39:59
【问题描述】:

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

关于项目...

  • Apache CXF JAX-RS,非 Spring Servlet 实现:2.7.7
  • 休眠 JPA:4.3.5.Final
  • EclipseLink Moxy:2.5.1
  • 春季:4.2.1.RELEASE
  • 雄猫 7

MOXy 当前是通过注册 org.eclipse.persistence.jaxb.rs.MOXyJsonProvider 类到 JAX-RS 应用程序,在 JPA 实体中包含 jaxb.properties 文件 课程包;文件内容: javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

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

如果我通过基于 Windows 的本地主机上的浏览器访问 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 客户端后,这种情况似乎不太常见,因此“启动”系统的概念似乎在某种程度上准确地解释了正在发生的事情。然而,即便如此,这种行为并不一致!似乎没有办法可靠地预测何时会发生这种异常情况。

既然 Spring 正在管理事务,我还需要做些什么,以便在从并发线程快速连续调用时让 MOXy 正确初始化?

总结:

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

【问题讨论】:

  • 花了很多 Google-fu 来制作正确的搜索词集,但我发现了这个问题的另一个实例,截至 2.5.1 尚未修复。如果我想要修复,我将不得不使用 MOXy 的 SNAPSHOT 版本。 eclipse.org/forums/index.php/t/667901
  • SNAPSHOT 版本不是必需的。自从我上次检查 MOXy 版本以来,发布了 2.5.2 版。 2.5.2 版(最新的 2.5.x 版本)为我解决了这个问题。我正在添加答案并关闭问题。

标签: spring hibernate jakarta-ee cxf moxy


【解决方案1】:

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

我将项目从 2.5.1 切换到 2.5.2,并且不再遇到此问题。

注意本地主机和测试服务器之间的不同行为...

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

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

【讨论】:

    猜你喜欢
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 2014-12-23
    相关资源
    最近更新 更多