增量部署class文件引发的血案

背景

项目中通过远程调用服务框架调用了许多其它的服务,其中有一个服务wx/subscribe/contract/CircleService 需要升级,其升级不是版本上的升级,而是整个服务重新取了一个名字,使用的也是全新的jar包wuxian/social/contract/SocialService,但是调用的方法没有改变,因此在升级时,只是在调用服务service类中修改了调用地址,和调用返回实体(由CircleService改为SocialService),该service中返回该调用实体使用的是static方法.修改完毕过后本地运行一切正常,于是将修改service的class文件以及对应的jar包上到沙箱环境,并将沙箱环境中原来的CircleService jar包删除,然后重启,但是报错了.代码修改如下:

private static volatile CircleService subCircleService = null;
subCircleService = ProxyFactory.create(CircleService .class,"tcp://circle/CircleServiceImpl" );
public static CircleService getSubCircleService() {
        return subCircleService;
    }

修改为

private static volatile SocialService subCircleService = null;
subCircleService = ProxyFactory.create(SocialService.class,"tcp://social/SocialServiceImpl" );
public static SocialService getSubCircleService() {
        return subCircleService;
    }

其它地方的调用都是用类名+方法名(SCFService.getSubCircleService())的方式访问,故此,在修改时只改动了这个文件,其它文件都没有修改,增量上线的时候也只上线该文件即可.

报错现象

重启服务器的时候无法启动服务,一直报如下错误
图片描述

错误内容为找不到wx/subscribe/contract/CircleService这个jar包提供的方法,很奇怪为什么会提示这个错误,刚开始怀疑是上线的class文件有问题,沙箱上部署class文件没有成功,还是原来的文件,所以又部署了一次,但是还是报同样的错误.

解决过程

将部署到沙箱上的文件下载下来,进行反编译,看引用中是否存在CircleService相关的jar包应用,结果反编译后,发现报错的文件中都没有CircleService相关的jar包引用,于是在cmd窗口中使用javap编译class文件

javap -v xx.class > D:/result.txt

使用该命令后,在result.txt中的常量池中,惊人的发现居然还有引用CircleService相关jar包的行
图片描述

故此解开了为何代码中为何会报上述错误的问题,于是将虽然代码没有改动,但是重新编译过后的class文件上到沙箱,重启,结果果然没有报错了,于是上线.但是上线过后才发现,其它类在访问时候才会调用该方法的类依旧会报上述错误,于是重新检查了一遍所有引用过上述修改过的方法的类,将重新编译过后的文件都上线,才解决了报错的问题,这就是增量上线class文件引发的一起血案.

思考

我们观察在在上述报错中,报错内容为NoSuchMethodError,而不是ClassNotFound,这是为什么呢?在其它代码引用上述修改的方法时,都是通过SCFService.getSubCircleService()的方式调用,而没有写返回类,在调用上述方法时,老的class文件常量池中,getSubCircleService()返回的是CircleService方法,而新上线的SCFService中该方法的返回值已经修改为SocialService,故此会先报NoSuchMethodError错误.
这种错误类似于我们在常量类中定义

public static final CONST = 100;

后,要修改常量CONST值为1000后,只增量上线了该常量class文件,而其它引用该常量的类的文件都更新上线所引发的CONST依旧为100的问题.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值