Java 向groovy类添加属性时出现ArrayIndexOutOfBoundsException

Java 向groovy类添加属性时出现ArrayIndexOutOfBoundsException,java,groovy,Java,Groovy,我有java遗留代码,它加载groovy脚本并向加载的类中添加两个属性。它在groovy 1.7.0中运行良好,但当我尝试将groovy升级到1.8.0或更高版本时,它会导致稳定错误“类生成期间的一般错误:-1 java.lang.ArrayIndexOutOfBoundsException:-1”。 我尝试过使用groovy all-jar,但结果与Spring 2.5.6或3.2.11相同。下面是一个maven依赖项: <dependency> <groupId>

我有java遗留代码,它加载groovy脚本并向加载的类中添加两个属性。它在groovy 1.7.0中运行良好,但当我尝试将groovy升级到1.8.0或更高版本时,它会导致稳定错误“类生成期间的一般错误:-1 java.lang.ArrayIndexOutOfBoundsException:-1”。 我尝试过使用groovy all-jar,但结果与Spring 2.5.6或3.2.11相同。下面是一个maven依赖项:

<dependency>
  <groupId>org.codehaus.groovy</groupId>
  <artifactId>groovy-all</artifactId>
  <version>1.8.9</version>
</dependency>
但对于groovy 1.7.0,此测试打印:

     Single=true
     List=[a, b, c]

请帮忙。

我真的不知道你想做什么,但不是这个

ArgumentListExpression argumentListExpression = new ArgumentListExpression();
for (String attributeName : Arrays.asList("a", "b", "c"))
    argumentListExpression.addExpression(new ConstantExpression(attributeName));
classNode.addObjectInitializerStatements(new ExpressionStatement(new MethodCallExpression(
                        VariableExpression.THIS_EXPRESSION, "setProperty",
                        new ArgumentListExpression(new ConstantExpression("attrList"), argumentListExpression))));
这会产生你想要的行为吗

ArgumentListExpression argumentListExpression = new ArgumentListExpression();
argumentListExpression.addExpression(new ConstantExpression("attrList"))
for (String attributeName : Arrays.asList("a", "b", "c"));
    argumentListExpression.addExpression(new ConstantExpression(attributeName));
classNode.addObjectInitializerStatements(new ExpressionStatement(new MethodCallExpression(
                        VariableExpression.THIS_EXPRESSION, "setProperty", argumentListExpression)));
编辑

