如何修复NoSuchMethodError?

时间:2008-08-29 20:04:28

标签: java nosuchmethoderror

运行Java程序时出现NoSuchMethodError错误。有什么问题,我该如何解决?

31 个答案:

答案 0 :(得分:202)

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

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

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

答案 1 :(得分:107)

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

步骤1 - 添加.jar以构建路径

enter image description here

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

enter image description here

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

enter image description here

答案 2 :(得分:65)

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

答案 3 :(得分:44)

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

java -verbose:class <other args>

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

  

...

     

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

     

...

答案 4 :(得分:11)

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

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

答案 5 :(得分:5)

如果使用maven或其他框架,并且几乎随机地得到此错误,请尝试“clean install”,特别是如果您编写了该对象,并且您知道它具有该方法。为我工作。

答案 6 :(得分:4)

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

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

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

答案 7 :(得分:3)

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

e.g。

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

答案 8 :(得分:2)

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

答案 9 :(得分:2)

只需添加到现有答案即可。我在Eclipse中遇到了tomcat的问题。我改变了一堂课,并按照以下步骤进行操作,

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

  2. mvn全新安装

  3. 重新启动tomcat

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

答案 10 :(得分:2)

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

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

答案 11 :(得分:2)

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

答案 12 :(得分:2)

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

  1. 如果你正在使用jar,那么反编译并检查相应版本的jar是否具有适当的类。
  2. 检查您是否从您的来源编辑了正确的课程。

答案 13 :(得分: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)

答案 14 :(得分:1)

我遇到了同样的问题。我更改了一种方法的返回类型并运行了该类的测试代码。那是我面对这个NoSuchMethodError的时候。作为解决方案,我在整个存储库上运行了一次 Maven 构建,然后再次运行测试代码。问题在下一次测试运行中得到解决。

答案 15 :(得分: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”后,异常就消失了。

答案 16 :(得分:0)

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

答案 17 :(得分:0)

为什么没有人提到依赖冲突?此常见问题可能与包含不同版本的依赖项 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

也许这就是您遇到问题的原因。

答案 18 :(得分:0)

在我的情况下,我有一个多模块项目,场景就像com.xyz.TestClass在模块A以及模块B中一样,模块A依赖于模块B。因此,在创建程序集jar时,我认为如果没有调用的方法,只保留了一个版本的类,那么我遇到了NoSuchMethodError运行时异常,但是编译很好。

相关:https://reflectoring.io/nosuchmethod/

答案 19 :(得分:0)

我有同样的错误:

  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+Uright 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 Exclusions来解决。

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

  <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>

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

答案 20 :(得分:0)

NoSuchMethodError:我花了几个小时解决了这个问题,最后通过重命名包名称,清理并构建来解决了它……如果不起作用,请先尝试清理构建,然后重命名类名或包名并清理建立...应该修复。祝你好运。

答案 21 :(得分:0)

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

答案 22 :(得分:0)

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

  

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

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

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

答案 23 :(得分:0)

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

  

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

答案 24 :(得分: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,因为它未被修改。我有意义的是不要包含它,因为我保留了初始论证的基类继承。

问题是,当你编译一个类时,生成的字节码有点像 static ,换句话说,它是硬引用

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

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

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

希望这有帮助。

答案 25 :(得分:0)

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

答案 26 :(得分:0)

  

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

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

答案 27 :(得分:0)

我遇到了类似的问题。

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

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

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

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

答案 28 :(得分:0)

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

答案 29 :(得分:-1)

发生此错误的一个这样的实例: 我碰巧犯了一个愚蠢的错误,即以非静态方法访问私有静态成员变量。将方法更改为静态可以解决问题。

答案 30 :(得分:-2)

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