如何修复NoSuchMethodError?

问题描述 投票:150回答:28

我在运行Java程序时遇到NoSuchMethodError错误。怎么了,怎么解决?

java nosuchmethoderror
28个回答
209
投票

没有任何更多的信息,很难确定问题,但根本原因是你很可能已经编译了一个类,该类针对的是缺少方法的类的不同版本,而不是运行它时使用的类。

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

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


2
投票

这意味着类中没有相应的方法:

  1. 如果您正在使用jar然后反编译并检查相应版本的jar是否具有适当的类。
  2. 检查您是否从源代码编译了正确的类。

2
投票

对我来说,这是因为我在函数中更改了参数类型,从Object a到String a。我可以用干净解决它并再次构建


2
投票

我刚刚通过重新启动Eclipse并运行applcation解决了这个错误。我的理由可能是因为我在不关闭项目或Eclipse的情况下替换了我的源文件。这导致我使用的不同版本的类。


2
投票

试试这种方法:删除项目目录下的所有.class文件(当然还有所有子目录)。重建。

有时mvn clean(如果你使用的是maven)不会清理由javac手动创建的.class文件。那些旧文件包含旧签名,导致NoSuchMethodError


2
投票

只需添加现有答案。我在eclipse中遇到了tomcat这个问题。我改变了一个班级并做了以下步骤,

  1. 在eclipse中清理并构建了项目
  2. mvn clean install
  3. 重启tomcat

我仍面临同样的错误。然后我清理了tomcat,清理了tomcat工作目录并重新启动了服务器,我的问题就消失了。希望这有助于某人


1
投票

回答原始问题。根据java docs here

“NoSuchMethodError”如果应用程序试图调用类的指定方法(静态或实例),并且该类不再具有该方法的定义,则抛出该异常。

通常,编译器会捕获此错误;如果类的定义发生了不兼容的更改,则此错误只能在运行时发生。

  1. 如果它在运行时发生,请检查包含该方法的类是否在类路径中。
  2. 检查是否添加了新版本的JAR,并且该方法是兼容的。

1
投票

我通过重命名Junit测试文件在Eclipse中解决了这个问题。 在我的Eclipse工作空间中,我有一个App项目和一个Test项目。 Test项目将App项目作为构建路径上的必需项目。

开始得到NoSuchMethodError。 然后我意识到Test项目中的类与App项目中的类名相同。

App/  
  src/
     com.example/  
       Projection.java
Test/  
  src/
     com.example/
       Projection.java

将Test重命名为正确的名称“ProjectionTest.java”后,异常就消失了。


0
投票

我在应用程序中更改方法签名时遇到了类似的问题。清理和重建我的项目解决了“NoSuchMethodError”。


0
投票

上面的答案解释得很好..只是添加一件事如果你使用eclipse使用ctrl + shift + T并输入类的包结构(例如:gateway.smpp.PDUEventListener),你会发现它存在的所有jar /项目。从类路径中删除不必要的jar或在类路径中添加上面的jar。现在它会选择正确的。


0
投票

我遇到了类似的问题。

Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I

最后我发现根本原因是改变了变量的数据类型。

  1. Employee.java - >包含变量(EmpId),其数据类型已从int更改为String
  2. ReportGeneration.java - >使用getter,getEmpId()检索值。

我们应该通过仅包含修改的类来重新绑定jar。由于ReportGeneration.java没有变化,我只在jar文件中包含了Employee.class。我必须在jar中包含ReportGeneration.class文件来解决问题。


107
投票

我遇到了你的问题,这就是我修复它的方法。以下步骤是添加库的工作方式。我已经完成了前两个步骤,但我没有完成最后一个步骤,将“.jar”文件直接从文件系统拖到我的eclipse项目的“lib”文件夹中。此外,我不得不从构建路径和“lib”文件夹中删除以前版本的库。

第1步 - 添加.jar来构建路径

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

第3步 - 实际将.jar文件拖到“lib”文件夹中(不是可选的)


0
投票

我遇到了同样的问题。当类中存在歧义时也会导致这种情况。我的程序试图调用一个方法,该方法存在于同一位置/类路径中的两个JAR文件中。删除一个JAR文件或执行代码,以便只使用一个JAR文件。检查您是否使用相同的JAR或包含相同类的相同JAR的不同版本。

DISP_E_EXCEPTION [step] [] [Z-JAVA-105 Java异常java.lang.NoSuchMethodError(com.example.yourmethod)]


0
投票

大多数情况下,java.lang.NoSuchMethodError被捕获为编译器,但有时它可能在运行时发生。如果在运行时发生此错误,那么唯一的原因可能是类结构的更改使其不兼容。

最佳说明:https://www.journaldev.com/14538/java-lang-nosuchmethoderror


0
投票

我也遇到过这个错误。

我的问题是我改变了一个方法的签名,比如说

void invest(Currency money){...}

void invest(Euro money){...}

从类似于的上下文调用此方法

public static void main(String args[]) {
    Bank myBank = new Bank();

    Euro capital = new Euro();
    myBank.invest(capital);
}

由于资本既是货币也是欧元,编制者对警告/错误保持沉默。

问题的出现是因为我只编译了定义方法的类--Bank,而不是从中调用方法的类,它包含main()方法。

