【问题标题】:Using a jar in a Java project?在 Java 项目中使用 jar?
【发布时间】:2010-11-01 12:56:42
【问题描述】:

我正在尝试使用作为 jar 文件(例如称为 Hello.jar)的项目提供的公共方法/分类,该文件包含在名为 hello 的包中。

package hello;

public class Hello
{

 public static void main(String[] args)
 {
    coucou();
 }

 public static void coucou()
 {
   System.out.println("Hello there");
 }

}

在一个名为 Tool 的单独项目中,我希望能够调用方法 Hello.coucou() 所以我写了这样的东西:

import hello.*;

public class Tool
{

 public static void main(String[] args)
 {
   System.out.println("main program running");
   Hello.coucou();

 }

}

我使用以下命令编译 Tool.java(在 linux 下):

$ javac Tool.java -classpath .:./extern/:

Hello.jar 在文件夹./extern中的位置

这似乎编译得很好,但是当我启动它(即 java 工具)时,我得到了这个:

main program running
Exception in thread "main" java.lang.NoClassDefFoundError: hello/Hello
    at Tool.main(Tool.java:9)
Caused by: java.lang.ClassNotFoundException: hello.Hello
    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)
    ... 1 more

我是 Java 新手(C/C++ 背景),我不明白我做错了什么。 有什么想法吗?

干杯 大卫


编辑:我尝试在命令行中将 Hello.jar 添加到类路径中,但仍然出现相同的错误:

$ javac Tool.java -classpath .:./extern/Hello.jar:
$ java Tool -classpath .:./extern/Hello.jar:
main program running
Exception in thread "main" java.lang.NoClassDefFoundError: hello/Hello
    at Tool.main(Tool.java:9)
Caused by: java.lang.ClassNotFoundException: hello.Hello
    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)
    ... 1 more

【问题讨论】:

  • 我希望用分号而不是冒号分隔类路径。
  • Windows:分号 Linux:冒号

标签: java linux command-line jar


【解决方案1】:

运行和编译时都需要类路径中的 Hello.jar。

【讨论】:

    【解决方案2】:

    其实诀窍在于命令行中参数的顺序:

    是-cp(或-classpath)是最后设置的,那么就不起作用了

    java Tool -cp .:extern/Hello.jar
    

    它必须首先像:

    java -cp .:extern/Hello.jar Tool
    

    !!!

    【讨论】:

    • 是的。否则,“-cp 不管”作为 args 数组传递给 main()。您需要记住 args 到 java 运行时和 args 到您的程序之间的区别。
    • 啊,当然,现在说得通了——感谢您的解释!
    【解决方案3】:

    Java 使用动态后期绑定,因此在编译期间将 JAR 放在类路径中只是为了确保您的代码正确使用其中的类,但它实际上并不像链接器在 C 中那样将它们嵌入到您的代码中/C++。因此,您还需要在执行代码时设置类路径。

    但是,这个:

    $ javac Tool.java -classpath .:./extern/:
    

    也不应该工作,因为 JAR 需要直接放入类路径,而不仅仅是它们所在的目录:

    $ javac Tool.java -classpath .:./extern/Hello.jar
    

    最后,您将代码放入默认的无名包中。这对于胡闹是可以的,但从长远来看会导致问题(一方面,您无法从其他任何地方的默认包中导入类)。

    【讨论】:

      【解决方案4】:

      运行 Java 时,还必须添加 jar 文件(仅添加目录路径不起作用)。

      查看classpath 信息。

      应该是这样的:

      java -classpath /java/MyClasses/myclasses.jar utility.myapp.Cool
      

      【讨论】:

      • 实际上分号完全把事情搞砸了,它应该真的是一个冒号。问题的诀窍是首先使用 -classpath 选项,即在 Tool 之前。
      • 是的,很抱歉,我不知何故忽略了问题的 Linux 部分,但当我意识到这一点时更新了答案以反映这一点。
      【解决方案5】:

      您也需要在启动时将 Hello.jar 文件包含在类路径中。

      【讨论】:

        【解决方案6】:

        java -cp xxx.jar 你好,其中 xxx 是你想在你的类路径中拥有的 jar,如果你想要多个 jar,然后使用 ;

        分隔它们

        卡尔

        【讨论】:

          猜你喜欢
          • 2011-03-04
          • 2013-10-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-03
          • 1970-01-01
          相关资源
          最近更新 更多