我试图做一些相当简单的事情。我想将整个方法代码包装到另一个用于测量执行时间的闭包块中。现在我收到了一条非常有用的错误消息:
Error:Groovyc: NPE while processing Test.groovy
注释:
@Retention(RetentionPolicy.SOURCE)
@Target([ElementType.METHOD])
@GroovyASTTransformationClass(["WithTimingASTTransformation"])
public @interface WithTiming {
}
我的包装封口:
class Benchmark {
static def measureTime(Closure cl) {
def start = System.currentTimeMillis()
def result = cl()
def time = System.currentTimeMillis() - start
println "it took $time"
result
}
}
我的转型:
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
class WithTimingASTTransformation implements ASTTransformation {
@Override
void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {
MethodNode method = astNodes[1]
method.code = wrap(method)
}
private Statement wrap(MethodNode method) {
def newBlock = new BlockStatement()
newBlock.addStatement(
new ExpressionStatement(
new StaticMethodCallExpression(
new ClassNode(Benchmark),
'measureTime',
new ArgumentListExpression(
new ClosureExpression(new Parameter[0], method.code)
))))
newBlock
}
}
我真的被困在这里,不知道如何调试问题。
对类似主题有一个答案(将整个方法体包装到try / catch块here中)。这很好,但我的情况略有不同。
答案 0 :(得分:0)
就我而言,类似的NPE来自:
java.lang.NullPointerException
at org.codehaus.groovy.classgen.asm.ClosureWriter.createClosureClass(ClosureWriter.java:194)
at org.codehaus.groovy.classgen.asm.ClosureWriter.getOrAddClosureClass(ClosureWriter.java:159)
at org.codehaus.groovy.classgen.asm.ClosureWriter.writeClosure(ClosureWriter.java:90)
at org.codehaus.groovy.classgen.AsmClassGenerator.visitClosureExpression(AsmClassGenerator.java:673)
鉴于:
if (parameters == null || expression.getVariableScope() == null) {
parameters = Parameter.EMPTY_ARRAY;
} else if (parameters.length == 0) {
// let's create a default 'it' parameter
Parameter it = new Parameter(ClassHelper.OBJECT_TYPE, "it", ConstantExpression.NULL);
parameters = new Parameter[]{it};
Variable ref = expression.getVariableScope().getDeclaredVariable("it");
if (ref != null) it.setClosureSharedVariable(ref.isClosureSharedVariable());
}
和第194行(截至https://github.com/groovy/groovy-core/commit/a52d0d3c5dd1cbb342992d36235171718a563c8b)是:
Variable ref = expression.getVariableScope().getDeclaredVariable("it");
因此,您需要为ClosureExpression定义VariableScope。我必须在org.codehaus.groovy.ast.ClosureWriter中添加跟踪才能找到这个,因为类生成阶段的异常显示存在问题 - 无论是在IntelliJ Idea还是在Groovy Console中 - 它都没有显示正确的代码行
此外,我认为ClosureWriter或ClosureExpression构造函数可以修复为默认工作 - 没有这个NPE。我可能会向Groovy Jira提交一个问题。
现在我可以在我的代码中注入闭包表达式。但努力称之为关闭。
获得:
groovy.lang.MissingMethodException: No signature of method: com.a9ae0b01f0ffc.VSMSGEN.implementation.T_visa_recon_generator$_convert_vts_log_to_ctf_closure2.call() is applicable for argument types: () values: []