NoSuchMethodError
运行Java程序时出现错误。有什么问题,我该如何解决?
NoSuchMethodError
运行Java程序时出现错误。有什么问题,我该如何解决?
Answers:
没有更多信息,很难找出问题所在,但根本原因是,您可能是针对缺少该方法的该类的另一版本编译了一个类,而不是运行该类时所使用的方法。
查看堆栈跟踪...如果在库中的对象上调用方法时出现异常,则很可能在编译和运行时使用库的不同版本。确保两个地方的版本都正确。
如果在调用由类实例化对象的方法,当出现异常你做,那么你的构建过程似乎是错误的。确保在编译时实际运行的类文件已更新。
这通常是由于使用诸如Apache Ant之类的构建系统而引起的,该构建系统仅在Java文件比类文件新时才编译Java文件。如果方法签名发生更改,并且类使用的是旧版本,则可能无法正确编译。通常的解决方法是进行完全重建(通常是“ ant clean”然后是“ ant”)。
有时,当针对库的一个版本进行编译但针对不同版本运行时,也可能导致这种情况。
如果使用Maven或其他框架,并且几乎随机出现此错误,请尝试像...这样的全新安装。
clean install
如果您编写了对象并且知道它具有方法,则这特别可能起作用。为我工作。
这也可能是使用反射的结果。如果您的代码可以在类上反映并按名称提取方法(例如:with Class.getDeclaredMethod("someMethodName", .....)
),则方法名称每次更改时(例如在重构期间),您都需要记住将参数更新为反射方法以匹配新方法签名,否则getDeclaredMethod
调用将引发NoSuchMethodException
。
如果是这个原因,那么堆栈跟踪应该显示反射方法被调用的点,您只需要更新参数以匹配实际的方法签名即可。
以我的经验,在对私有方法/字段进行单元测试并使用TestUtilities
类提取字段以进行测试验证时,偶尔会遇到这种情况。(通常使用的遗留代码在设计时并未考虑单元测试。)
这些问题是由在相同的两个类上使用相同的对象引起的。已使用新的对象类所包含的不包含新方法的对象。
例如:
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)。
我通过重命名Junit测试文件在Eclipse中解决了此问题。
在Eclipse工作区中,我有一个App项目和一个Test项目。
测试项目将App项目作为构建路径上的必需项目。
开始获取NoSuchMethodError。
然后我意识到Test项目中的类与App项目中的类同名。
App/
src/
com.example/
Projection.java
Test/
src/
com.example/
Projection.java
将测试重命名为正确的名称“ ProjectionTest.java”后,异常消失了。
我有同样的错误:
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)
为了解决这个问题,我首先检查了模块依赖图(click in your POM the combination -> Ctrl+Alt+Shift+U
或right click in your POM -> Maven -> Show dependencies
),以了解库之间的冲突到底在哪里(Intelij IDEA)。在我的特定情况下,我有不同版本的Jackson依赖项。
1)因此,我直接在项目的POM中明确添加了最高版本-这两个版本均为2.8.7。
在属性中:
<jackson.version>2.8.7</jackson.version>
并作为依赖项:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
2)但是也可以使用依赖排除来解决。
通过以下示例中的相同原理:
<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>
与有害版本的依赖关系将从您的项目中排除。
在我的情况下,我有一个多模块项目,场景就像com.xyz.TestClass
在模块中一样,在模块中A
一样,B
并且模块A
依赖于模块B
。因此,在创建程序集jar时,我认为如果没有调用的方法,只保留了一个版本的类,那么我遇到了NoSuchMethodError
运行时异常,但是编译很好。
我遇到了类似的问题。
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
最后,我确定了根本原因是更改了变量的数据类型。
Employee.java
->包含变量(EmpId
),其数据类型已从更改int
为String
。ReportGeneration.java
->使用getter检索值getEmpId()
。我们应该通过仅包含已修改的类来重新打包jar。由于没有任何变化,因此ReportGeneration.java
我仅包含Employee.class
in Jar文件。我必须将ReportGeneration.class
文件包含在jar中才能解决此问题。
大多数情况下,java.lang.NoSuchMethodError被编译器捕获,但有时它可能在运行时发生。如果在运行时发生此错误,则唯一的原因可能是类结构的更改导致其不兼容。
最佳解释:https : //www.journaldev.com/14538/java-lang-nosuchmethoderror
我也遇到了这个错误。
我的问题是我更改了方法的签名,例如
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之后,它将找不到这种方法,看起来好像它已被删除并没有更改,因此命名错误。
希望这可以帮助。
我在使用Intelij的Gradle项目中遇到了类似的问题。我通过删除.gradle(请参见下面的屏幕截图)包并重建Project来解决它。 .gradle软件包
NoSuchMethodError:我花了几个小时解决此问题,最后通过重命名包名称,清理并构建来解决了此问题。如果不起作用,请首先尝试清理构建,然后重命名类名或包名并清理构建。 。它应该是固定的。祝好运。
如果您的文件名与包含main方法的类名不同,则可能是由该错误引起的。