commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bigfishsmallp...@gogoworld.com
Subject [JXPATH] Issue with multithreading
Date Fri, 25 Apr 2003 18:34:18 GMT
I believe I have found an issue with running JXPath v1.1 in a
multithreading situation.  In a program that has about 20 threads using
JXPath, I occasionally get this exception:

java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.next(Unknown Source)
at
org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.cleanupCache(JXPathContextReferenceImpl.java:270)
at
org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.compileExpression(JXPathContextReferenceImpl.java:252)
at
org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:283)
at
com.kronos.ivr.server.EndDocumentHandler.processMessage(EndDocumentHandler.java:62)
at com.kronos.ivr.server.Server.processMessage(Server.java:324)
at com.kronos.ivr.server.Server.message(Server.java:241)
at com.kronos.scripter.engine.Engine$WorkerThread.run(Engine.java:186)

Looking at the JXPathContextReferenceImpl, I think I see a potential
source of this error.  It contains a HashMap variable called compiled this
is static, but its use is not synchronized.  I could see a situation in
the compileExpression method where one thread tries to put an expression
in the HashMap, while another is performing a cleanupCache(). That would
certainly cause the exception.

To test this hypothesis, I put the code section in a synchronized block
and am no longer getting the exception.  The code sample is:

    private Expression compileExpression(String xpath) {
        Expression expr;
        if (USE_SOFT_CACHE) {
            expr = null;
 ====>      synchronized( compiled )   <==== CHANGE
            {
                SoftReference ref = (SoftReference) compiled.get(xpath);
                if (ref != null) {
                    expr = (Expression) ref.get();
                }
                if (expr == null) {
                    expr =
                        (Expression) Parser.parseExpression(xpath,
getCompiler());
                    compiled.put(xpath, new SoftReference(expr));
                    if (cleanupCount++ >= CLEANUP_THRESHOLD) {
                        cleanupCache();
                    }
                }
            }
        }
        else {
            expr = (Expression) compiled.get(xpath);
            if (expr == null) {
                expr =
                    (Expression) Parser.parseExpression(xpath,
getCompiler());
                compiled.put(xpath, expr);
            }
        }
        return expr;
    }

-Chuck.


-------------------------------------------------
Get your FREE email address at www.gogoworld.com



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message