我得到了一个 NoSuchMethodError 运行我的 Java 程序时出错。出了什么问题以及如何修复它?

有帮助吗?

解决方案

如果没有更多信息,很难查明问题,但根本原因是您很可能针对缺少方法的类的不同版本编译了一个类,而不是运行该类时使用的版本。

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

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

其他提示

我遇到了你的问题,这就是我解决它的方法。以下步骤是添加库的有效方法。我已经正确完成了前两个步骤,但我没有通过将“.jar”文件直接从文件系统拖到我的 eclipse 项目上的“lib”文件夹中来完成最后一个步骤。此外,我必须从构建路径和“lib”文件夹中删除以前版本的库。

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

enter image description here

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

enter image description here

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

enter image description here

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

如果您有权更改 JVM 参数,那么添加详细输出应该可以让您看到正在从哪些 JAR 加载哪些类。

java -verbose:class <other args>

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

...

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

...

这通常是在使用像这样的构建系统时引起的 阿帕奇蚂蚁 仅当 java 文件比类文件新时才编译 java 文件。如果方法签名发生更改并且类使用旧版本,则可能无法正确编译。通常的修复方法是进行完全重建(通常是“ant clean”,然后是“ant”)。

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

如果使用 梅文 或其他框架,并且您几乎随机收到此错误,请尝试全新安装,例如...

clean install

如果您编写了该对象并且知道它具有该方法,那么这尤其可能有效。为我工作。

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

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

根据我的经验,在对私有方法/字段进行单元测试并使用 TestUtilities 类来提取字段以进行测试验证。(通常使用未考虑单元测试的遗留代码。)

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

例如

  • tomcat/常见/lib
  • mywebapp/WEB-INF/lib

这些问题是由于在相同的两个类中使用相同的对象而引起的。使用的对象不包含已添加的新对象类包含的新方法。

前任:

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)

这意味着类中不存在相应的方法:

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

对我来说,发生这种情况是因为我将函数中的参数类型从对象 a 更改为字符串 a。我可以用 clean 来解决它并再次构建

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

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

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

只是添加到现有的答案。我在 eclipse 中使用 tomcat 时遇到了这个问题。我改变了一个班级并执行了以下步骤,

  1. 在 eclpise 中清理并构建了项目

  2. mvn 干净安装

  3. 重启tomcat

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

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

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

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

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

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

上面的答案很好地解释了..如果使用Eclipse使用ctrl+shift+t,请添加一件事,然后输入类的软件包结构(例如:gateway.smpp.PDUEventListener ),您将找到它所在的所有 jars/项目。从类路径中删除不必要的 jar 或在类路径中添加上述内容。现在它会选择正确的一个。

我遇到了类似的问题。

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

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

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

我们应该通过仅包含修改后的类来重新捆绑 jar。由于没有发生任何变化 ReportGeneration.java 我只包括 Employee.class 在 Jar 文件中。我必须包括 ReportGeneration.class jar 中的文件来解决问题。

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

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

来回答原来的问题。根据java文档 这里:

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

通常,这个错误会被编译器捕获;仅当类的定义发生不兼容的更改时,此错误才会在运行时发生。

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

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

最佳解释: https://www.journaldev.com/14538/java-lang-nosuchmethoderror

我也遇到过这个错误。

我的问题是我更改了方法的签名,例如

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后,将找不到这样的方法,看起来好像它被删除并且没有改变,因此出现命名错误。

希望这可以帮助。

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

我使用 Intelij 的 Gradle 项目也遇到了类似的问题。我通过删除 .gradle (参见下面的屏幕截图)包并重建项目来解决它。.gradle 包

没有这样的方法错误:我花了几个小时解决这个问题,最后通过重命名包名称、清理和构建来解决它......如果不起作用,请先尝试干净构建,然后尝试重命名类名称或包名称,然后进行干净构建...应该可以修复。祝你好运。

我有同样的错误:

  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)

为了解决这个问题,我首先检查了, 模块依赖图 (click in your POM the combination -> Ctrl+Alt+Shift+U 或者 right click in your POM -> Maven -> Show dependencies)来了解库之间的冲突到底在哪里(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>

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top