如何修复 NoSuchMethodError?

233

在运行我的Java程序时,我遇到了一个NoSuchMethodError错误。出了什么问题?如何解决?


13
在Netbeans中:在“项目”选项卡中右键单击项目,选择“清理和构建”。这对我解决了问题。 - Heinzlmaen
6
在Intellij Idea中,有时重新构建可以解决问题。 - Hawk
3
这篇文章对于这个问题非常有帮助 https://reflectoring.io/nosuchmethod/ - Michael Smith
https://reflectoring.io/nosuchmethod/ https://www.baeldung.com/java-nosuchmethod-error https://www.javatpoint.com/java-lang-nosuchmethoderror https://www.geeksforgeeks.org/how-to-solve-java-lang-nosuchmethoderror-in-java/ https://dev59.com/pvTtpIgB1922wOYJd-Ee https://dev59.com/mNT7oIgBc1ULPQZF8Ipc - Dmytro Mitin
34个回答

280

没有更多的信息,很难确定问题的根本原因,但最可能的原因是您对一个缺少方法的类的不同版本进行了编译,与在运行时使用的版本不同。

查看堆栈跟踪...如果在调用库中对象的方法时出现异常,则在编译和运行时可能使用了不同的库版本。确保两个地方都使用正确的版本。

如果在调用由您创建的类实例化的对象的方法时出现异常,则您的构建过程似乎存在问题。请确保您实际运行的类文件在编译时已更新。


4
最近我们发现了其中一个问题的原因,原来是构建过程在 Java 服务器关闭之前就放置了类文件,由于 Java 服务器没有加载某些类,所以我们遇到了这个问题。之后虽然 Java 服务器加载了一些类,但又有了新的类,并且新的代码引用了旧类中不存在的方法......结果就出现了 NoSuchMethodError 错误。 - vazor
1
看栈追踪(stack trace)……我几乎总是去检查栈追踪中的最后一个“Caused by”部分,以找到罪魁祸首的类/包。 - KrishPrabakar
@Vetle,这是否意味着在Java中导入的类是动态加载的,而不像C中那样静态加载? - Sourav Kannantha B

113
我也遇到了你的问题,以下是我解决它的方法。这些步骤可以有效地添加一个库。前两步我已经完成,但是我没有执行最后一步,也就是将".jar"文件从文件系统中直接拖入我的Eclipse项目的"lib"文件夹中。此外,我还需要从构建路径和"lib"文件夹中删除之前版本的库。

步骤1 - 将.jar文件添加到构建路径

输入图像说明

步骤2 - 关联来源和javadoc(可选)

输入图像说明

步骤3 - 将.jar文件实际拖入"lib"文件夹中(不可选)

输入图像说明


82
+1 表示「赞同」,意思是「大家都期望你知道如何使用它,如果不知道,他们就会在问题下投票反对。」 - Vikram

84

需要注意的是,在反射的情况下,你会得到一个NoSuchMethodException异常,而在非反射代码中,你会得到NoSuchMethodError错误。当面临其中一种情况时,我倾向于在非常不同的地方进行查找。


3
换句话说,你的意思是,如果你使用反射在一个类上获取一个方法,但该方法不存在,那么就会抛出一个NoSuchMethodException异常。但是,如果你在编译代码时使用了某些库,在服务器上你有其他的库(也许是更新的库或较旧的库),那么就会抛出一个NoSuchMethodError异常。如果我理解错误请纠正我。 - Victor

69

如果您可以更改JVM参数,则添加详细输出应允许您查看从哪些JAR文件加载哪些类。

java -verbose:class <other args>

当你的程序运行时,JVM 应该向标准输出中转储信息,例如:

 

...

    

[从文件:/C:/Program%20Files/junit3.8.2/junit.jar加载了junit.framework.Assert]

    

...


4
+1 太棒了!我用这种方法解决了一个麻烦的小问题,谢谢。这是一个很好的方式,可以发现某些类以某种方式悄悄地出现在类路径上。 - Duncan Jones
1
我认为其他答案都不合理...这就是你找出错误依赖项加载位置的方法,这正是问题的本质...救了我的(第二)天 :) - nenea
@matt 这是否意味着,在Java中导入的类是动态加载的,而在C中是静态加载的? - Sourav Kannantha B

21

如果您使用Maven或另一个框架,并且几乎随机地遇到此错误,请尝试像这样进行清理安装...

clean install

如果您编写了对象并且知道它有该方法,则特别可能会起作用。


1
Gradle构建也是如此。 - Jonathan E. Landrum

16

通常,这是由于使用类似于Apache Ant的构建系统时发生的,该系统仅在Java文件比类文件新时编译Java文件。 如果方法签名更改且类正在使用旧版本,则可能无法正确编译。 通常的解决方法是进行完整的重建(通常为“ant clean”然后“ant”)。

有时,这也可能是编译针对一个库的一个版本,但运行另一个版本而导致的问题。


2
实际上,这更像是Java程序员在使用任何Java开发框架(如Maven、NetBeans和Apache Ant)时遇到的问题,正如您从这里所有的答案中所看到的。 - HoldOffHunger

9

我遇到了相同的错误:

  Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.core.JsonGenerator.writeStartObject(Ljava/lang/Object;)V
        at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:151)
        at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
        at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3681)
        at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3057)

为了解决这个问题,我首先检查了 模块依赖图在POM中单击组合键-> Ctrl+Alt+Shift+U右键单击POM -> Maven -> 显示依赖项),以了解库之间的冲突发生在哪里(Intelij IDEA)。在我的情况下,我有不同版本的Jackson依赖关系。

enter image description here enter image description here

1) 所以,我直接在项目的POM文件中明确添加了这两个版本中最高的版本-2.8.7。

在属性中:

<jackson.version>2.8.7</jackson.version>

作为依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>

2) 但也可以使用依赖排除来解决。

与下面的示例原理相同:

  <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-a</artifactId>
      <version>1.0</version>
          <exclusions>
             <exclusion>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
             </exclusion>
         </exclusions>
  </dependency>

如果依赖项版本不符合要求,将从您的项目中排除该依赖项。


6
为什么没有人提到依赖冲突?这个常见的问题可能与包含不同版本的依赖JAR文件有关。 详细的解释和解决方案:https://dzone.com/articles/solving-dependency-conflicts-in-maven 简短回答:
添加这个Maven依赖;
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
    <rules>
        <dependencyConvergence />
    </rules>
</configuration>
</plugin>


然后运行此命令;
mvn enforcer:enforce

也许这就是你面临问题的原因。

啊!这真的帮了我,原来我一直看错方向了。谢谢你,伙计!!! - Girish Nair

5

如果你正在编写一个Web应用程序,请确保你的容器全局库目录和应用程序中没有冲突的jar版本。你可能不知道类加载器正在使用哪个jar。

例如:

  • tomcat/common/lib
  • mywebapp/WEB-INF/lib

5

我遇到这个问题是因为我在函数中将参数类型从Object a更改为String a。我可以通过重新清理和构建来解决它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接