包grails.boot;
导入静态org.junit.Assert.assertTrue;
导入groovy.lang.GroovyClassLoader;
导入groovy.lang.GroovyCodeSource;
导入groovy.lang.GroovyObject;
导入java.security.CodeSource;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入org.codehaus.groovy.ast.ClassHelper;
导入org.codehaus.groovy.ast.ClassNode;
导入org.codehaus.groovy.ast.expr.ArgumentListExpression;
导入org.codehaus.groovy.ast.expr.ArrayExpression;
导入org.codehaus.groovy.ast.expr.ConstantExpression;
导入org.codehaus.groovy.ast.expr.Expression;
导入org.codehaus.groovy.ast.expr.MethodCallExpression;
导入org.codehaus.groovy.ast.expr.VariableExpression;
导入org.codehaus.groovy.ast.stmt.ExpressionStatement;
导入org.codehaus.groovy.classgen.GeneratorContext;
导入org.codehaus.groovy.control.compiledFailedException;
导入org.codehaus.groovy.control.compileUnit;
导入org.codehaus.groovy.control.CompilerConfiguration;
导入org.codehaus.groovy.control.Phases;
导入org.codehaus.groovy.control.SourceUnit;
导入org.junit.Test;
公共类是自治的{
@试验
public void testParsing()引发异常{
SimpleCustomizedGroovCyclassLoader自定义EdgroovCyclassLoader=新SimpleCustomizedGroovCyclassLoader(新GroovCyclassLoader());
类groovyClass;
试一试{
groovyClass=customizedGroovyClassLoader.parseClass(新的GroovyCodeSource(
“{fact->fact.a!=null}”,
CustomizedGroovCyclassLoader.generateScriptName(),
“/scriptSandbox”);
}捕获(例外e){
System.out.println(“错误加载类”);
投掷e;
}
assertTrue(groovyClass!=null);
GroovyObject GroovyObject=(GroovyObject)groovyClass.newInstance();
Boolean attrSingle=(Boolean)groovyObject.getProperty(“attrSingle”);
System.out.println(“Single=“+attrssingle”);
List attrList=new ArrayList();
Object[]objects=(Object[])groovyObject.getProperty(“attrList”);
用于(对象o:对象)
attrList.add((字符串)o);
System.out.println(“List=“+attrList”);
}
类SimpleCustomizedGroovCyclassLoader扩展了GroovCyclassLoader{
公共SimpleCustomizedGroovCyclassLoader(类装入器cl){
超级(cl);
}
@凌驾
受保护的CompilationUnit CreateComilationUnit(编译器配置配置,代码源){
CompilationUnit cu=super.createCompilationUnit(配置,源);
cu.addPhaseOperation(新的编译单元.PrimaryClassNodeOperation(){
公共void调用(SourceUnit SourceUnit、GeneratorContext上下文、ClassNode ClassNode)引发CompliationFailedException{
addObjectInitializerStatements(新表达式Statement(新方法调用Expression(
VariableExpression.THIS_表达式“setProperty”,
新ArgumentListExpression(新常量表达式(“attrSingle”),
新恒常压力(真(()())));
List args=new ArrayList();
ArgumentListExpression ArgumentListExpression=新ArgumentListExpression();
argumentListExpression.addExpression(新常量表达式(“属性列表”);
对于(字符串attributeName:Arrays.asList(“a”、“b”、“c”))
参数add(新常量表达式(属性名称));
ArrayExpression ArrayExpression=新的ArrayExpression(ClassHelper.make(Object.class),args);
argumentListExpression.addExpression(arrayExpression);
addObjectInitializerStatements(新表达式Statement(新方法调用Expression(
VariableExpression.THIS_表达式,“setProperty”,argumentListExpression));
}
}、阶段、转换);
返回cu;
}
}
}

非常感谢您,Jeff,它适用于1.7.0及更高版本

下面的代码稍微接近初始版本也可以工作:

               List<Expression> args = new ArrayList<Expression>();
                for (String attributeName : Arrays.asList("a", "b", "c"))
                    args.add(new ConstantExpression(attributeName));
                ArrayExpression arrayExpression = new ArrayExpression(ClassHelper.make(Object.class), args);

                classNode.addObjectInitializerStatements(new ExpressionStatement(new MethodCallExpression(
                        VariableExpression.THIS_EXPRESSION, "setProperty",
                        new ArgumentListExpression(new ConstantExpression("attrList"), arrayExpression))));
与提取器代码中的更改一起:

    List<String> attrList = (ArrayList<String>) groovyObject.getProperty("attrList");
    System.out.println("List=" + attrList); 
List attrList=(ArrayList)groovyObject.getProperty(“attrList”);
System.out.println(“List=“+attrList”);

据我所知,由于1.8.0版ArgumentListExpression不接受相同类型的参数(ArgumentListExpression),因此它必须是ListExpression或ArrayExpression类型,至少对于setProperty方法来说是有效的。

您是否尝试过更新到比2013年2月更新的版本?使用
2.3.6
运行此示例会导致
错误!源单元“Script100002.groovy”中的“类生成”阶段出现异常,在类Script100002方法void()中从操作数堆栈跟踪器弹出参数时出错。
Yes,groovy all 2.3.7的错误与Opal所说的相同。在另一个地方我读取了这些属性:GroovyObject GroovyObject=(GroovyObject)groovyClass.newInstance();
package grails.boot;

import static org.junit.Assert.assertTrue;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
import groovy.lang.GroovyObject;

import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
import org.codehaus.groovy.ast.expr.ArrayExpression;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.Phases;
import org.codehaus.groovy.control.SourceUnit;
import org.junit.Test;

public class GroovyTestAutonomous {

    @Test
    public void testParsing() throws Exception {
        SimpleCustomizedGroovyClassLoader customizedGroovyClassLoader = new SimpleCustomizedGroovyClassLoader(new GroovyClassLoader());
        Class<?> groovyClass;
        try {
            groovyClass = customizedGroovyClassLoader.parseClass(new GroovyCodeSource(
                    "{fact -> fact.a != null}",
                    customizedGroovyClassLoader.generateScriptName(),
                    "/scriptSandbox"));
        } catch (Exception e) {
            System.out.println("Error loading class");
            throw e;
        }
        assertTrue(groovyClass != null);
        GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();

        Boolean attrSingle = (Boolean) groovyObject.getProperty("attrSingle");
        System.out.println("Single=" + attrSingle);

        List<String> attrList = new ArrayList<String>();
        Object[] objects = (Object[]) groovyObject.getProperty("attrList");
        for (Object o : objects)
            attrList.add((String) o);
        System.out.println("List=" + attrList);
    }

    class SimpleCustomizedGroovyClassLoader extends GroovyClassLoader {
        public SimpleCustomizedGroovyClassLoader(ClassLoader cl) {
            super(cl);
        }

        @Override
        protected CompilationUnit createCompilationUnit(CompilerConfiguration config, CodeSource source) {
            CompilationUnit cu = super.createCompilationUnit(config, source);
            cu.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
                        public void call(SourceUnit sourceUnit, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {

                            classNode.addObjectInitializerStatements(new ExpressionStatement(new MethodCallExpression(
                                    VariableExpression.THIS_EXPRESSION, "setProperty",
                                    new ArgumentListExpression(new ConstantExpression("attrSingle"),
                                    new ConstantExpression(true)))));

                            List<Expression> args = new ArrayList<Expression>();
                            ArgumentListExpression argumentListExpression = new     ArgumentListExpression();
                            argumentListExpression.addExpression(new ConstantExpression("attrList"));
                            for (String attributeName : Arrays.asList("a", "b", "c"))
                                args.add(new ConstantExpression(attributeName));

                            ArrayExpression arrayExpression = new ArrayExpression(ClassHelper.make(Object.class), args);
                            argumentListExpression.addExpression(arrayExpression);
                            classNode.addObjectInitializerStatements(new ExpressionStatement(new MethodCallExpression(
                                    VariableExpression.THIS_EXPRESSION, "setProperty", argumentListExpression)));
                        }
                    }, Phases.CONVERSION);
            return cu;
        }
    }
}
               List<Expression> args = new ArrayList<Expression>();
                for (String attributeName : Arrays.asList("a", "b", "c"))
                    args.add(new ConstantExpression(attributeName));
                ArrayExpression arrayExpression = new ArrayExpression(ClassHelper.make(Object.class), args);

                classNode.addObjectInitializerStatements(new ExpressionStatement(new MethodCallExpression(
                        VariableExpression.THIS_EXPRESSION, "setProperty",
                        new ArgumentListExpression(new ConstantExpression("attrList"), arrayExpression))));
                ListExpression args = new ListExpression();
                for (String attributeName : Arrays.asList("a", "b", "c"))
                    args.addExpression(new ConstantExpression(attributeName));

                classNode.addObjectInitializerStatements(new ExpressionStatement(new MethodCallExpression(
                        VariableExpression.THIS_EXPRESSION, "setProperty",
                        new ArgumentListExpression(new ConstantExpression("attrList"), args))));
    List<String> attrList = (ArrayList<String>) groovyObject.getProperty("attrList");
    System.out.println("List=" + attrList);