tomcat项目中class文件替换无效引发的思考

最近在项目部署需要修改补丁文件时,我发现了一个特别古怪的问题:

替换掉原先的class文件无效,重启服务器也无效!

一般来说,我们更新网站,就是把更新后的文件,如jsp、class文件,替换掉原先的class文件即可。服务器如Tomcat,会自动为我们完成热部署。如果内存有溢出的话,重启一下服务器就OK了。可是今天,我却发现,替换之后的class文件,无论如何也不生效。

想了很多种可能:Tomcat里面配置自动解析WAR包的配置会不会有影响(项目非war包)?Tomcat里面web.xml相关模式是否有影响?……

弄了半天,修改后的class文件仍然无法起作用。

被修改的类文件,并不同普通的类文件,而是一个接口里面的静态常量。而在Java中,对常量和变量的处理是不一样的。常量是在编译期就已经确定的。也就是说:项目在经javac编译成class文件后,常量在应用中不是以常量名的形式存在的,而是以常量值的形式存在。

举个简单的例子:

我在修改之前的常量是这样:

1
2
3
public class Properties {  
public static final String BACKUP_STATE_7 = "Failure recovery";
}

修改之后是这样:

1
2
3
public class Properties {  
public static final String BACKUP_STATE_7 = "Failure recovery File normal";
}

而在程序中,我们这样使用常量:Properties.BACKUP_STATE_7

可是,在java中编译之后,使用该常量的地方都变成了:Failure recovery

所以,我只是替换我更改后的常量类,项目中使用常量的地方,并没有改变,仍然是Failure recovery

我们都知道,java是在运行期对类进行装载的,所以,它总是会访问到最新版本的类。但是,对于常量域的引用,会在编译期被转化为它表示的值。所以,也就出现了今天的问题。

所以说,静态常量,我们使用时一定要慎重。一旦有修改就需要将整个项目重新编译替换

那么,我又有问题了:如果我现在将上面的常量设置为null,只替换这个文件会怎么样呢?

也即是如下:

1
2
3
public class Properties {  
public static final String BACKUP_STATE_7 = null;
}

替换后,也会出现上面的情况吗?

答案应该是替换后的null(未经尝试,大家可以自己试一下)。原因也跟Java的设计者有关系。

参考:http://blog.csdn.net/liu765023051/article/details/43156631

hoxis wechat
一个脱离了高级趣味的程序员,关注回复1024有惊喜~
赞赏一杯咖啡
0%