NoSuchMethodError错误

cxb1004 浙江海翕信息技术有限公司 技术总监/研发总监  2016-05-16 04:57:44

在如下代码发生了这个错误

query.getIsSelf()==1

错误

[TRACE][15:30:43][org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [BIGINT] - [2]
[DEBUG][15:30:43][org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] - Released JDBC connection
Exception in thread "Thread-12" java.lang.NoSuchMethodError: com.nielsen.nsi.domain.Query.getIsSelf()I
at com.nielsen.nsi.timer.SyncWordCloudDataService.syncWordCloudData(SyncWordCloudDataService.java:59)
at com.nielsen.nsi.timer.SyncWordCloudDataService$$FastClassBySpringCGLIB$$e2696af.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.nielsen.nsi.timer.SyncWordCloudDataService$$EnhancerBySpringCGLIB$$aa7640e6.syncWordCloudData(<generated>)
at com.nielsen.nsi.timer.SyncBuzzDataService$SyncWordCloudDataRunnable.run(SyncBuzzDataService.java:173)
at java.lang.Thread.run(Thread.java:722)
[DEBUG][15:30:43][org.hibernate.loader.Loader] - Result set row: 0

【排查】
1,从产品环境上拉下Query.class,反编译,发现这个类的确有这个方法;
2,在我本地运行的时候没有出错;
3,把本地类替换到服务器上之后,出现错误,觉得应该是代码不一致;
4,同步代码之后,发现Query里的isserf字段从int变成了Integer
5,把代码更新成 SELF_BRAND .equals(query.getIsSelf()) 就可以了。

【原因分析】
Java的编译环境和运行环境还是有不同的。
对于代码query.getIsSelf()==1来说,编译器可能有两种解释:
1,query.getIsSelf()拿到的是Integer对象,编译器会把后面的1自动转化为一个Integer对象,然后做比较,看是否是一个对象(当然不会是一个)
2,query.getIsSelf()拿到的是Integer对象,编译器会自动解释为query.getIsSelf().intValue(),获得int值,然后和1做比较
无论哪种,反正编译器没有报错

但是到了运行的时候,运行器根据==1去到Query里找方法: int getIsSelf() 但是没有,因为只有 Integer getIsSelf() 方法。
于是就爆出这个错误。

【避免方法】
1,严格遵守类型一致,尽量避免是用Java自动类型转换的功能;
2,找错的时候,使用Error,而不是找出错日志, 很奇怪,这个地方竟然没有报错误日志:[ERROR]
...全文
379 点赞 收藏 6
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
skgary 2016-09-09
引用 5 楼 cxb1004 的回复:
[quote=引用 3 楼 skgary的回复:]楼主分析过程和定位结果还不好说。 如果我看到这个问题,其实原因在于,你们的运行环境和开发环境肯定不一致。或者说,你们有好几个人做了jar包,查问题还要去反编译,而没有人敢新出包去打印日志。 要避免这个问题,什么反编译啊,比对啊都是无益的。 解决方法只有一个:形成团队的check in - build - test - release的游戏规则。
说起来容易,做起来难。[/quote] 说起来容易,做起来也容易。 简单的一条规则就是有一台专门用来出包的服务器,正式发给测试团队的安装包必须从这台服务器上出包。
回复
cxb1004 2016-09-05
引用 3 楼 skgary的回复:
楼主分析过程和定位结果还不好说。 如果我看到这个问题,其实原因在于,你们的运行环境和开发环境肯定不一致。或者说,你们有好几个人做了jar包,查问题还要去反编译,而没有人敢新出包去打印日志。 要避免这个问题,什么反编译啊,比对啊都是无益的。 解决方法只有一个:形成团队的check in - build - test - release的游戏规则。
说起来容易,做起来难。
回复
cxb1004 2016-09-05
引用 2 楼 MONKEY_D_GARP的回复:
你是来分享的
仅做记录和分享,一家之言
回复
skgary 2016-05-17
楼主分析过程和定位结果还不好说。 如果我看到这个问题,其实原因在于,你们的运行环境和开发环境肯定不一致。或者说,你们有好几个人做了jar包,查问题还要去反编译,而没有人敢新出包去打印日志。 要避免这个问题,什么反编译啊,比对啊都是无益的。 解决方法只有一个:形成团队的check in - build - test - release的游戏规则。
回复
MONKEY_D_GARP 2016-05-17
你是来分享的
回复
cxb1004 2016-05-16
关键的问题在于没有编译错误,所以才比较难发现.
回复
相关推荐
发帖
Java SE
创建于2007-09-28

6.1w+

社区成员

Java 2 Standard Edition
申请成为版主
帖子事件
创建了帖子
2016-05-16 04:57
社区公告
暂无公告