2011-03-31 141 views
3

我以奇怪的方式获得NPE。其次是方法调用,因为它的它的发生:NPE采用常规方法编译时

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块(甚至声明只)我得到常规产生的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变量不为空。但我无法弄清楚到底发生了什么。

+0

您使用的是什么版本的Groovy? – 2011-03-31 14:22:58

+0

你使用哪个SSH库? – 2011-03-31 14:28:23

+0

@Emil,1.7.10; @tim_yates,请不要尝试进入你实际上不需要的东西。 – 2011-03-31 15:37:46

回答

2

它看起来像把如果(错误)返回null;终于块进入方法结束了伎俩,不完全确定为什么,但。

0

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

+0

是的,这不是问题。 (这意味着它是潜在的问题,但不适合特定的代码)请参阅我的答案。 – 2011-03-31 15:38:20

2

问题不在代码中,而是随着groovy编译它的方式,所以最好的检查地点是他们的bug跟踪器http://jira.codehaus.org/browse/GROOVY
您可以查找现有问题或创建一个问题。
这里是一个简化的例子,触发errror,我不知道它是否可以变小,因为我不知道确切的问题。

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

我会说有嵌套try块和明确的回报之间的相互作用。还要注意,这个块必须是方法中的最后一个语句(如果用作脚本,它会抛出该NPE,这是run()方法的最后一个语句)。