我在库中的接口中更改了一个方法的返回类型。 以前它是无效的,我修改它以返回一个对象。我没有更改模块中的代码,因为我不想对返回的对象做任何事情(它是针对不同的模块) 我使用新的库jar编译了我的模块并运行了单元测试,运行正常但是当我将jar与库jar一起推送到生产并运行模块时,我得到了java.lang.NoSuchMethodError,用于我在界面上更改的方法。 我修改了界面以及实现,两者都在库jar中,我使用spring注释在我的模块中注入实现对象。 这个问题的可能原因是什么?
答案 0 :(得分:7)
听起来你没有重新编译所有内容,或者没有将所有重新编译的jar文件推送到prod。
此外,您没有指定是否重新启动服务器。如果您正在进行某种“热启动”,则必须非常仔细地配置所有类加载器以使其正确。如果你可以完全重启容器,那可能会有所帮助。
答案 1 :(得分:6)
在Java字节码中,方法的返回类型是方法签名的一部分,它区分具有相同名称和相同参数的两个方法(这是您在Java语言中无法做到的)。所以你的代码以某种方式调用这个方法没有重新编译,它仍然试图调用返回void的方法。
答案 2 :(得分:0)
您是否清除了生产部署环境,因为旧的方法签名仍然悬浮在某处?
答案 3 :(得分:0)
我们总是配置我们的生产(和QA)构建过程来清除所有类并重新编译,因为这样的问题。有时编译器依赖性启发式错误(特别是当您将静态final字段定义为常量时,编译器只会优化整个依赖项)。
在这种情况下,虽然使用该方法的代码没有改变(实际上特别是因为它没有改变),但编译后的字节码没有解析为正确的方法签名,也无法找到它所寻找的内容。在字节码级别,有一个对JVM正在查找但未找到的返回类型的引用。
答案 4 :(得分:0)
void
不是任何其他类型的子类型。因此,如果您更改界面以返回非void
类型,则仍会返回void
的实现类将不再与此方法兼容。