[ 
https://issues.apache.org/jira/browse/GROOVY-9541?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul King closed GROOVY-9541.
-----------------------------

> Compiling statically using GroovyClassLoader does not always respect the 
> configured parent ClassLoader
> ------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-9541
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9541
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 3.0.3
>            Reporter: Lyuben Atanasov
>            Assignee: Eric Milles
>            Priority: Major
>             Fix For: 3.0.14, 4.0.7
>
>
> When using GroovyClassLoader to parse a groovy script annotated with 
> @CompileStatic, the static type checker does not seem to use the configured 
> parent class loader. Instead it uses the thread context ClassLoader. This 
> sometimes causes compilation failures (especially when Closures are present) 
> in environments like OSGi, where the thread context ClassLoader is definitely 
> not the desired ClassLoader.
>  For example this code:
> {code:java}
> try (GroovyClassLoader classLoader = new GroovyClassLoader(bundleClassLoader,
>                 compilerConfiguration))
> {
>     Class<?> scriptClass = classLoader.parseClass(scriptContent, scriptName);
> }
> {code}
> can fail like this:
> {noformat}
> java.lang.RuntimeException: java.lang.NoClassDefFoundError: 
> groovy/lang/GroovyObject
>         at 
> org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:955)
>         at 
> org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:650)
>         at 
> org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:627)
>         at 
> groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:389)
>         at 
> groovy.lang.GroovyClassLoader.lambda$parseClass$3(GroovyClassLoader.java:332)
>         at 
> org.codehaus.groovy.runtime.memoize.StampedCommonCache.compute(StampedCommonCache.java:163)
>         at 
> org.codehaus.groovy.runtime.memoize.StampedCommonCache.getAndPut(StampedCommonCache.java:154)
>         at 
> groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:330)
>         at 
> groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:314)
>         at 
> groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:257)
>         ....
> Caused by: java.lang.NoClassDefFoundError: groovy/lang/GroovyObject
>         at java.lang.ClassLoader.defineClass1(Native Method)
>         at java.lang.ClassLoader.defineClass(ClassLoader.java:757)
>         at java.lang.ClassLoader.defineClass(ClassLoader.java:636)
>         at 
> groovy.lang.GroovyClassLoader.defineClass(GroovyClassLoader.java:733)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.evaluateExpression(StaticTypeCheckingSupport.java:2176)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.checkClosureWithDelegatesTo(StaticTypeCheckingVisitor.java:3101)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodCallArguments(StaticTypeCheckingVisitor.java:2645)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodCallExpression(StaticTypeCheckingVisitor.java:3482)
>         at 
> org.codehaus.groovy.transform.sc.StaticCompilationVisitor.visitMethodCallExpression(StaticCompilationVisitor.java:409)
>         at 
> org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:76)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitBinaryExpression(StaticTypeCheckingVisitor.java:770)
>         at 
> org.codehaus.groovy.ast.CodeVisitorSupport.visitDeclarationExpression(CodeVisitorSupport.java:335)
>         at 
> org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitDeclarationExpression(ClassCodeVisitorSupport.java:150)
>         at 
> org.codehaus.groovy.ast.expr.DeclarationExpression.visit(DeclarationExpression.java:89)
>         at 
> org.codehaus.groovy.ast.CodeVisitorSupport.visitExpressionStatement(CodeVisitorSupport.java:117)
>         at 
> org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitExpressionStatement(ClassCodeVisitorSupport.java:200)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitExpressionStatement(StaticTypeCheckingVisitor.java:2120)
>         at 
> org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:40)
>         at 
> org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:86)
>         at 
> org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:164)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitBlockStatement(StaticTypeCheckingVisitor.java:3825)
>         at 
> org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:69)
>         at 
> org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:138)
>         at 
> org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:111)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitConstructorOrMethod(StaticTypeCheckingVisitor.java:2109)
>         at 
> org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:106)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.startMethodInference(StaticTypeCheckingVisitor.java:2477)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethod(StaticTypeCheckingVisitor.java:2435)
>         at 
> org.codehaus.groovy.transform.sc.StaticCompilationVisitor.visitMethod(StaticCompilationVisitor.java:235)
>         at org.codehaus.groovy.ast.ClassNode.visitMethods(ClassNode.java:1100)
>         at 
> org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1093)
>         at 
> org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:52)
>         at 
> org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitClass(StaticTypeCheckingVisitor.java:405)
>         at 
> org.codehaus.groovy.transform.sc.StaticCompilationVisitor.visitClass(StaticCompilationVisitor.java:193)
>         at 
> org.codehaus.groovy.transform.sc.StaticCompileTransformation.visit(StaticCompileTransformation.java:65)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>         at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:498)
>         at 
> org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43)
>         at 
> org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:191)
>         at 
> org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
>         at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
>         at 
> org.codehaus.groovy.control.customizers.ASTTransformationCustomizer.call(ASTTransformationCustomizer.groovy:297)
>         at 
> org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:921)
>         ... 30 more
> Caused by: java.lang.ClassNotFoundException: groovy.lang.GroovyObject
>         at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
>         at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
>         at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:869)
>         at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:979)
>         at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:967)
>         ... 75 more
> {noformat}
> This can happen if the compilation has been triggered by a thread started by 
> another OSGi bundle that does not import groovy packages, even though the 
> GroovyClassLoader has been explicitly created with the correct parent 
> ClassLoader that can indeed access those packages.
> So far I have tracked the issue to 
> {{org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport#evaluateExpression(final
>  Expression, final CompilerConfiguration)}}
>  where it creates a CompilationUnit without giving it a ClassLoader, which 
> results in the CompilationUnit creating a default GroovyClassLoader with 
> parent set to the thread context ClassLoader. I think that 
> StaticTypeCheckingSupport should be able to pass the parent ClassLoader that 
> the original GroovyClassLoader was configured with in order to avoid 
> unexpected results.
> I don't know whether there are more places during static type checking where 
> the issue could occur.
> The current workaround for this issue is to temporarily change the thread's 
> context ClassLoader to the one that is given to the GroovyClassLoader before 
> compiling a script, and then restoring the original context ClassLoader. This 
> is, however, probably not possible in all environments.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to