Hello,

We are evaluating GroovyShell <http://groovy-lang.org/download.html>
interpreter
(v2.4) in our application for dynamically executing standard Java syntax.

Earlier, we were using Java BeanShell Interpreter for it, but it has an
issue
<https://stackoverflow.com/questions/45450947/lock-contention-in-java-beanshell-interpreter-under-high-load/45451768#45451768>
under
high load which prompted us to look for an alternative such as Groovy.

We are seeing thread lock contention when multiple threads execute the
below sample code simultaneously. We have multiple threads in the blocked
state which is degrading application performance.

My questions are:

   1. Has anyone experienced such problem? If yes, can you please suggest
   any possible resolution for it? I googled around for this problem and few
   blogs suggested to cache groovy Script object. Is Script object
   thread-safe? Moreover, I need to bind variables to Scriptobject (via
   groovy Binding object, which is different for each execution in
   different threads), so I don't think caching groovy Script object is a
   viable option.
   2. Are there any best practices that I need to follow while using Groovy
   Shell interpreter with Java?

PFA, sample code, and blocked thread call stack.

Let me know if you need more information. Thanks in advance for your time.

Regards,
Aman
    java.lang.Thread.State: BLOCKED (on object monitor)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:404)
        - waiting to lock <0x00000007bc425e40> (a java.lang.Object)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        - locked <0x00000007bd369ba8> (a groovy.lang.GroovyClassLoader)
        at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:677)
        at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:545)
        at 
org.codehaus.groovy.control.ClassNodeResolver.tryAsLoaderClassOrScript(ClassNodeResolver.java:185)
        at 
org.codehaus.groovy.control.ClassNodeResolver.findClassNode(ClassNodeResolver.java:170)
        at 
org.codehaus.groovy.control.ClassNodeResolver.resolveName(ClassNodeResolver.java:126)
        at 
org.codehaus.groovy.control.ResolveVisitor.resolveToOuter(ResolveVisitor.java:676)
        at 
org.codehaus.groovy.control.ResolveVisitor.resolve(ResolveVisitor.java:313)
        at 
org.codehaus.groovy.control.ResolveVisitor.transformPropertyExpression(ResolveVisitor.java:845)
        at 
org.codehaus.groovy.control.ResolveVisitor.transform(ResolveVisitor.java:696)
        at 
org.codehaus.groovy.control.ResolveVisitor.transformMethodCallExpression(ResolveVisitor.java:1081)
        at 
org.codehaus.groovy.control.ResolveVisitor.transform(ResolveVisitor.java:702)
        at 
org.codehaus.groovy.ast.ClassCodeExpressionTransformer.visitExpressionStatement(ClassCodeExpressionTransformer.java:142)
        at 
org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:42)
        at 
org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:37)
        at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:166)
        at 
org.codehaus.groovy.control.ResolveVisitor.visitBlockStatement(ResolveVisitor.java:1336)
        at 
org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
        at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:104)
        at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:115)
        at 
org.codehaus.groovy.ast.ClassCodeExpressionTransformer.visitConstructorOrMethod(ClassCodeExpressionTransformer.java:53)
        at 
org.codehaus.groovy.control.ResolveVisitor.visitConstructorOrMethod(ResolveVisitor.java:201)
        at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:126)
        at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1081)
        at 
org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:53)
        at 
org.codehaus.groovy.control.ResolveVisitor.visitClass(ResolveVisitor.java:1279)
        at 
org.codehaus.groovy.control.ResolveVisitor.startResolving(ResolveVisitor.java:176)
        at 
org.codehaus.groovy.control.CompilationUnit$12.call(CompilationUnit.java:663)
        at 
org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:943)
        at 
org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:605)
        at 
org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:554)
        at 
groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
        at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
        - locked <0x00000007bd372240> (a java.util.HashMap)
        at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
        at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
        at groovy.lang.GroovyShell.parse(GroovyShell.java:736)
        at groovy.lang.GroovyShell.parse(GroovyShell.java:727)
static String script = "int y = x * x; System.out.println(\"** value of y ** :: 
\" + y ); ";

GroovyShell gs = new GroovyShell();
Script evalScript = gs.parse("void evalMethod() {" + script + "}");
// bind variables
Binding binding = new Binding();
binding.setVariable("x", 5);
evalScript.setBinding(binding);
// invoke eval method
evalScript.invokeMethod("evalMethod", null);

Reply via email to