java -- java.lang.NoSuchMethodError的问题

让这个问题折腾了好长时间,最终在网上看到了一篇文章,解决了这个问题。

转自: http://timen-zbt.iteye.com/blog/1871152

在Java项目进行增量更新的时候经常会出现java.lang.NoSuchMethodError的问题,究其原因有很多:

1、在引包是引用了不匹配的包版本

2、开发环境和运行环境的不一致

3、以上两点都齐全,并且确实有对应的方法存在,依然报java.lang.NoSuchMethodError错误

。。。

 

本文章主要解决第三种问题:对应的方法存在却依然报java.lang.NoSuchMethodError错误

错误重现:

搭建Java工程,并生成如下两个类

TestNoSuchMethodError用于测试

 

Java代码   收藏代码
  1. package com.timen.demo;  
  2.   
  3. public class TestNoSuchMethodError {  
  4.     public static void main(String[] args) {  
  5.         Person p = new Person();  
  6.         p.setName("timen");  
  7.         p.setSuperUser(true);  
  8.         System.out.println(p.getName() + " is Super User? " + p.isSuperUser());  
  9.     }  
  10. }  
 Person
Java代码   收藏代码
  1. package com.timen.demo;  
  2.   
  3. public class Person {  
  4.     private String name;  
  5.     private boolean superUser;  
  6.       
  7.     public Person() {  
  8.     }  
  9.     public String getName() {  
  10.         return name;  
  11.     }  
  12.     public void setName(String name) {  
  13.         this.name = name;  
  14.     }  
  15.     public boolean isSuperUser() {  
  16.         return superUser;  
  17.     }  
  18.     public void setSuperUser(boolean superUser) {  
  19.         this.superUser = superUser;  
  20.     }  
  21.   
  22. }  
 注意:该类的superUser属性为boolean原生数据类型
执行TestNoSuchMethodError,结果如下:

Python代码   收藏代码
  1. D:\MyWorkspace\sts\NoSuchMethodError\bin>java com.timen.demo.TestNoSuchMethodError  
  2. timen is Super User? true  
  3.   
  4. D:\MyWorkspace\sts\NoSuchMethodError\bin>  
将这两个类的编译后的Class文件(包括包目录)保存到其他目录下(相当于发布工程到正式环境中),然后修改Person类
Java代码   收藏代码
  1. package com.timen.demo;  
  2.   
  3. public class Person {  
  4.     private String name;  
  5.     private Boolean superUser;  
  6.       
  7.       
  8.     public Person() {  
  9.     }  
  10.     public String getName() {  
  11.         return name;  
  12.     }  
  13.     public void setName(String name) {  
  14.         this.name = name;  
  15.     }  
  16.     public Boolean isSuperUser() {  
  17.         return superUser;  
  18.     }  
  19.     public void setSuperUser(Boolean superUser) {  
  20.         this.superUser = superUser;  
  21.     }  
  22.   
  23. }  
 注意:这里将superUser属性的类型改为Boolean(boolean的封装类型)
然后将编译后的Person.class拷贝到刚刚发布的项目中替换掉刚才的Person.class文件(注意你没有更改TestNoSuchMethodError类,所以大多你不会想更新这个类)
问题发生了:
Python代码   收藏代码
  1. D:\temp>java com.timen.demo.TestNoSuchMethodError  
  2. Exception in thread "main" java.lang.NoSuchMethodError: com.timen.demo.Person.setSuperUser(Z)V  
  3.         at com.timen.demo.TestNoSuchMethodError.main(TestNoSuchMethodError.java:7)  
  4.   
  5. D:\temp>  
 报出 java.lang.NoSuchMethodError: com.timen.demo.Person.setSuperUser(Z)错误。
该java.lang.NoSuchMethodError为setSuperUser(Z)对应的方法应该是setSuperUser(boolean var)
而在新的Person文件中的setSuperUser方法的签名为可以用javap -s Person查看:
Python代码   收藏代码
  1. D:\temp\com\timen\demo>javap -s Person  
  2. Compiled from "Person.java"  
  3. public class com.timen.demo.Person extends java.lang.Object{  
  4. public com.timen.demo.Person();  
  5.   Signature: ()V  
  6. public java.lang.String getName();  
  7.   Signature: ()Ljava/lang/String;  
  8. public void setName(java.lang.String);  
  9.   Signature: (Ljava/lang/String;)V  
  10. public java.lang.Boolean isSuperUser();  
  11.   Signature: ()Ljava/lang/Boolean;  
  12. public void setSuperUser(java.lang.Boolean);  
  13.   Signature: (Ljava/lang/Boolean;)V  
  14. }  
  15. D:\temp\com\timen\demo>  
 这里就查到原因了,Java在编译的时候确定方法的签名,而Boolean为引用类型使用Ljava/lang/Boolean;签名,而boolean为原生数据类型,用Z作为签名,所以两次编译TestNoSuchMethodError所生成的字节码并不相同。而我们在做手动增量更新的时候又竟然忘记,就会出现java.lang.NoSuchMethodError错误。
更多请关注: http://timen.cloudfoundry.com/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值