Menu

#1556 ConcurrentModificationException in UnifiedLoaderRepository3

v3.2
closed-fixed
JBossMX (91)
5
2003-11-10
2003-10-14
Peter Stout
No

The getResourceFromRepository method in
UnifiedLoaderRepository3 does not synchronize access to
the packagesMap and classLoaders fields, unlike all
other accesses to those fields. As a result, if
classes are being loaded at the same time as a resource
is being looked up, a ConcurrentModificationException
can be triggered.

I have attached a proposed patch for this bug. The fix
wraps the uses of packagesMap and classLoaders fields
in the appropriate synchronized blocks. If the all of
the class loaders need to be searched, a copy of the
classLoaders field is made to avoid having to
synchronize while performing the search. The existing
code is inconsistent in the way it makes a copy of the
classLoaders field: new HashSet(classLoaders) versus
classLoaders.clone(). I arbitrarily chose the former,
but whoever fixes the bug might consider making the
code consistent one way or the other.

I suspect that there is a second order synchronization
problem in the processing of any HashSet retrieved from
the packagesMap. The retrieved HashSet may be
concurrently modified if a class loader is added or
removed while the set is being processed. The
modifications to the HashSet's in the packagesMap
performed in the add/remove class loader code path are
performed while holding the packagesMap lock, but the
code in getResourceFromRepository and
LoadMgr3.beginLoadTask, which retrieves a package set
using the getPackageClassLoaders method, is
unsynchronized. Unless there is some other lock that
makes this a non-issue, I suspect that fixing the
problem will require either making a copy of the
HashSet or a moderate amount of code restructuring.

