【问题标题】:What's causing NoSuchMethodError and NoClassDefFoundError?是什么导致了 NoSuchMethodError 和 NoClassDefFoundError?
【发布时间】:2012-02-09 07:50:57
【问题描述】:

当我运行 test.class 时,我收到以下错误:

Exception in thread "main" java.lang.NoSuchMethodError: ml.Temp.<init>(Ljava/lang/String;II)V
    at test.main(test.java:11)

这里是 test.java 的代码

import java.io.*;
import ml.*;

class test
{
        public static void main(String[] args) throws FileNotFoundException, IOException
        {
                String filename = "input";

                Temp id = new Temp(filename, 6, 100);
                    id.someFunction();          
         }
}

基本上我有一个包含 Temp.class 的 jar 文件(Temp 是我编写的一个库文件,位于 ml 包下)。 Temp 有一个构造函数,它接受这三个参数和一个公共的 someFunction。

不确定这是否有帮助,但我在编译期间包含了 jar 文件的类路径。当我在 test.class 运行期间包含 jar 文件的类路径时,我得到以下内容

Exception in thread "main" java.lang.NoClassDefFoundError: test
Caused by: java.lang.ClassNotFoundException: test
    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:321)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: test. Program will exit.

编辑:

如果有帮助我编译如下(ml.jar和test.java在同一目录下)

javac -cp ml.jar test.java

【问题讨论】:

  • 你是如何构建/运行这个的?
  • 如果出现第一个错误,我只是做了一个java测试。如果我进行 java -cp "ml.jar" 测试,我会收到第二个错误

标签: java classpath noclassdeffounderror nosuchmethoderror


【解决方案1】:

如果没有源代码,很难准确地告诉您发生了什么,但看起来您的库和使用它的项目不同步。您是否更改了库/项目中任何方法的签名?我建议重新编译所有内容,然后检查类 test 是否使用您重新编译的库的最新版本以及它是否声明了 public

有关如何阅读 NoSuchMethodError 等的更多有用信息可以在此处的一篇精彩文章中找到:http://www.cubrid.org/blog/dev-platform/understanding-jvm-internals/

【讨论】:

    【解决方案2】:

    您应该从test.class 所在的路径运行命令java -cp &lt;path-to-ml.jar&gt; test

    编辑

    NoSuchMethodError 表示在 test 类的第 11 行中,您正在尝试使用 ml.ID3(不是 Temp!)的构造函数和不存在的签名 (String, int, int)。这并不意味着它不在类路径中,因为这会导致NoClassDefFoundError

    另一方面,NoClassDefFoundError: test 意味着 test 不再在您的 clsspath 中。将 jar 添加到类路径中,如果您确实为获得 NoClassDefFoundError: test 所做的一切,无法导致 test 从您的类路径中消失......所以您更有可能已经做了一些其他无意的动作。

    编辑 2

    也许该构造函数存在于您的开发环境中使用的ID3 中,但它显然不存在于您的运行时环境中。如果它是第 3 方 jat,可能会发生您有该 jar 的两个版本,一个在开发中使用,另一个在运行时使用。或者甚至可能两者都出现在您的运行时环境中,但缺少构造工具优先级。

    【讨论】:

    • 是的,我确实从 test.class 所在的位置运行它。或者你是说 Temp.class 吗?
    • 没有。 Temp.class 应该在 path-to-ml.jar 引用的 jar 中。
    • 是的,在这种情况下 - 我确实从与 test.class 相同的路径运行它
    • 我编辑了我的答案以添加可能会引导您进行进一步调查的解释。
    • 好吧 ID3 与 Temp 相同(我通常在将代码发布到论坛之前更改类名 - 但没有在错误中删除它)。 ID3 确实有一个具有相同签名的构造函数(这就是我感到困惑的原因)。
    【解决方案3】:

    我要伪装成你,走完整个流程:

    1 - 图书馆。我在一个名为workspace 的目录中。在其中,我创建了一个名为ml 的目录。
    ml 目录中,我创建了一个名为Temp.java 的新文件,其中包含以下内容:

    package ml;
    
    public class Temp
    {
        public Temp(String filename, int arg1, int arg2)
        {
            //do something
        }
    
        public void someFunction()
        {
            //do something else
            System.out.println("look left!");
        }
    }
    

    我现在要编译库类并创建一个库 jar。 首先我通过运行编译

    javac ./Temp.java
    

    ml 目录中。然后,我通过将一个目录向上移动到 workspace 目录并运行来 jar 库:

    jar cf ml.jar ml/
    

    2 - 程序。我现在在workspace 目录中创建Test.java 文件。该文件包含以下内容:

    import java.io.*;
    import ml.*;
    
    public class Test
    {
        public static void main(String[] args) throws FileNotFoundException, IOException
        {
            String filename = "input";
    
            Temp id = new Temp(filename, 6, 100);
            id.someFunction();
        }
    }
    

    3 - 结果。我现在继续编译并运行我的测试程序。在我运行的workspace 目录中:

    javac -cp ./:ml.jar ./Test.java
    

    我终于可以通过在workspace 目录中运行以下命令来运行程序了:

    java -cp ./:ml.jar Test
    

    这将显示输出:

    look left!
    

    我希望这会有所帮助。

    【讨论】: