You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2022/11/20 21:59:00 UTC

[jira] [Comment Edited] (GROOVY-9541) Compiling statically using GroovyClassLoader does not always respect the configured parent ClassLoader

    [ https://issues.apache.org/jira/browse/GROOVY-9541?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17630479#comment-17630479 ] 

Eric Milles edited comment on GROOVY-9541 at 11/20/22 9:58 PM:
---------------------------------------------------------------

https://github.com/apache/groovy/commit/bf405f70bc8b2ff24150f8d5249023a29da224ed
https://github.com/apache/groovy/commit/bc0a240bc801f31833e80ed01d9c1a27d25fe984


was (Author: emilles):
https://github.com/apache/groovy/commit/bf405f70bc8b2ff24150f8d5249023a29da224ed

> 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)