Java“NoSuchMethodError”
我得到:
NoSuchMethodError: com.foo.SomeService.doSmth()Z
我是否正确理解这个 'Z'
意味着 doSmth() 方法的返回类型是布尔值?如果为 true,那么这种方法确实不存在,因为该方法返回一些 Collection。但另一方面,如果我调用此方法,我不会将其返回值分配给任何变量。我只是这样调用这个方法:
service.doSmth();
任何想法为什么会发生这个错误?所有必需的 JAR 文件都存在,并且此类中的所有其他方法似乎都存在。
I'm getting:
NoSuchMethodError: com.foo.SomeService.doSmth()Z
Am I understanding correctly that this 'Z'
means that return type of doSmth() method is boolean? If true, then that kind of method really does not exist because this method returns some Collection. But on the other hand if I call this method, I'm not assigning its return value to any variable. I just call this method like this:
service.doSmth();
Any ideas why this error occurs? All necessary JAR files exist and all other methods from this class seems to exist.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
看起来方法在编译期间存在于类路径中,但在应用程序运行期间不存在。
我不认为返回类型是一个问题。如果是的话,就无法编译。当方法调用不明确时,并且当两个方法仅返回类型不同时,编译器会抛出错误。
Looks like method exists in classpath during compilation, but not during running of your application.
I don't think return type is a problem. If it was, it wouldn't compile. Compiler throws error when method call is ambiguous, and it is when two methods differ only by return type.
简而言之 - 运行时的类/jar 文件与编译时使用的不同。
In short - a class/jar file at runtime is not the same that you used at compile time.
这可能是编译时类路径和运行时类路径之间的差异。
事情似乎是这样的:
doSmth()
方法的类路径进行编译的。字节码指的是doSmth()Z
方法。doSmth()Z
方法。相反,找到了返回 Collection 的方法。要纠正此问题,请检查您的(编译时)类路径。
This is probably a difference between your compile-time classpath and you run-time classpath.
Here is what seems to be going on:
doSmth()
method returning a boolean. The byte-code refers to thedoSmth()Z
method.doSmth()Z
method isn't found. A method returning a Collection is found instead.To correct this problem, check your (compile time) classpath.
目前的回复只是告诉你失败的原因。通常知道如何解决问题会更好。正如所提到的,问题通常是您构建了程序,但在运行或导出它时,未包含该库。所以解决方案是...
如果您正在运行,请检查运行配置
选择运行选项卡->运行配置->选择您正在运行的配置->检查类路径选项卡 ->确保您需要的库存在
如果您要导出(例如 war 文件),请按照此操作
选择项目->选择属性->选择部署程序集->按添加->选择 Java 构建路径条目 ->选择要包含在导出文件中的库(例如 war 文件)
在这两种情况下,请确保包含您引用的库。
此错误的其他常见问题是参数类型或可见性不正确,但编译器会在运行之前检测到错误。在这种情况下,只需检查文档以匹配函数和包的可见性,并确保在项目属性的 Java 构建路径中找到该库。
The current reply just tell you why is failing. Usually is even nicer to know how to fix problems. As it is mentioned, the problem usually is that you built your program but when running or exporting it, the library is not included. So the solution is...
If you are running, check the the run configuration
Select Run tab -> Run configurations -> Select the configuration you are running -> Check the Classpath tab -> Ensure the libraries you need are there
If you are exporting (for example a war file), follow this
Select project -> Select properties -> Select Deployment Assembly -> Press Add -> Select Java Build Path Entries -> Select the libraries you want to be included in your exported file (for example a war file)
In both cases, ensure the library which you are referencing in included.
Other frequent problems for this error are not the right type of parameters or visibility but then, the compiler will detect the error before running. In this case, just check the documentation to match the function and package visibility, and ensure that the library is found in Java Build Path in your project properties.
也许仍然可以帮助某人,但是当您在类路径上有两个位于不同 jar 文件中的类,它们具有相同的确切签名但它们没有相同的公共方法时,也会发生此异常。
例如:
在文件 mylibrary1.jar 上,您有类 com.mypackage.mysubpackage.MyClass 和方法 doSmth()
在文件 mylibrary2.jar 上,您有类 com.mypackage.mysubpackage.MyClass 没有方法 doSmth()
但找不到该类上的方法。
确保两个不同的文件上没有相同的包+类。
Maybe still can help somebody, but this exception can happen also when you have on the classpath two classes in different jar files that have the same exact signature but they haven't the same public methods.
For example:
On file mylibrary1.jar you have class com.mypackage.mysubpackage.MyClass with method doSmth()
On file mylibrary2.jar you have class com.mypackage.mysubpackage.MyClass without method doSmth()
When searching the class, the classloader may find first mylibrary2.jar depending on the path precedence but can't find the method on that class.
Be sure you don't have the same package + class on two different files.
我在 Eclipse 中从 SVN 更新这些项目后,在测试多个链接项目中的一些实验性更改时发现了这个问题。
具体来说,我从 SVN 更新了所有项目,并恢复了 .classpath 文件,而不是手动编辑它,以保持简单。
然后我将链接的项目重新添加到路径中,但忘记删除相关的jar。我的问题就是这样发生的。
显然,运行时使用 jar 文件,而编译器使用项目文件。
I noticed this problem occurring while testing some experimental changes in multiple linked projects, after updating them from SVN in Eclipse.
Specifically, I updated all projects from SVN, and reverted the .classpath file rather than edit it manually to keep things simple.
Then I re-added the linked projects to the path, but forgot to remove the related jars. This was how the problem occurred for me.
So apparently the run time used the jar file while the compiler used the project files.
另一种可能发生这种情况并且很难找到的方式是:
如果外部 jar 中方法的签名发生变化,而在 IDE 中没有发现错误,因为它仍然与您调用它的方式兼容,则该类可能不会被重新调用。编译。
如果您的构建检查文件是否有更改,然后才重新编译它们,则在构建过程中可能不会重新编译该类。
因此,当您运行它时,可能会导致该问题。尽管您拥有新的 jar,但您自己的代码仍然需要旧的 jar,但从不抱怨。
更难的是,这取决于 jvm 是否可以处理这种情况。因此,在最坏的情况下,它会在测试服务器上运行,但不会在实际机器上运行。
Another way this can happen and is difficult to find:
If a signature of a method in an external jar changes in a way that there is no error found in the IDE because it's still compatible with how you call it the class might not be re-compiled.
If your build checks the files for changes and only then recompiles them, the class might not be recompiled during the build process.
So when you run it this might lead to that problem. Although you have the new jar, your own code expects still the old one but does never complain.
To make it harder it depends on the jvm if it can handle such cases. So in the worst case it runs on the test server but not on the live machine.