【问题标题】:I don't understand why this ClassNotFoundException gets thrown我不明白为什么抛出这个 ClassNotFoundException
【发布时间】:2021-01-18 11:21:08
【问题描述】:

我正在从我的一个类中执行 java 二进制文件,然后抛出 ClassNotFoundException:


Results of executing:/usr/bin/java -classpath "/home/geo" Geoline
Error stream:
Exception in thread "main" java.lang.NoClassDefFoundError: Geoline
Caused by: java.lang.ClassNotFoundException: Geoline
        at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
Could not find the main class: Geoline. Program will exit.
Output stream:

Geoline 类位于 /home/geo/Geoline.java。问题是,无论我位于文件系统的哪个位置,如果我手动执行相同的命令,就会执行该类。为什么使用 Runtime.getRuntime().exec 执行二进制文件时会发生不同的事情?

edit: 这是使用详细标志生成的输出:pastie link 编辑:这是文件的内容:


public class Geoline {
    public static void main(String[] args) {
        System.out.println("blabla");
    }
}

【问题讨论】:

  • 为什么要引用 .java 文件?我讨厌问一个“愚蠢”的问题,但你有没有把它编译成一个 .class 文件?以及路径 /home/geo/Geoline.class 所在的目录是在 CLASSPATH 中吗?
  • 是的,已编译。编译发生在运行操作之前。 -classpath "/home/geo" 不是加载到CLASSPATH中吗?
  • 类有包吗?如果是,则包的根目录必须位于 CLASSPATH 中。如果没有,请添加一个。没有包的类是微不足道的。
  • 该类不属于包。 /home/geo 在这种情况下不是好目录吗?
  • 以防万一启用 -verbose 选项,看看是否有任何奇怪的事情

标签: java exception


【解决方案1】:

很难判断发生了什么,因为您没有发布代码。

不过,这是我最有根据的猜测。

您试图将整个命令运行到 java String 中,而 java 解释器没有将它们识别为不同的参数。

尝试将它们全部打包在 String[]

所以不是

Runtime.getRuntime().execute("/usr/bin/java -classpath \"/home/geo\" Geoline");

尝试:

Runtime.getRuntime().execute( new String[]{
               "/usr/bin/java","-classpath","/home/geo","Geoline"
});

或者,您可以发布您的实际代码,我们可以看看发生了什么。

编辑

这是我的尝试。我创建了 RunIt.java 类,它基本上是我建议的 Runtime.execHello.java 几乎说 Hello + args[0]

这是输出:

$cat RunIt.java 
import java.io.*;

public class RunIt{ 
    public static void main( String [] args ) throws IOException  {
        Process p = Runtime.getRuntime().exec(  args );
        BufferedReader reader = new BufferedReader( new InputStreamReader ( p.getInputStream() ) );
        String line = null;

        while( ( line = reader.readLine() ) != null ) {
            System.out.println( line );
        }
        reader.close();
    }
}
$cat Hello.java 
public class Hello { 
    public static void main( String [] args ) {
        System.out.println("Hola: " +  ( args.length > 0 ?  args[0] : " a nadie" ) );
    }
}
$javac RunIt.java 
$java RunIt javac Hello.java 
$java RunIt java Hello Mundo
Hola: Mundo
$

【讨论】:

    【解决方案2】:

    您可能需要阅读以下内容:When Runtime.exec() won't

    【讨论】:

    • 那篇文章是怎么回事?我从来不想读它,但它的日期是 2000 年。也许事情已经解决了。在 Java1.5 中,向 JRE 添加了一个新类:java.sun.com/j2se/1.5.0/docs/api/java/lang/ProcessBuilder.html 我不知道它是否可以修复那篇文章所说的内容。你有总结吗?
    • 告诉你使用 Runtime.exec() 时的陷阱。 Vintage 2000,但仍然值得了解,因为从那时起 Runtime 没有发生任何变化。
    【解决方案3】:

    不确定您的系统是什么,但 Runtime.exec 与 shell 不同:尝试在类路径周围不带 "

    /usr/bin/java -classpath /home/geo Geoline
    

    (或将 exec 与数组参数一起使用)
    我假设你的类文件是 /home/geo/Geoline.class

    编辑:如果您尝试使用标准输出重定向“dosomething > somefile”,也会发生同样的情况
    Runtime.exec 也无法识别这一点

    []]

    【讨论】:

      猜你喜欢
      • 2023-02-01
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      • 2019-09-07
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      • 2023-03-16
      相关资源
      最近更新 更多