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)

Reply via email to