У меня есть код устаревшего java, который загружает groovy-скрипт и добавляет два свойства в загруженный класс. Он отлично работает с groovy 1.7.0, но когда я пытаюсь обновить groovy до версии 1.8.0 или более поздней версии, он вызывает стабильную ошибку «Общая ошибка при генерации класса: -1 java.lang.ArrayIndexOutOfBoundsException: -1». Я пробовал использовать барабанную палочку, но результат был таким же, как у Spring 2.5.6 или 3.2.11. Ниже приведена зависимость от maven:ArrayIndexOutOfBoundsException при добавлении свойства в класс groovy
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>1.8.9</version>
</dependency>
Короткий тест, который воспроизводит ошибку. Интересно, что при добавлении простого свойства (attrSingle) ошибка не возникает, но только при добавлении списка (attrList).
редактируется (добавлено получение свойств)
import groovy.lang.*;
import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.control.*;
import org.junit.Test;
import java.security.CodeSource;
import java.util.*;
import static org.junit.Assert.assertTrue;
public class TestGroovyAutonomous {
@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)))));
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))));
}
}, Phases.CONVERSION);
return cu;
}
}
}
И ошибка текст:
index problem in script1000001.groovy
Error loading class
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during class generation: -1
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:400)
at java.util.ArrayList.remove(ArrayList.java:477)
at org.codehaus.groovy.classgen.asm.OperandStack.remove(OperandStack.java:199)
at org.codehaus.groovy.classgen.asm.OperandStack.replace(OperandStack.java:270)
at org.codehaus.groovy.classgen.asm.CallSiteWriter.makeCallSite(CallSiteWriter.java:334)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCall(InvocationWriter.java:187)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeCall(InvocationWriter.java:89)
at org.codehaus.groovy.classgen.asm.InvocationWriter.makeInvokeMethodCall(InvocationWriter.java:73)
at org.codehaus.groovy.classgen.asm.InvocationWriter.writeInvokeMethod(InvocationWriter.java:292)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitMethodCallExpression(AsmClassGenerator.java:655)
at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:75)
at org.codehaus.groovy.classgen.asm.StatementWriter.writeExpressionStatement(StatementWriter.java:599)
at org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.writeExpressionStatement(OptimizingStatementWriter.java:354)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitExpressionStatement(AsmClassGenerator.java:501)
at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:40)
at org.codehaus.groovy.classgen.asm.StatementWriter.writeBlockStatement(StatementWriter.java:80)
at org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.writeBlockStatement(OptimizingStatementWriter.java:155)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitBlockStatement(AsmClassGenerator.java:447)
at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:69)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:101)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:112)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitStdMethod(AsmClassGenerator.java:311)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructorOrMethod(AsmClassGenerator.java:268)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructor(ClassCodeVisitorSupport.java:119)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructor(AsmClassGenerator.java:383)
at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1054)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:50)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitClass(AsmClassGenerator.java:172)
at org.codehaus.groovy.control.CompilationUnit$14.call(CompilationUnit.java:770)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:970)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:548)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:526)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:503)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:302)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:281)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:267)
at x.y.TestGroovyAutonomous.testParsing(TestGroovyAutonomous.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Но с заводной 1.7.0 этот тест печатает:
Single=true
List=[a, b, c]
Пожалуйста, помогите.
Вы пробовали обновление до версии более поздней, чем февраль 2013 года? –
Запуск этого примера с результатом '2.3.6' в' BUG! исключение в фазе «генерация класса» в исходной единице «script1000002.groovy» Ошибка при появлении аргумента из операнда стека в классе script1000002 метод void(). –
Opal
Да, получая ту же ошибку с groovy-all 2.3.7, как говорит Опал , – GodVic