Java 向groovy类添加属性时出现ArrayIndexOutOfBoundsException
我有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依赖项: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>
<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);