如何解决NoSuchMethodError?
运行我的Java程序时出现NoSuchMethodError
错误。 怎么了,我该如何解决?
如果没有更多的信息,就很难指出问题的根源,但根本原因在于,您最有可能针对缺less方法的类的不同版本编译了一个类,而不是运行它时使用的类。
查看堆栈跟踪…如果在调用库中某个对象的方法时出现exception,那么在编译和运行时很可能使用了不同版本的库。 确保你有正确的版本两个地方。
如果在你所做的类实例化的对象上调用方法时出现exception,那么你的构build过程似乎是错误的。 确保在编译时更新实际运行的类文件。
我感受到你的痛苦。 你可以从一本书中学习编程,但是在使用Eclipse或者Visual Studio的时候,它会做一些简单的事情,比如添加一个库。 每个人都希望你知道如何使用它,如果你不这样做,他们downvote你的问题。 问题是,如果你不在办公室工作,或者不了解任何人可以提出这些问题,那么几乎不可能把这些东西搞清楚。 无论如何…
我有你的问题,这是我如何解决它。 以下步骤是添加库的一种工作方式。 我已经完成了前两个步骤,但是我没有通过直接从文件系统拖动“.jar”文件到我的eclipse项目中的“lib”文件夹来完成最后一步。 此外,我不得不从构buildpath和“lib”文件夹中删除以前版本的库。
如果有人知道更合适的方式添加/更新图书馆,请join。
第1步 – 添加.jar来构buildpath
第2步 – 关联源和javadocs(可选)
第3步 – 实际上拖动.jar文件到“lib”文件夹(不可选)
请注意,在reflection的情况下,您会得到NoSuchMethodException
,而使用非reflection代码时,会得到NoSuchMethodError
。 当面对一个对另一个时,我倾向于在非常不同的地方看。
如果您有权更改JVM参数,则添加详细输出应该允许您查看哪些类正在从哪些JAR中加载。
java -verbose:class <other args>
当程序运行时,JVM应该转储到标准输出信息,如:
…
[加载junit.framework.Assert从文件:/ C:/Program%20Files/junit3.8.2/junit.jar]
…
这通常是因为使用像Apache Ant这样的构build系统,当java文件比类文件更新时才编译java文件。 如果方法签名发生更改,并且类使用旧版本,则可能无法正确编译。 通常的解决办法是做一个完整的重build(通常是“ant清理”,然后“ant”)。
有时候,这也可能导致对一个版本的库进行编译,而针对不同的版本运行。
这也可以是使用reflection的结果。 如果你的代码反映了一个类,并提取一个名字的方法(例如:用Class.getDeclaredMethod("someMethodName", .....)
),那么任何时候该方法名称的变化,如在重构期间,你会需要记住将参数更新为reflection方法以匹配新的方法签名,否则getDeclaredMethod
调用将抛出NoSuchMethodException
。
如果这是原因,那么堆栈跟踪应该显示reflection方法被调用的点,并且您只需要更新参数以匹配实际的方法签名。
根据我的经验,当unit testing私有方法/字段,并使用TestUtilities
类来提取testingvalidation字段时,偶尔会出现这种情况。 (一般来说,遗留代码不是用unit testingdevise的。)
如果使用maven或其他框架,并且几乎是随机得到这个错误,请尝试“干净安装”,特别是如果您编写了对象并且知道它具有该方法。 为我工作。
如果您正在编写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)
这意味着各自的方法不在课堂上:
- 如果你正在使用jar然后反编译,并检查各个版本的jar是否有适当的类。
- 检查你是否从你的源码编译了适当的类。
对我来说,这是因为我改变了函数的参数types,从Object a到String a。 我可以用干净的方法来解决它,然后重新构build
当我在应用程序中更改方法签名时遇到了类似的问题。 清理和重build我的项目解决了“NoSuchMethodError”。
上面的答案解释得非常好..只是添加一件事情如果您使用的是使用eclipse使用ctrl + shift + T并input类的包结构(例如:gateway.smpp.PDUEventListener),你会发现它存在的所有jar子/项目。 从类path中删除不必要的jar或在类path中添加上面的。 现在它会select正确的一个。
我刚刚解决了这个错误,重新启动我的Eclipse并运行应用程序。 我的情况的原因可能是因为我replace我的源文件而不closures我的项目或Eclipse。 这导致了我使用的不同版本的类。
我遇到了类似的问题。
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
最后我确定了根本原因是改变variables的数据types。
-
Employee.java
– >包含其数据types已从int
更改为String
的variables(EmpId
)。 -
ReportGeneration.java
– >使用gettergetEmpId()
检索值。
我们应该通过只包含修改后的类来重新装满jar。 由于ReportGeneration.java
中没有改变,我只在Jar文件中包含了Employee.class
。 我不得不在jar中包含ReportGeneration.class
文件来解决这个问题。
我有同样的问题。 这也是在课堂上存在歧义时造成的。 我的程序试图调用存在于相同位置/类path中的两个JAR文件中的方法。 删除一个JAR文件或执行您的代码,以便只使用一个JAR文件。 检查您是不是使用相同的JAR或包含相同类的相同JAR的不同版本。
DISP_E_EXCEPTION [步] [] [Z-JAVA-105 Javaexceptionjava.lang.NoSuchMethodError(com.example.yourmethod)]
回答原来的问题。 根据java文档在这里 :
“NoSuchMethodError”如果应用程序尝试调用某个类的指定方法(静态或实例),并且该类不再具有该方法的定义,则抛出该exception。
通常,这个错误是由编译器捕获的; 这个错误只能在运行时发生,如果一个类的定义不兼容改变。
- 如果在运行时发生,请检查包含该方法的类是否在类path中。
- 检查是否添加了新版本的JAR,并且该方法是兼容的。
如果你的文件名不同于包含main方法的类名,那么这个错误可能是可能的。