编译时的常规方法中的NPE

时间:2011-03-31 14:06:05

标签: groovy try-catch nullpointerexception

我以一种奇怪的方式得到了一个N​​PE。接下来是方法调用,因为它正在发生:

    String exec(String command) {
        if (command == null || isConnected()) return null;

        Session session = null;
        boolean error = false;
        try {
            session = ssh.startSession();
//           try {
//                final Session.Command cmd = session.exec(command);
//                String result = cmd.getOutputAsString();
//                if (cmd.getExitStatus() != null && cmd.getExitStatus() != 0){
//                    //TODO:command execution failure should be logged
//                    error = true;
//                } else {
//                    return result;
//                }

//            } catch (Exception ex){
//                //TODO:command execution failure should be logged
//                ex.printStackTrace();
//                error = true;
//            }
        } catch (Exception ex) {
            // TODO:session creation failure should be logged
            ex.printStackTrace();
            error = true;
        } finally {
            session.close();
            if (error) return null;
        }
    }

如果我取消注释内部try / catch块(仅限声明),我会得到一个由groovy生成的NPE,如下所示:

java.lang.NullPointerException
    at org.objectweb.asm.MethodWriter.visitMaxs(Unknown Source)
    at org.objectweb.asm.MethodAdapter.visitMaxs(Unknown Source)
    at org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructorOrMethod(AsmClassGenerator.java:605)
    at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:123)
    at org.codehaus.groovy.classgen.AsmClassGenerator.visitMethod(AsmClassGenerator.java:696)
    at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1039)
    at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:50)
    at org.codehaus.groovy.classgen.AsmClassGenerator.visitClass(AsmClassGenerator.java:276)
    at org.codehaus.groovy.control.CompilationUnit$12.call(CompilationUnit.java:748)
    at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:942)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:519)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:497)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:474)
    at org.jetbrains.groovy.compiler.rt.GroovyCompilerWrapper.compile(GroovyCompilerWrapper.java:43)
    at org.jetbrains.groovy.compiler.rt.GroovycRunner.main(GroovycRunner.java:128)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:75)

代码没什么特别的, ssh 变量不是null。但我无法弄清楚到底发生了什么。

3 个答案:

答案 0 :(得分:2)

看起来像把 if(error)返回null; finally 块中移出到方法结束就可以了,但还不完全确定原因。

答案 1 :(得分:2)

问题不在代码中,但groovy正在编译它的方式,因此检查的最佳位置是他们的错误跟踪器http://jira.codehaus.org/browse/GROOVY
您可以查找现有问题或创建问题 这是一个触发错误的简化示例,我不知道它是否可以变小,因为我不知道确切的问题。

try {
  try {} catch (e) {}
} finally {
  return anything
}

我会说嵌套的try块和显式返回之间存在一些交互。还要注意这个块必须是方法中的最后一个语句(如果用作脚本就像抛出那个NPE一样,是run()方法的最后一个语句)。

答案 2 :(得分:0)

finally块中的

session.close()会抛出一个NPE,因为如果ssh.startSession()失败,会话永远不会被初始化。或者我错过了吗?