Filip Hrisafov created GROOVY-10579:
---------------------------------------
Summary: Type '[I' is not assignable to reference type when using
Groovy 3.0.10
Key: GROOVY-10579
URL: https://issues.apache.org/jira/browse/GROOVY-10579
Project: Groovy
Issue Type: Bug
Affects Versions: 3.0.10
Reporter: Filip Hrisafov
We are having a strange problem when using static compile transformation.
Most likely what we are doing is not the best approach. However, this was
working in 3.0.9 and stopped working with 3.0.10.
If we take this main class:
{code}
package org.example;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer;
import org.codehaus.groovy.jsr223.GroovyScriptEngineImpl;
import groovy.lang.GroovyClassLoader;
import groovy.transform.CompileStatic;
public class GroovyProblemExample {
public static final String VAR_TYPES = "variable.types";
public static final ThreadLocal<Map<String, Object>> COMPILE_OPTIONS = new
ThreadLocal<>();
public static void main(String[] args) throws ScriptException {
ScriptEngine scriptEngine = new
GroovyScriptEngineImpl(createClassLoader());
String script = ""
+ "int sum = 0\n"
+ "for ( i in inputArray ) {\n"
+ " sum += i\n"
+ "}\n"
+ "execution.setVariable(\"sum\", sum)";
Map<String, Object> input = new HashMap<>();
TestExecution execution = new TestExecution();
int[] inputArray = new int[] { 1, 2, 3, 4, 5 };
input.put("inputArray", inputArray);
input.put("execution", execution);
Bindings bindings = createBindings(input);
COMPILE_OPTIONS.remove();
Map<String, ClassNode> variableTypes = new HashMap<>();
for (Map.Entry<String, Object> entry : bindings.entrySet()) {
variableTypes.put(entry.getKey(),
ClassHelper.make(entry.getValue().getClass()));
}
variableTypes.put("execution", ClassHelper.make(TestExecution.class));
Map<String, Object> options = new HashMap<>();
options.put(VAR_TYPES, variableTypes);
COMPILE_OPTIONS.set(options);
scriptEngine.eval(script, bindings);
System.out.println(execution.getVariable("sum"));
}
public static Bindings createBindings(Map<String, Object> parameters) {
return new SimpleBindings(parameters);
}
public static GroovyClassLoader createClassLoader() {
return new
GroovyClassLoader(GroovyProblemExample.class.getClassLoader(),
createStaticConfiguration(), true);
}
protected static CompilerConfiguration createStaticConfiguration() {
CompilerConfiguration compilerConfiguration = new
CompilerConfiguration();
ASTTransformationCustomizer astTransformationCustomizer = new
ASTTransformationCustomizer(
Collections.singletonMap("extensions",
Collections.singletonList("ExampleExtension.groovy")),
CompileStatic.class,
"org.codehaus.groovy.transform.sc.StaticCompileTransformation");
compilerConfiguration.addCompilationCustomizers(astTransformationCustomizer);
return compilerConfiguration;
}
public static class TestExecution {
protected final Map<String, Object> data = new HashMap<>();
public void setVariable(String name, Object value) {
data.put(name, value);
}
public Object getVariable(String name) {
return data.get(name);
}
}
}
{code}
and this extension:
{code}
import static org.example.GroovyProblemExample.COMPILE_OPTIONS
import static org.example.GroovyProblemExample.VAR_TYPES
def typesOfVariables = COMPILE_OPTIONS.get()[VAR_TYPES]
unresolvedVariable { var ->
if (typesOfVariables[var.name]) {
return makeDynamic(var, typesOfVariables[var.name])
}
}
{code}
Running the main class with Groovy 3.0.9 we have 15 printed out in the console.
However, running it with 3.0.10 we get the following error:
{code}
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack in
aaload
Exception Details:
Location:
Script1.run()Ljava/lang/Object; @54: aaload
Reason:
Type '[I' (current frame, stack[0]) is not assignable to reference type
Current Frame:
bci: @54
flags: { }
locals: { 'Script1', '[Lorg/codehaus/groovy/runtime/callsite/CallSite;',
integer, top, '[I', integer, integer }
stack: { '[I', integer }
Bytecode:
0000000: 00b8 0024 4c03 3d1c 5701 4e2b 1225 322a
0000010: b900 2b02 0059 122d b800 33c0 002d 3a04
0000020: c600 2719 04be 3605 0336 0615 0615 05a2
0000030: 0018 1904 1506 324e 8406 011c 2db8 0039
0000040: 6059 3d57 a7ff e72b 123a 322a b900 2b02
0000050: 00c0 003c 123e 1cb8 0044 b600 4801 b0
Stackmap Table:
full_frame(@43,{Object[#2],Object[#77],Integer,Top,Object[#45],Integer,Integer},{})
chop_frame(@71,2)
at java.base/java.lang.Class.getDeclaredConstructors0(Native Method)
at
java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3373)
at java.base/java.lang.Class.getConstructor0(Class.java:3578)
at java.base/java.lang.Class.getConstructor(Class.java:2271)
at
org.codehaus.groovy.runtime.InvokerHelper.newScript(InvokerHelper.java:502)
at
org.codehaus.groovy.runtime.InvokerHelper.createScript(InvokerHelper.java:461)
at
org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:266)
at
org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:155)
at
java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:231)
at org.example.GroovyProblemExample.main(GroovyProblemExample.java:55)
{code}
This happens with Java 17 and Java 11.
This is a simplified example that is taken from something that we have in the
Flowable Engine
(https://github.com/flowable/flowable-engine/tree/main/modules/flowable-groovy-script-static-engine).
--
This message was sent by Atlassian Jira
(v8.20.1#820001)