Ivan Kuznetsov created GROOVY-9283:
--------------------------------------
Summary: Nested closures run on wrong delegate
Key: GROOVY-9283
URL: https://issues.apache.org/jira/browse/GROOVY-9283
Project: Groovy
Issue Type: Bug
Components: Static compilation
Affects Versions: 3.0.0-beta-3, 2.5.7
Environment: CentOS Linux release 7.7.1908 (Core), openjdk 12.0.2
2019-07-16
Reporter: Ivan Kuznetsov
We use Groovy to write DSL scripts for our project, and the only version we can
use now is 2.5.6 because of bug with {{\@CompileStatic}} wich is reproducible
with the following code:
{code:java}
package test;
import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
import groovy.lang.GroovyClassLoader;
import groovy.transform.CompileStatic;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer;
import org.codehaus.groovy.runtime.InvokerHelper;
public class Main {
private static final String script = "" +
"import test.Main\n" +
"\n" +
"new Main().enter {\n" +
" nest {\n" +
" nest {\n" +
" nest {\n" +
" println(\"REACHED\")\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n";
public static void main(String[] args) {
CompilerConfiguration config = new CompilerConfiguration();
config.addCompilationCustomizers(new
ASTTransformationCustomizer(CompileStatic.class));
GroovyClassLoader loader = new
GroovyClassLoader(Main.class.getClassLoader(), config);
Class<?> cls = loader.parseClass(script, "file");
InvokerHelper.runScript(cls, new String[0]);
}
public void enter(@DelegatesTo(Root.class) Closure<?> closure) {
Root scope = new Root();
closure.setDelegate(scope);
closure.run();
}
public static class Outer extends Main {
private final Main parent;
Outer() {
this.parent = null;
}
Outer(Outer parent) {
this.parent = parent;
}
public void nest(@DelegatesTo(Inner.class) Closure<?> closure) {
closure.setDelegate(new Inner(this));
closure.run();
System.out.println(this + ": " + parent);
}
}
public static class Inner extends Outer {
public Inner(Outer parent) {
super(parent);
}
}
public static class Root extends Outer {
Root() {
}
}
}
{code}
till version 2.5.6 it prints:
{noformat}
REACHED
test.Main$Inner@7582ff54: test.Main$Inner@67545b57
test.Main$Inner@67545b57: test.Main$Root@6c2c1385
test.Main$Root@6c2c1385: null
{noformat}
but starting with 2.5.7 it prints:
{noformat}
REACHED
test.Main$Root@2f67b837: null
test.Main$Root@2f67b837: null
test.Main$Root@2f67b837: null
{noformat}
The workaround is to turn off static compilation, but it degrades performance
because some handles are defined using this DSL and they are called very often.
Thanks in advance!
--
This message was sent by Atlassian Jira
(v8.3.4#803005)