快速的个人背景:几个月前,我被一家公司(其他开发人员都是php开发者)的唯一.NET开发人员(C#)聘用。在工作一周后,我被告知他们想要切换到Java而不是.NET。不是一个理想的情况,但我正努力让它发挥作用。
我认为我不理解项目库和类路径之间的关系。我正在使用NetBeans 6.7.1进行开发。我目前的项目是创建一个应用程序,它将更新多个商家来源(eBay,亚马逊等)。我创建了一个类库项目来处理这些更新的计划。我们称之为更新。
我正在为各种来源(例如eBay)创建类库项目。我将ebay项目作为库添加到Update项目中。在IDE中有一个框,其中显示“在类路径上构建项目”,该框被选中。
最后,现在我有一个小的控制台应用程序,其中Update项目被引用为库(因此ebay项目现在是2个库深)以相同的方式。它适用于Update项目中的代码。
这可以正常工作,直到我在ebay项目中实例化一个类(来自通过控制台应用程序的Update项目)。那时我得到了一个
Exception in thread "main"
java.lang.NoClassDefFoundError
是
Caused by: java.lang.ClassNotFoundException
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
这些项目都构建良好,但这个运行时异常正在扼杀我。我不知道我是否真的理解将一个库添加到项目中的内容,以及是否还需要做些什么才能使该类可访问。我习惯于能够添加对DLL的引用并且很好。我不明白为什么我没有得到任何编译器错误或构建错误但我得到关于可访问性的运行时错误。我猜这个类路径是一个我不太了解的缺失部分,虽然我认为这个问题可能完全与其他东西有关。
答案 0 :(得分:3)
我强烈建议选择Core Java,第1卷和第2卷。对于想要理解语言内部的Java开发人员,例如ClassLoader,必须阅读这些内容。至少,请阅读课程加载。
要回答您的问题,更新项目应该生成.class文件或jar。您需要在类路径中为您引用它们的项目提供类文件或jar的位置。根据您的IDE,对项目的引用可能只允许您访问源,以进行编译。
答案 1 :(得分:3)
您需要将Java概念与特定于IDE的概念分开。我建议在进入NetBeans之前使用文本编辑器和命令shell进行简单的java教程。
库和项目是NetBeans特定术语。我不是NetBeans用户,因此我不会尝试猜测它们是什么,虽然我有一些猜测,但我会说它们的配置很可能会影响编译时环境。
Classpath是一个核心Java概念。您必须在运行时向java
命令提供所有类(或包含这些类的jar)的路径,以便它能够加载这些类。 (您还需要在编译时对javac
命令执行与您引用但尚未编译的类相同的命令。
任何时候您都会看到java.lang.ClassNotFoundException
,这意味着在您启动运行时,类路径中缺少编译代码时类路径中存在的某些类。
答案 2 :(得分:2)
在Java中,与C#不同,您需要将类路径显式添加到项目中。我使用eclipse,我必须这样做才能获得一些引用的jar。
答案 3 :(得分:1)
我现在提出的解决方案:
我希望嵌套库中的引用“冒泡”。这显然不适用于类路径。我的结构基本上是:
A引用B引用C
当我运行A时,它工作正常,直到它得到了C中的内容。我所做的是通过将C作为库添加到项目中来直接引用C。从一些快速的谷歌搜索来看,这看起来就像你在NetBeans中为项目添加类路径一样。
对我来说似乎有些混乱,也许有更好的方法可以做到这一点,但它现在解决了我的问题。感谢所有回答的人 - 虽然没有人能够解决我的特定问题(你们大约有95%的人在那里得到了我们)但他们验证了我的想法并让我弄清楚最后的一点点才能实现。
答案 4 :(得分:1)
Exception in thread "main"
java.lang.NoClassDefFoundError
错误消息中缺少类名,但我们假设您要为其执行main
方法的类本身。在这种情况下,它只是意味着Java无法在运行时类路径中找到特定的类。
要解决此问题,您需要cd
到该类所在的包的根目录,然后重新执行java
命令,如下所示:
java -cp . com.example.MainClass
此处-cp
参数指定类路径。它只有.
的值,这意味着当前的工作目录应该被带入类路径(这通常是默认情况,但比没有更安全)。
或者,您可以在-cp
参数中指定其完整路径,以便您可以从任何地方执行它,例如:
java -cp /path/to/package/root com.example.MainClass
另一个在初学者教程中最常见但通常没有被专业人士使用的替代方法是定义一个%CLASSPATH%
环境变量,其中你准确地将那个值放在你想要在{{1}中使用的值中参数。然后-cp
命令会查找它(只要你不使用java
,-cp
或-classpath
参数之一。< / p>
如果输入long命令变得无聊,您可以使用批处理文件或shell文件,以便您可以轻松管理它。
例如,如果您有一个JAR文件或另一个包含您希望在程序中使用的类的根包文件夹,则需要将它们附加到类路径中。在Windows上,分隔符是分号-jar
,而在Linux上,分隔符是;
。此外,当路径包含空格时,您需要引用特定路径。这是一个Windows示例:
:
希望这有帮助。