【问题标题】:Java very unusual classpath problemsJava 非常不寻常的类路径问题
【发布时间】:2013-02-13 19:52:34
【问题描述】:

我正在尝试使用以下代码运行具有本机库和内容的应用程序:

ProcessBuilder pb = new ProcessBuilder("javaw",
    "-classpath", 
    binDir + "polyrd.jar;" + binDir + "lwjgl.jar;" + binDir + "lwjgl_util.jar;",
    "-Djava.library.path=" + nativesDir,
    "monster860.polyrd.Polyrd");

我尝试在命令行中执行等效操作,将其更改为 -cp,仅使用 bindir 而不是 binDir + "polyrd.jar;" + binDir + "lwjgl.jar;" + binDir + "lwjgl_util.jar;",并在 java 和 javaw 之间切换,但无论我做什么,它都给了我:

java.lang.NoClassDefFoundError: monster860/polyrd/Polyrd
Caused by: java.lang.ClassNotFoundException: monster860.polyrd.Polyrd
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source) 

谁能帮忙?

我的操作系统是 Windows Vista。 是的,这些文件确实存在。

这是我得到binDirnativesDir 的方法:

public ProcessRunnable(File nativesDir, File binDir) {
        try {
            this.nativesDir = nativesDir.getCanonicalPath() + File.separator;
            this.binDir = binDir.getCanonicalPath() + File.separator;
        } catch (IOException e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

编辑: 好吧,当然,它与此完全无关,但下载器只下载文件的前 2 KB。

【问题讨论】:

  • 好吧,binDir 是什么,你在什么操作系统上运行,所有这些文件是否真的存在,等等?
  • 使用 IDE 怎么样?
  • @JonSkeet:必须是所有东西都在同一个目录中。所以他单独保存目录位置并将其添加到此字符串中。我确定它代表保存 jar 文件的文件夹位置
  • 你知道monster860/polyrd/Polyrd类位于哪个jar吗?
  • 请发布您的确切命令行或脚本

标签: java jar classpath


【解决方案1】:

从 Java 6 开始,“为了特别方便,包含基本名称 * 的类路径元素被认为等同于指定目录中所有扩展名为 .jar.JAR 的文件的列表”。有关详细信息,请参阅java 命令行选项。

附录:此示例使用提到的通配符功能以 JFreeChart 开头。

import java.io.BufferedReader;
import java.io.InputStreamReader;

/** @see https://stackoverflow.com/a/15121864/230513 */
public class PBTest {

    private static final String baseDir = "/opt/jfreechart/";
    public static void main(String[] args) {
        ProcessBuilder pb = new ProcessBuilder("java", "-cp",
            baseDir + "lib/*:" + baseDir + "jfreechart-1.0.14-demo.jar",
            "demo.SuperDemo");
        pb.redirectErrorStream(true);
        try {
            Process p = pb.start();
            String s;
            // read from the process's combined stdout & stderr
            BufferedReader stdout = new BufferedReader(
                new InputStreamReader(p.getInputStream()));
            while ((s = stdout.readLine()) != null) {
                System.out.println(s);
            }
            System.out.println("Exit value: " + p.waitFor());
            p.getInputStream().close();
            p.getOutputStream().close();
            p.getErrorStream().close();
        } catch (Exception ex) {
            ex.printStackTrace(System.err);
        }
    }
}

附录:以下是 Windows 的更改,需要 ; 作为路径分隔符。

private static final String baseDir = "C:/Users/Public/JFreeChart/";
public static void main(String[] args) {
    ProcessBuilder pb = new ProcessBuilder("java", "-cp",
        baseDir + "lib/*;" + baseDir + "jfreechart-1.0.14-demo.jar",
        "demo.SuperDemo");

【讨论】:

  • 我很难理解这一点,但我尝试了bindir + "*",但它不起作用。
  • 就是这样,我使用File.getCanonicalPath() 并附加“/”,并将其分配为“binDir”。
  • 您是否正在连接getCanonicalPath()/*?愿您更新您的问题以向您展示当前的方法。
  • 嗯,我所做的是将binDir设置为File.getCanonicalPath(),在尝试您的方法时,我在ProcessBuilder构造函数中添加了*
  • 我在上面添加了一个工作示例;注意我的操作系统使用: 来分隔路径,你的使用;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多