我得到一个NoSuchMethodError错误时运行我的Java程序。出了什么问题,我该怎么解决?


当前回答

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

其他回答

我也遇到过这种错误。

我的问题是我改变了一个方法的签名,就像这样

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()方法。

您可能不会经常遇到这个问题,因为最常见的情况是手动重新构建项目或自动触发Build操作,而不仅仅是编译一个修改过的类。

我的用例是,我生成了一个.jar文件,它是用来作为一个热修复,不包含App.class,因为这是没有修改。对我来说,不包含它是有意义的,因为我通过继承保留了初始参数的基类。

问题是,当你编译一个类时,产生的字节码是静态的,换句话说,它是一个硬引用。

原始的分解字节码(由javap工具生成)如下所示:

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

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

希望这能有所帮助。

这通常是在使用像Apache Ant这样的构建系统时引起的,该构建系统只在java文件比类文件更新时才编译java文件。如果方法签名发生了变化,并且类使用了旧版本,则可能无法正确编译。通常的修复方法是做一个完整的重建(通常是“ant clean”然后“ant”)。

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

注意,在反射的情况下,您将得到NoSuchMethodException,而对于非反射代码,您将得到NoSuchMethodError。当我面对其中一种和另一种时,我倾向于去看非常不同的地方。

这意味着相应的方法在类中不存在:

如果您正在使用jar,那么反编译并检查jar的各个版本是否有适当的类。 检查是否从源代码编译了正确的类。

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

也许这就是你面临问题的原因。