【问题标题】:Spurious NoSuchMethodError虚假的 NoSuchMethodError
【发布时间】:2011-06-22 08:26:32
【问题描述】:

在我们的一个类上通过一个简单的 getter 方法得到了 NoSuchMethodError。奇怪的是,我们可以调试代码并在调试器中看到错误发生(通过跳过相关行),但是我们也可以使用 IDE (IntelliJ IDEA) 来查看该方法是否存在。

xxxx.getYYY() 通过 IDE 表达式求值器可以很好地求值。继续xxxx.getClass().getMethods(),我们可以在列表中看到getYYY() 方法。我们已经尝试清除所有构建的文件、IDE 输出目录、IDE 缓存、重新启动等,但似乎没有任何帮助。

如果我们针对某些东西进行编译,但随后在运行时发现了不同的 Jar/类,我会理解会发生 NoSuchMethodError。但这并没有向我解释为什么在运行时调试有问题的行时,我们可以看到该方法在那里,但是跨过该行会引发异常。

尝试在另一台机器上重现,但无法重现。

有人对这里可能发生的事情有任何见解吗?

【问题讨论】:

  • 你有自己的类加载器层次结构吗?
  • 您可以编辑问题并添加(完整)堆栈跟踪吗?
  • 该行/方法是做什么的,您确定不是该方法引发了 NoSuchMethodError?
  • 你能提供更多关于你的项目设置的信息吗?您是通过 IntelliJ 还是从命令行运行您的应用程序?
  • @Suraj,不仅仅是标准的类加载器。只是使用基本的 Spring 作为容器,没有聪明的东西。

标签: java nosuchmethoderror


【解决方案1】:

很可能您在 IntelliJ 中运行的代码版本与您正在编辑的代码版本不同。我经常遇到这个问题,因为很多 maven 项目同时打开,不同的版本依赖于我正在编辑的内容。 IntelliJ 可能会感到困惑(或者我对我实际运行的版本感到困惑)

【讨论】:

  • 是的,这是我的第一个想法,但这并不能解释在运行时反思“看到”方法的能力。
  • 该方法可能略有不同,例如返回类型可能不同。对于 JVM,所有参数和返回类型都很重要。
  • @Mike Q,这就是编译器所做的。如果您将返回类型从 long 更改为 int,即使您不需要更改代码,也必须重新编译调用者。
  • @Peter,我认为您的返回类型是正确的。我们在某个时候将其更改为返回 Integer 而不是 int,我认为正在捡起一个旧罐子。很难在调试器中发现这种细微差别。
  • 您可能会觉得这篇文章很有趣。它展示了如何通过 Java 中的返回类型进行重载。 vanillajava.blogspot.com/2011/02/…
【解决方案2】:

NoSuchMethodError - 这主要发生在运行时。我遇到了这个错误,原因是我的类路径中的 asm 和 cglib 库版本不兼容。

asm 和 cglib 库被许多框架(如 hibernate、spring、hadoop)用于运行时字节码操作。

类加载器总是引用类路径中 jar 的第一个版本。

【讨论】:

    猜你喜欢
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多