JBoss Resteasy服务中的罕见ConcurrentModificationException [英] Rare ConcurrentModificationException in JBoss Resteasy service

查看:109
本文介绍了JBoss Resteasy服务中的罕见ConcurrentModificationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了在Apache Tomcat下运行的Resteasy服务.它工作正常,但是有时,在向服务发送请求时,很少会收到这样的疯狂错误:

I have implemented Resteasy service which is working under Apache Tomcat. It works fine, but sometimes, when sending request to service, very rarely I receive such crazy error:

java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        at java.util.ArrayList$Itr.next(Unknown Source)
        at com.sun.xml.bind.v2.runtime.reflect.Lister$CollectionLister$1.next(Lister.java:288)
        at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:139)
        at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:159)
        at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:358)
        at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:696)
        at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:69)
        at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:172)
        at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:159)
        at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:358)
        at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:593)
        at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:340)
        at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494)
        at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:323)
        at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:251)
        at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(Unknown Source)
        at org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider.writeTo(AbstractJAXBProvider.java:138)
        at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:129)
        at org.jboss.resteasy.core.interception.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:62)
        at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:118)
        at org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor.aroundWriteTo(GZIPEncodingInterceptor.java:100)
        at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:122)
        at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:99)
        at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:411)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:376)
        at org.jboss.resteasy.core.SynchronousDispatcher.invokePropagateNotFound(SynchronousDispatcher.java:217)
        at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:224)
        at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:62)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        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:502)
        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:953)
        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:1023)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

关于这种错误的原因或方式有什么想法,如何重现/修复它?

Are any ideas about reason for such error or ways, how to reproduce/fix it?

更新

伙计们,有几个答案建议我在我的bean中实现Synchronized集合.这不是一种方法,因为:

There are several answers where you, guys, suggest me to implement Synchronized collections inside my beans. It is not a way, because:

1)我使用标准生成器从XSD生成了bean.我大约. 100种不同的豆,我不想手动更改它们

1) I generate my beans from XSD using standard generators. I have approx. 100 different beans and I do not want to change them all manually

2)在JAXB文档中和在RESTEasy文档中都没有提到需要同步化的集合.

2) There is not any mention about need of synchonized collections neither in JAXB docs, neither in RESTEasy docs.

推荐答案

Resteasy似乎正在生成XML响应,但是传递给JAXB marshaller的对象树已被Java中的另一个线程修改.应用程序.

It seems that Resteasy is in the process of generating an XML response, but the object tree that was passed to the JAXB marshaller has been modified by another thread in the application.

编组对象树中的列表已被另一个线程修改,因此当编组者遍历该列表时,将导致ConcurrentModificationException.

A list in the marshalled object tree has been modified by another thread, and so when the marshaller goes through the list, it causes a ConcurrentModificationException.

通常有两个应用程序线程访问同一个bean,例如,是否有一些bean存储在静态变量中?

Is it normal that there are two application threads accessing the same bean, are there some beans stored in static variables for example ?

尝试打开-Djaxb.debug = true以获取有关引起问题的bean属性的更多信息.可能并非总是同一属性会导致错误.

Try turning on -Djaxb.debug=true to get further info on which bean property it's causing the problem. It might not always be the same property causing the error.

识别属性的另一种方法是在抛出CME的行中放置一个断点,并检查列表元素的类型是什么.

Another way of identifying the property is putting a breakpoint in the line that throws the CME, and checking what is the type of the elements of the list is.

如果应用程序中的Bean打算由多个线程访问,则有必要使Bean类的线程安全,但是根据您提到的内容,没有明显的共享状态-因此您的Bean仅应由一个线程访问一次线程.

If the beans in the application are intended to be accessed by multiple threads, then it's necessary to make the bean classes thread safe but based on what you mention there is no evident shared state - so your beans should only be accessed by one thread at a time.

您总是可以进行一些堆转储,并在eclipse内存分析器中搜索哪些线程正在引用导致问题的列表中的对象.

You can always take a few heap dumps and search in eclipse memory analyzer for which threads are referencing objects of the list/lists causing problems.

这篇关于JBoss Resteasy服务中的罕见ConcurrentModificationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