这个问题不是您可能经常遇到的问题,因为最常见的是项目是手动重建或自动触发构建操作,而不是仅编译一个修改过的类。

我的用例是我生成了一个.jar文件,该文件将用作修补程序,它不包含App.class,因为它没有被修改。我有意义的是不要包含它,因为我保留了初始参数的基类通过继承。

问题是,当你编译一个类时,生成的字节码是静态的,换句话说,它是一个硬引用。

原始的反汇编字节码(使用javap工具生成)如下所示:

 #7 = Methodref          #2.#22         // Bank.invest:(LCurrency;)V

在ClassLoader加载新编译的Bank.class之后,它将找不到这样的方法,它看起来好像已被删除而未被更改,因此命名错误。

希望这可以帮助。


0
投票

我的问题是在构建路径中有两个版本的同一个库。旧版本的库没有这个功能,而新版本的功能也没有。


0
投票

使用Intellij我的Gradle项目遇到了类似的问题。我通过删除.gradle(见下面的截图)包和重建项目来解决它。 qazxsw poi


0
投票

NoSuchMethodError:我花了几个小时修复这个问题,最后修改它只是重命名包名,清理和构建...如果它不起作用尝试干净构建尝试重命名类名或包名称和清理构建.. .it应该是固定的。祝好运。


0
投票

我有同样的错误:

.gradle Package

为了解决这个问题,我首先检查了 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) Module Dependency Diagramclick in your POM the combination -> Ctrl+Alt+Shift+U),以了解图书馆之间的冲突究竟在哪里(Intelij IDEA)。在我的特殊情况下,我有不同版本的Jackson依赖项。

right click in your POM -> Maven -> Show dependencies enter image description here

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

在属性中:

enter image description here

作为依赖:

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

2)但它也可以使用<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> 解决。

通过与以下示例相同的原理:

Dependency Exclusions

不需要的版本的依赖项将从您的项目中排除。


0
投票

在我的情况下,我有一个多模块项目和场景就像 <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> 在模块com.xyz.TestClass和模块A和模块B依赖于模块A。因此,在创建程序集jar时,我认为只有一个版本的类被保留,如果没有调用的方法然后我得到B运行时异常,但编译很好。

相关:NoSuchMethodError


-2
投票

如果您的文件名与包含m​​ain方法的类名不同,则可能是此错误可能导致的。


67
投票

请注意,在反射的情况下,你得到一个NoSuchMethodException,而使用非反射代码,你得到NoSuchMethodError。当面对一个与另一个相比时,我倾向于在非常不同的地方寻找。


44
投票

如果您有权更改JVM参数,则添加详细输出应该允许您查看从哪些JAR加载的类。

java -verbose:class <other args>

运行程序时,JVM应转储到标准输出信息,例如:

...

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

...


11
投票

这通常是在使用像Apache Ant这样的构建系统时导致的,当java文件比类文件更新时,它只编译java文件。如果方法签名发生更改且类使用旧版本,则可能无法正确编译。通常的解决方法是进行完全重建(通常是“ant clean”然后是“ant”)。

有时,在针对一个版本的库进行编译但针对不同版本运行时也会导致这种情况。


5
投票

如果使用Maven或其他框架,并且几乎随机地得到此错误,请尝试干净安装,如...

clean install

如果您编写了对象并且您知道它具有该方法,则此功能尤其有用。为我工作。


4
投票

这也可能是使用反射的结果。如果您有代码反映在类上并按名称提取方法(例如:使用Class.getDeclaredMethod("someMethodName", .....)),那么在方法名称发生更改时,例如在重构期间,您需要记住将参数更新为反射方法以匹配新方法签名,或getDeclaredMethod调用将抛出NoSuchMethodException

如果这是原因,那么堆栈跟踪应该显示调用反射方法的点,并且您只需要更新参数以匹配实际的方法签名。

根据我的经验,当单元测试私有方法/字段并使用TestUtilities类提取字段以进行测试验证时,偶尔会出现这种情况。 (通常使用未考虑单元测试而设计的遗留代码。)


3
投票

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

EG

  • 的Tomcat /普通/ lib中
  • mywebapp / WEB-INF / lib

2
投票

这些问题是由在同一两个类中使用相同对象引起的。使用的对象不包含新对象类所包含的新方法。

例如:

filenotnull=/DayMoreConfig.conf
16-07-2015 05:02:10:ussdgw-1: Open TCP/IP connection to SMSC: 10.149.96.66 at 2775
16-07-2015 05:02:10:ussdgw-1: Bind request: (bindreq: (pdu: 0 9 0 [1]) 900 900 GEN 52 (addrrang: 0 0 2000) ) 
Exception in thread "main" java.lang.NoSuchMethodError: gateway.smpp.PDUEventListener.<init>(Lgateway/smpp/USSDClient;)V
        at gateway.smpp.USSDClient.bind(USSDClient.java:139)
        at gateway.USSDGW.initSmppConnection(USSDGW.java:274)
        at gateway.USSDGW.<init>(USSDGW.java:184)
        at com.vinaphone.app.ttn.USSDDayMore.main(USSDDayMore.java:40)

-bash-3.00$ 

这些问题是由伴随的02类似类引起的(src中为1,jar文件中的1为gateway.jar)

© www.soinside.com 2019 - 2024. All rights reserved.