Without any more information it is difficult to pinpoint the problem, but the root cause is that you most likely have compiled a class against a different version of the class that is missing a method, than the one you are using when running it.
在没有更多信息的情况下,很难准确定位问题,但根本原因是您很可能针对缺少方法的类的不同版本编译了一个类,而不是运行它时使用的版本。
Look at the stack trace ... If the exception appears when calling a method on an object in a library, you are most likely using separate versions of the library when compiling and running. Make sure you have the right version both places.
看看堆栈跟踪..。如果在对库中的对象调用方法时出现异常,则很可能是在编译和运行时使用库的不同版本。确保您在两个地方都有正确的版本。
If the exception appears when calling a method on objects instantiated by classes you made, then your build process seems to be faulty. Make sure the class files that you are actually running are updated when you compile.
如果异常出现在调用由你创建的类实例化的对象的方法时,那么你的构建过程似乎是错误的。确保在编译时更新了实际运行的类文件。
I was having your problem, and this is how I fixed it. The following steps are a working way to add a library. I had done the first two steps right, but I hadn't done the last one by dragging the ".jar" file direct from the file system into the "lib" folder on my eclipse project. Additionally, I had to remove the previous version of the library from both the build path and the "lib" folder.
我遇到了你的问题,这就是我解决它的方法。以下步骤是添加库的有效方法。我已经正确地完成了前两步,但没有完成最后一步,将“.jar”文件直接从文件系统拖到我的eclipse项目的“lib”文件夹中。此外,我必须从构建路径和“lib”文件夹中删除该库的以前版本。
Step 1 - Add .jar to build path
Step 2 - Associate sources and javadocs (optional)
Step 3 - Actually drag .jar file into "lib" folder (not optional)
Note that in the case of reflection, you get an NoSuchMethodException
, while with non-reflective code, you get NoSuchMethodError
. I tend to go looking in very different places when confronted with one versus the other.
请注意,在反射的情况下,您将获得NoSuchMethodException,而对于非反射代码,您将获得NoSuchMethodError。当我面对其中一个和另一个时,我倾向于从非常不同的地方去寻找。
If you have access to change the JVM parameters, adding verbose output should allow you to see what classes are being loaded from which JAR files.
如果您有权更改JVM参数,那么添加详细输出应该可以让您看到从哪个JVM文件加载了哪些类。
java -verbose:class <other args>
When your program is run, the JVM should dump to standard out information such as:
当您的程序运行时,JVM应该转储到标准输出信息,例如:
...
[Loaded junit.framework.Assert from file:/C:/Program%20Files/junit3.8.2/junit.jar]
...
If using Maven or another framework, and you get this error almost randomly, try a clean install like...
如果使用Maven或其他框架,并且几乎是随机得到此错误,请尝试全新安装,如下所示:
clean install
This is especially likely to work if you wrote the object and you know it has the method.
如果您编写了对象并且知道它有方法,这尤其可能会起作用。
This is usually caused when using a build system like Apache Ant that only compiles java files when the java file is newer than the class file. If a method signature changes and classes were using the old version things may not be compiled correctly. The usual fix is to do a full rebuild (usually "ant clean" then "ant").
这通常是在使用像ApacheAnt这样的构建系统时造成的,该构建系统只在Java文件比类文件新的时候编译Java文件。如果方法签名发生更改,而类使用的是旧版本,则可能无法正确编译。通常的解决方法是进行完全重建(通常先进行“清理”,然后进行“清理”)。
Sometimes this can also be caused when compiling against one version of a library but running against a different version.
有时,当针对某个库的一个版本进行编译,但在另一个版本上运行时,也会导致这种情况。
I had the same error:
我也犯了同样的错误:
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)
To solve it I checked, firstly, Module Dependency Diagram (click in your POM the combination -> Ctrl+Alt+Shift+U
or right click in your POM -> Maven -> Show dependencies
) to understand where exactly was the conflict between libraries (Intelij IDEA). In my particular case, I had different versions of Jackson dependencies.
为了解决这个问题,我首先检查了模块依赖图(在POM中单击组合->Ctrl+Alt+Shift+U或在POM中右键单击->Maven->显示依赖关系),以了解库之间冲突的确切位置(Intelij Idea)。在我的特殊情况下,我有不同版本的杰克逊依赖关系。
1) So, I added directly in my POM of the project explicitly the highest version - 2.8.7 of these two.
1)因此,我直接在项目的POM中明确添加了最高版本--这两个版本中的2.8.7。
In properties:
在属性中:
<jackson.version>2.8.7</jackson.version>
And as dependency:
作为依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
2) But also it can be solved using Dependency Exclusions.
2)但也可以使用依赖排除来解决。
By the same principle as below in example:
按照与下面示例中相同的原则:
<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>
Dependency with unwanted version will be excluded from your project.
不需要的版本的依赖项将从您的项目中排除。
Why anybody doesn't mention dependency conflicts? This common problem can be related to included dependency jars with different versions.
Detailed explanation and solution: https://dzone.com/articles/solving-dependency-conflicts-in-maven
为什么没有人提到依赖冲突?这个常见问题可能与包含不同版本的依赖jar有关。详细解释和解决方案:https://dzone.com/articles/solving-dependency-conflicts-in-maven
Short answer;
简短的回答;
Add this maven dependency;
添加这个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>
Then run this command;
然后运行此命令;
mvn enforcer:enforce
Maybe this is the cause your the issue you faced.
也许这就是你面临的问题的原因.
If you are writing a webapp, ensure that you don't have conflicting versions of a jar in your container's global library directory and also in your app. You may not necessarily know which jar is being used by the classloader.
如果您正在编写Web应用程序,请确保容器的全局库目录中和应用程序中没有冲突的JAR版本。您可能不一定知道类加载器正在使用哪个JAR。
e.g.
例如:
- tomcat/common/lib
- mywebapp/WEB-INF/lib
For me it happened because I changed argument type in function, from Object a, to String a. I could resolve it with clean and build again
对我来说,这是因为我将函数中的参数类型从对象a更改为字符串a。
This can also be the result of using reflection. If you have code that reflects on a class and extracts a method by name (eg: with Class.getDeclaredMethod("someMethodName", .....)
) then any time that method name changes, such as during a refactor, you will need to remember to update the parameters to the reflection method to match the new method signature, or the getDeclaredMethod
call will throw a NoSuchMethodException
.
这也可能是使用反射的结果。如果您有反映在类上并按名称提取方法的代码(例如:with Class.getDeclaredMethod(“omeMethodName”,.....))然后,只要该方法名称发生更改,例如在重构期间,您将需要记住更新反射方法的参数以匹配新的方法签名,否则getDeclaredMethod调用将抛出NoSuchMethodException异常。
If this is the reason, then the stack trace should show the point that the reflection method is invoked, and you'll just need to update the parameters to match the actual method signature.
如果这是原因,那么堆栈跟踪应该显示反射方法被调用的点,您只需要更新参数以匹配实际的方法签名。
In my experience, this comes up occasionally when unit testing private methods/fields, and using a TestUtilities
class to extract fields for test verification. (Generally with legacy code that wasn't designed with unit testing in mind.)
根据我的经验,在对私有方法/字段进行单元测试以及使用TestUtilities类提取用于测试验证的字段时,偶尔会出现这种情况。(通常使用设计时未考虑单元测试的遗留代码。)
In my case I had a multi module project and scenario was like com.xyz.TestClass
was in module A
and as well as in module B
and module A
was dependent on module B
. So while creating a assembly jar I think only one version of class was retained if that doesn't have the invoked method then I was getting NoSuchMethodError
runtime exception, but compilation was fine.
在我的例子中,我有一个多模块项目,场景类似于com.xyz。TestClass在模块A中,也在模块B中,模块A依赖于模块B。因此,在创建程序集JAR时,我认为只保留了类的一个版本,如果它没有调用的方法,那么我会得到NoSuchMethodError运行时异常,但编译很好。
Related : https://reflectoring.io/nosuchmethod/
相关:https://reflectoring.io/nosuchmethod/
It means the respective method is not present in the class:
这意味着相应的方法不存在于类中:
- If you are using jar then decompile and check if the respective version of jar have proper class.
- Check if you have compiled proper class from your source.
I have just solved this error by restarting my Eclipse and run the applcation.
The reason for my case may because I replace my source files without closing my project or Eclipse.
Which caused different version of classes I was using.
我刚刚通过重新启动我的Eclipse并运行应用程序解决了这个错误。我出现这种情况的原因可能是因为我在没有关闭项目或Eclipse的情况下替换了源文件。这导致了我使用的类的不同版本。
Try this way: remove all .class files under your project directories (and, of course, all subdirectories). Rebuild.
尝试这种方法:删除项目目录(当然还有所有子目录)下的所有.class文件。重建。
Sometimes mvn clean
(if you are using maven) does not clean .class files manually created by javac
. And those old files contain old signatures, leading to NoSuchMethodError
.
有时,MVN CLEAN(如果您使用的是Maven)不会清除由javac手动创建的.class文件。这些旧文件包含旧签名,导致NoSuchMethodError。
Just adding to existing answers. I was facing this issue with tomcat in eclipse. I had changed one class and did following steps,
只是对现有的答案进行补充。我在日食中遇到了Tomcat的这个问题。我换了一节课,做了以下几个步骤,
Cleaned and built the project in eclpise
mvn clean install
- Restarted tomcat
Still I was facing same error. Then I cleaned tomcat, cleaned tomcat working directory and restarted server and my issue is gone. Hope this helps someone
尽管如此,我仍然面临着同样的错误。然后我清理了Tomcat,清理了Tomcat工作目录,并重新启动了服务器,我的问题就解决了。希望这能帮助一些人
These problems are caused by the use of the same object at the same two classes.
Objects used does not contain new method has been added that the new object class contains.
这些问题是由于在相同的两个类中使用相同的对象而引起的。使用的对象不包含新对象类所包含的已添加的新方法。
ex:
例如:
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$
These problems are caused by the concomitant 02 similar class (1 in src, 1 in jar file here is gateway.jar)
这些问题是由伴随的02相似类引起的(1在src中,1在jar文件中,这里是gateway.jar)
To answer the original question. According to java docs here:
回答原来的问题。根据这里的Java文档:
"NoSuchMethodError" Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.
Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.
通常,此错误由编译器捕获;此错误仅在类的定义发生不兼容更改时才会在运行时发生。
- If it happens in the run time, check the class containing the method is in class path.
- Check if you have added new version of JAR and the method is compatible.
I fixed this problem in Eclipse by renaming a Junit test file.
In my Eclipse work space I have an App project and a Test project.
The Test project has the App project as a required project on the build path.
我通过重命名一个Junit测试文件修复了Eclipse中的这个问题。在我的Eclipse工作区中,我有一个App项目和一个测试项目。测试项目将App项目作为构建路径上的必需项目。
Started getting the NoSuchMethodError.
Then I realized the class in the Test project had the same name as the class in the App project.
已开始获取NoSuchMethodError。然后我意识到测试项目中的类与App项目中的类同名。
App/
src/
com.example/
Projection.java
Test/
src/
com.example/
Projection.java
After renaming the Test to the correct name "ProjectionTest.java" the exception went away.
将测试重命名为正确的名称“ProjectionTest.java”后,异常消失了。
NoSuchMethodError : I have spend couple of hours fixing this issue, finally fixed it by just renaming package name , clean and build ... Try clean build first if it doesn't works try renaming the class name or package name and clean build...it should be fixed. Good luck.
NoSuchMethodError:我花了几个小时来修复这个问题,最后通过重命名包名称、清理和构建来修复它。如果不起作用,首先尝试干净构建,尝试重命名类名或包名,然后尝试干净构建……它应该被修复。祝好运。
I ran into a similar problem when I was changing method signatures in my application.
Cleaning and rebuilding my project resolved the "NoSuchMethodError".
当我在应用程序中更改方法签名时,我遇到了类似的问题。清理和重建我的项目解决了“NoSuchMethodError”。
Above answer explains very well ..just to add one thing
If you are using using eclipse use ctrl+shift+T and enter package structure of class (e.g. : gateway.smpp.PDUEventListener ), you will find all jars/projects where it's present. Remove unnecessary jars from classpath or add above in class path. Now it will pick up correct one.
上面的答案解释得很好……如果你正在使用eclipse,使用ctrl+Shift+T并输入类的包结构(例如:gateway.smpp.PDUEventListener),你会发现它所在的所有JAR/项目。从类路径中删除不必要的JAR或将其添加到类路径中。现在它会拿起一个正确的。
I ran into similar issue.
我也遇到过类似的问题。
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
Finally I identified the root cause was changing the data type of variable.
最后,我找出了根本原因是更改了变量的数据类型。
Employee.java
--> Contains the variable (EmpId
) whose Data Type has been changed from int
to String
.
ReportGeneration.java
--> Retrieves the value using the getter, getEmpId()
.
We are supposed to rebundle the jar by including only the modified classes. As there was no change in ReportGeneration.java
I was only including the Employee.class
in Jar file. I had to include the ReportGeneration.class
file in the jar to solve the issue.
我们应该通过只包含修改后的类来重新绑定JAR。由于ReportGeneration.java中没有更改,所以我只在Jar文件中包含了Employee.类。为了解决这个问题,我不得不在JAR中包含ReportGeneration.class文件。
I've had the same problem. This is also caused when there is an ambiguity in classes. My program was trying to invoke a method which was present in two JAR files present in the same location / class path. Delete one JAR file or execute your code such that only one JAR file is used. Check that you are not using same JAR or different versions of the same JAR that contain the same class.
我也遇到过同样的问题。当类中存在歧义时,也会导致这种情况。我的程序试图调用一个方法,该方法出现在同一位置/类路径中的两个JAR文件中。删除一个JAR文件或执行您的代码,以便只使用一个JAR文件。检查您没有使用包含相同类的相同JAR或相同JAR的不同版本。
DISP_E_EXCEPTION [step] [] [Z-JAVA-105 Java exception java.lang.NoSuchMethodError(com.example.yourmethod)]
Most of the times java.lang.NoSuchMethodError is caught be compiler but sometimes it can occur at runtime. If this error occurs at runtime then the only reason could be the change in the class structure that made it incompatible.
Best Explanation: https://www.journaldev.com/14538/java-lang-nosuchmethoderror
最佳解释:https://www.journaldev.com/14538/java-lang-nosuchmethoderror
I've encountered this error too.
我也遇到过这个错误。
My problem was that I've changed a method's signature, something like
我的问题是我更改了一个方法的签名,如下所示
void invest(Currency money){...}
into
vt.进入,进入
void invest(Euro money){...}
This method was invoked from a context similar to
此方法是从类似于
public static void main(String args[]) {
Bank myBank = new Bank();
Euro capital = new Euro();
myBank.invest(capital);
}
The compiler was silent with regard to warnings/ errors, as capital is both Currency as well as Euro.
编者对警告/错误保持沉默,因为资本既是货币,也是欧元。
The problem appeared due to the fact that I only compiled the class in which the method was defined - Bank, but not the class from which the method is being called from, which contains the main() method.
出现问题的原因是,我只编译了定义方法的类-Bank,而没有编译从中调用方法的类,该类包含main()方法。
This issue is not something you might encounter too often, as most frequently the project is rebuilt mannually or a Build action is triggered automatically, instead of just compiling the one modified class.
这个问题您可能不会经常遇到,因为最常见的情况是手动重新构建项目,或者自动触发构建操作,而不是仅仅编译一个修改过的类。
My usecase was that I generated a .jar file which was to be used as a hotfix, that did not contain the App.class as this was not modified. It made sense to me not to include it as I kept the initial argument's base class trough inheritance.
我的用例是,我生成了一个要用作修补程序的.jar文件,该文件不包含App.class,因为它没有被修改。对我来说,不包括它是有意义的,因为我通过继承保留了初始参数的基类。
The thing is, when you compile a class, the resulting bytecode is kind of static, in other words, it's a hard-reference.
问题是,当您编译一个类时,结果字节码是一种静态的,换句话说,它是硬引用。
The original disassembled bytecode (generated with the javap tool) looks like this:
原始的反汇编字节码(使用javap工具生成)如下所示:
#7 = Methodref #2.#22 // Bank.invest:(LCurrency;)V
After the ClassLoader loads the new compiled Bank.class, it will not find such a method, it appears as if it was removed and not changed, thus the named error.
ClassLoader加载新的编译后的Bank.class后,它将找不到这样的方法,它看起来好像被移除了,没有更改,因此出现了命名错误。
Hope this helps.
希望这能帮上忙。
The problem in my case was having two versions of the same library in the build path. The older version of the library didn't have the function, and newer one did.
在我的例子中,问题是在构建路径中有同一个库的两个版本。较旧版本的库没有该功能,而较新版本的库则有。
I had a similar problem with my Gradle Project using Intelij.
I solved it by deleting the .gradle (see screenshot below) Package and rebuilding the Project.
.gradle Package
我在使用Intelij的Gradle项目中也遇到了类似的问题。我通过删除.gradle包(见下面的屏幕截图)并重新构建项目解决了这个问题。.gradle包
I had faced the same issue. I changed the return type of one method and ran the test code of that one class. That is when I faced this NoSuchMethodError
. As a solution, I ran the maven builds on the entire repository once, before running the test code again. The issue got resolved in the next single test run.
我也曾面临过同样的问题。我更改了一个方法的返回类型,并运行了那个类的测试代码。这就是我面对这个NoSuchMethodError的时候。作为解决方案,在再次运行测试代码之前,我在整个存储库上运行了一次maven构建。这个问题在下一次测试运行中得到了解决。
One such instance where this error occurs:
I happened to make a silly mistake of accessing private static member variables in a non static method. Changing the method to static solved the problem.
发生这种错误的一个这样的例子是:我碰巧犯了一个愚蠢的错误,在非静态方法中访问私有静态成员变量。将方法改为静态,解决了问题。
更多回答
We recently discovered the cause of one of these and it turned out the build process was putting class files in place before the java server was shut down, and we hit this because the java server hadn't loaded some classes, and then it did load some but it got these new ones, and since the new code referred to methods that the old classes didn't have... bingo, NoSuchMethodError
我们最近发现了其中一个问题的原因,事实证明,构建过程是在Java服务器关闭之前将类文件放在适当的位置,我们遇到了这个问题,因为Java服务器没有加载一些类,然后它确实加载了一些类,但它获得了这些新的类,而且因为新代码引用了旧类没有的方法……Bingo,NoSuchMethodError
"Look at the stack trace..." - Well, I almost always go and check the last Caused by
section in the stack trace to find the culprit class/jar
“查看堆栈跟踪...”-好的,我几乎总是检查堆栈跟踪中的最后一个原因部分,以找到罪魁祸首类/JAR
@Vetle, does that mean, imported classes are dynamically loaded in Java in contrast to static loading in C?
@Vetle,这是否意味着导入的类在Java中动态加载,而不是在C中静态加载?
+1 for "Everybody expects you to know how to use it and if you don't they downvote your question."
+1代表“每个人都希望你知道如何使用它,如果你不知道如何使用,他们就会否决你的问题。”
In other words, you are saying that if you are using reflection to get a method on a class and the method is not found, you get a NoSuchMethodException. But if you are in a scenario when you compiled your code against some libs and on the server you have other libs (maybe newer maybe older) then you get the NoSuchMethodError. Correct me if I'm wrong.
换句话说,您是说,如果使用反射获取类上的方法,但未找到该方法,则会出现NoSuchMethodException。但是,如果您使用某些库来编译代码,并且在服务器上有其他库(可能更新,也可能更老),则会出现NoSuchMethodError。如果我说错了,请纠正我。
+1 Brilliant! I solved a nasty little problem by using this method, thanks. This is an excellent way to discover when classes have sneaked their way onto a classpath somehow.
+1太棒了!我用这个方法解决了一个棘手的小问题,谢谢。这是发现类以某种方式偷偷进入类路径的绝佳方法。
I don't think any other answers are justified...this is how you figure out where the wrong dependency is loaded from, which is the essence of the question...saved my (second) day :)
我不认为任何其他答案是合理的……这就是如何找出错误的依赖项是从哪里加载的,这是问题的实质……节省了我(第二天)的时间:)
@matt Does that mean, imported classes are dynamically loaded in Java in contrast to static loading in C?
@Matt这是否意味着,导入的类在Java中动态加载,而不是在C中静态加载?
This is also the case for Gradle builds.
Gradle版本也是如此。
Actually, this feels more like an issue that crops up for Java programmers who are using any Java development framework: Maven, NetBeans, and Apache Ant, as you can see from all the answers here.
实际上,这更像是使用任何Java开发框架的Java程序员都会遇到的问题:Maven、NetBeans和ApacheAnt,正如您可以从这里的所有答案中看到的那样。
Ahh! this helped me, was looking in the wrong direction after all. Thanks, man !!!
啊!这对我有帮助,毕竟是在寻找错误的方向。谢谢,伙计!
The question was about NoSuchMethodError
, not NoSuchMethodException
问题是关于NoSuchMethodError的,而不是关于NoSuchMethodException的
Oh, good call out! I didn't know both of those existed when I wrote this 15 years ago, and assumed it was a typo.
哦,打得好!15年前,当我写这篇文章的时候,我并不知道这两个词都存在,我以为这是一个打字错误。
Thanks, you just saved me from hours of debugging!
谢谢,你帮我省下了几个小时的调试时间!
God damn it, thanks man, you are the best man, who solves the problem among their people.
他妈的,谢天谢地,你是最好的人,解决了他们人民之间的问题。
I had a similar issue. I had a dependency class with the same complete canonical name. After renaming the exception went away.
我也有过类似的问题。我有一个具有相同完整规范名称的依赖类。重命名后,例外就消失了。
我是一名优秀的程序员,十分优秀!