ITPub博客

首页 > > > 乙方的烦恼---如何在乙方升级的情况下甲方不用升级?

乙方的烦恼---如何在乙方升级的情况下甲方不用升级?

作者:zhmw 时间:2019-12-26 13:36:37 0 删除 编辑

故事背景

自古以来,做买卖、特别是供大于求情况下,市场游戏总会出现乙方有求于甲方的现象。

 

 

 在现在的市场经济机制下,甲方和乙方的地位更难平等,小王是深有体会。小王是一家软件外包公司的员工,他们为一家国企提供软件服务,最近小王比较烦,因需求变更,甲方大爷软件中引用的一个jar中的常量发生了变化,他们更新了jar包,但甲方只同意将新jar包替换掉旧的jar包,导致系统出现执行异常!甲方限令必须尽快找到问题并解决掉!

为了防止公司信息泄露,我们模拟一下这个场景:

publicclass BinaryCompatibilityTest {

publicstaticvoid main(String[] args) {

System.out.println(DefineConstants.FIRST + " " + DefineConstants.SECOND + " " + DefineConstants.THIRD);

}

}

其中DefineConstants来自甲方对乙方的引用:

import com.test.constants.Words;publicclass DefineConstants {

privateDefineConstants() { };// UninstantiablepublicstaticfinalString FIRST = Words.FIRST;

publicstaticfinalString SECOND = Words.SECOND;

publicstaticfinalString THIRD = Words.THIRD;

}

其中,Words是引用的公用jar包

 

 

 类实现如下:

package com.test.constants;publicclass Words {

private Words() {

}; // UninstantiablepublicstaticfinalString FIRST = "the";

publicstaticfinalString SECOND =null;

publicstaticfinalString THIRD = "set";

}

 

原先打印结果为

the null set

 

现在乙方小王修改了jar包后,代码变成了

package com.test.constants;publicclass Words {

private Words() {

}; // UninstantiablepublicstaticfinalString FIRST = "physics";

publicstaticfinalString SECOND = "chemistry";

publicstaticfinalString THIRD = "biology";

}

他将重新打包后的jar包传给甲方,让甲方在tomcat上替换原来的jar包,结果运行后打印的结果却为:

the chemistry set

小王百思不得其解。

 

 

 反复确认了jar包是否正确,都是最新的jar包。

万般无奈之下只好请出被辞退的中老年技术大神"老司机",并答应老司机1w/d的辛苦费。

 

 老司机了解了情况后,就找到了原因,通过jd-gui反编译了代码给小王看:

 

 替换了jar包后,DefineConstants并没有被重新编译,导致FIRST和THIRD的结果没有发生改变,

但因SECOND本身为null,在编译期常量表达式(compile-time constant expression)[JLS15.28]的精确定义中找到。它的定义太长了,就不在这里写出来了,但是理解这

个程序的行为的关键是null 不是一个编译期常量表达式。运行时就会执行新的结果:chemistry

解决办法是

1. 需要重新编译DefineConstants后,替换到新的class

2.重新编译整个项目的打包文件,提供新的包文件替换旧的打包文件

第一个方案

   优点: 线上改动小,影响小,速度快

   缺点:只能解决当前问题,如果项目中还有别的地方引用这个变量,将还会出错。

第二个方案

   优点:从根本上解决问题

   缺点:线上影响稍微大一些。

 

小王入司刚两年,是个勤奋好学的家伙,项目搞定后请老司机吃饭喝酒,趁老司机酒醉,趁机问解决这个问题的诀窍,老司机喝迷糊后道出了本质:

原来java考虑到升级的问题,有二进制兼容性规范,。。。。。。。。。

因老司机喝的有点多,描述的不是很清楚,小王只记住了在jsl规范了有明确的描述:jsl 13章,https://docs.oracle.com/javase/specs/jls/se12/html/index.html

 

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69901620/viewspace-3142409/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-12-04

  • 博文量
    295
  • 访问量
    9531