Discussion

  • Peter Stout

    Peter Stout - 2003-10-14

    A patch to fix the primary synchronization problem.

     
  • Scott M Stark

    Scott M Stark - 2003-11-09

    Logged In: YES
    user_id=175228

    Add a trace of the ConcurrentModificationException if you
    have it. The proposed synchronizations really should not
    have any effect because this does not prevent iteration over
    the pkg map from failing. I would think the real solution is
    another data structure like the
    EDU.oswego.cs.dl.util.concurrentConcurrentReaderHashMap

     
  • Scott M Stark

    Scott M Stark - 2003-11-09
    • assigned_to: nobody --> starksm
    • status: open --> open-accepted
     
  • Scott M Stark

    Scott M Stark - 2003-11-10
    • status: open-accepted --> closed-fixed
     
  • Scott M Stark

    Scott M Stark - 2003-11-10

    Logged In: YES
    user_id=175228

    I am just making a copy of the set which iteration is being
    done over to make sure the ConcurrentModificationException
    cannot happen. This is in for 3.2.3RC1

     
  • sal ingrilli

    sal ingrilli - 2004-01-09

    Logged In: YES
    user_id=396317

    I just got a trace:

    <03> <DEBUG> <OperatingSystem> <Couldn't find system
    variable (upper/lower case): MYSQL_HOME>
    <03> <WARN > <PropertiesUtil> <MYSQL_HOME property was
    null: changed to "">
    <03> <DEBUG> <ResourceHandler> <findResourceAsUrl ():
    fullPath: "/support.properties">
    <03> <INFO > <MainDeployer> <Deployed package:
    file:/C:/runtime/jboss/server/vxtracker/deploy/250syncvoice-
    support.sar>
    <03> <INFO > <MainDeployer> <Starting deployment of
    package:
    file:/C:/runtime/jboss/server/vxtracker/deploy/999wrapper-
    service.xml>
    <03> <DEBUG> <IncludeManager> <available: 4717>
    <03> <DEBUG> <IncludeManager> <available: 623>
    <03> <DEBUG> <IncludeManager> <available: 632>
    <03> <FATAL> <IncludeManager> <>
    java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.next
    (HashMap.java:736)
    at
    org.jboss.mx.loading.UnifiedLoaderRepository3.getResourceFro
    mRepository(UnifiedLoaderRepository3.java:372)
    at
    org.jboss.mx.loading.UnifiedLoaderRepository3.getResource
    (UnifiedLoaderRepository3.java:257)
    at org.jboss.mx.loading.UnifiedClassLoader3.getResource
    (UnifiedClassLoader3.java:228)
    at java.lang.ClassLoader.getResourceAsStream
    (ClassLoader.java:932)
    at java.lang.Class.getResourceAsStream
    (Class.java:1220)
    at
    com.vxgateway.rpt.include.IncludeManager.loadResource
    (IncludeManager.java:106)
    at com.vxgateway.rpt.include.IncludeManager.<clinit>
    (IncludeManager.java:91)
    at com.vxgateway.jsp.home._jspService(home.java:270)
    at org.apache.jasper.runtime.HttpJspBase.service
    (HttpJspBase.java:137)
    at javax.servlet.http.HttpServlet.service
    (HttpServlet.java:853)
    at
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
    (ApplicationFilterChain.java:247)
    at
    org.apache.catalina.core.ApplicationFilterChain.doFilter
    (ApplicationFilterChain.java:193)
    at
    org.apache.catalina.core.StandardWrapperValve.invoke
    (StandardWrapperValve.java:256)
    at
    org.apache.catalina.core.StandardPipeline$StandardPipelineVal
    veContext.invokeNext(StandardPipeline.java:643)
    at org.apache.catalina.core.StandardPipeline.invoke
    (StandardPipeline.java:480)
    at org.apache.catalina.core.ContainerBase.invoke
    (ContainerBase.java:995)
    at
    org.apache.catalina.core.StandardContextValve.invoke
    (StandardContextValve.java:191)
    at
    org.apache.catalina.core.StandardPipeline$StandardPipelineVal
    veContext.invokeNext(StandardPipeline.java:643)
    at org.apache.catalina.valves.CertificatesValve.invoke
    (CertificatesValve.java:246)
    at
    org.apache.catalina.core.StandardPipeline$StandardPipelineVal
    veContext.invokeNext(StandardPipeline.java:641)
    at org.apache.catalina.core.StandardPipeline.invoke
    (StandardPipeline.java:480)
    at org.apache.catalina.core.ContainerBase.invoke
    (ContainerBase.java:995)
    at org.apache.catalina.core.StandardContext.invoke
    (StandardContext.java:2415)
    at org.apache.catalina.core.StandardHostValve.invoke
    (StandardHostValve.java:180)
    at
    org.apache.catalina.core.StandardPipeline$StandardPipelineVal
    veContext.invokeNext(StandardPipeline.java:643)
    at
    org.apache.catalina.valves.ErrorDispatcherValve.invoke
    (ErrorDispatcherValve.java:171)
    at
    org.apache.catalina.core.StandardPipeline$StandardPipelineVal
    veContext.invokeNext(StandardPipeline.java:641)
    at org.apache.catalina.valves.ErrorReportValve.invoke
    (ErrorReportValve.java:172)
    at
    org.apache.catalina.core.StandardPipeline$StandardPipelineVal
    veContext.invokeNext(StandardPipeline.java:641)
    at org.apache.catalina.valves.AccessLogValve.invoke
    (AccessLogValve.java:509)
    at
    org.apache.catalina.core.StandardPipeline$StandardPipelineVal
    veContext.invokeNext(StandardPipeline.java:641)
    at org.apache.catalina.core.StandardPipeline.invoke
    (StandardPipeline.java:480)
    at org.apache.catalina.core.ContainerBase.invoke
    (ContainerBase.java:995)
    at org.apache.catalina.core.StandardEngineValve.invoke
    (StandardEngineValve.java:174)
    at
    org.apache.catalina.core.StandardPipeline$StandardPipelineVal
    veContext.invokeNext(StandardPipeline.java:643)
    at org.apache.catalina.core.StandardPipeline.invoke
    (StandardPipeline.java:480)
    at org.apache.catalina.core.ContainerBase.invoke
    (ContainerBase.java:995)
    at org.apache.coyote.tomcat4.CoyoteAdapter.service
    (CoyoteAdapter.java:223)
    at org.apache.coyote.http11.Http11Processor.process
    (Http11Processor.java:594)
    at
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionH
    andler.processConnection(Http11Protocol.java:392)
    at org.apache.tomcat.util.net.TcpWorkerThread.runIt
    (PoolTcpEndpoint.java:565)
    at
    org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.ru
    n(ThreadPool.java:619)
    at java.lang.Thread.run(Thread.java:484)
    <03> <INFO > <IncludeManager> <Loading menuItems>

     

Log in to post a comment.