某一天线上突然出现如下报错(不影响应用启动和访问,但就是报错了!!):
28-Feb-2020 23:44:45.149 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.startup.ContextConfig.processAnnotationsJar Unable to process Jar entry [module-info.class] from Jar [jar:file:/D:/code/other/draw-crm/target/crm/WEB-INF/lib/FastInfoset-1.2.15.jar!/] for annotations
org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19
at org.apache.tomcat.util.bcel.classfile.Constant.readConstant(Constant.java:127)
at org.apache.tomcat.util.bcel.classfile.ConstantPool.<init>(ConstantPool.java:59)
at org.apache.tomcat.util.bcel.classfile.ClassParser.readConstantPool(ClassParser.java:
截取上面的“Invalid byte tag in constant pool”去源码搜到如下:
static final Constant readConstant(DataInputStream file)
throws IOException, ClassFormatException
{
byte b = file.readByte(); // Read tag byte
switch(b) {
case Constants.CONSTANT_Class: return new ConstantClass(file);
case Constants.CONSTANT_Fieldref: return new ConstantFieldref(file);
case Constants.CONSTANT_Methodref: return new ConstantMethodref(file);
case Constants.CONSTANT_InterfaceMethodref: return new
ConstantInterfaceMethodref(file);
case Constants.CONSTANT_String: return new ConstantString(file);
case Constants.CONSTANT_Integer: return new ConstantInteger(file);
case Constants.CONSTANT_Float: return new ConstantFloat(file);
case Constants.CONSTANT_Long: return new ConstantLong(file);
case Constants.CONSTANT_Double: return new ConstantDouble(file);
case Constants.CONSTANT_NameAndType: return new ConstantNameAndType(file);
case Constants.CONSTANT_Utf8: return new ConstantUtf8(file);
default:
throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
}
}
我们这里看起来是b=19时没有匹配上,查了下他的原因如下:
JDK9新增了一个特别重要的特性——模块化,使用JDK9创建模块打包后有一个module-info.class的类
其中常量结构可能有19 - CONSTANT_Module and 20 - CONSTANT_Package两种,不在原有的11种取值之内
备注:官网的bug解决链接为 https://bz.apache.org/bugzilla/show_bug.cgi?id=60688
看完上面就很明显了,解决办法就是将tomcat更换为tomcat 9,道理是知道,我先用几个版本测试,并记录结果如下:
是否线上版本 | tomcat版本 | 结果 |
是 | Tomcat 7.0.59 | 抛错 |
否 | Tomcat 8.0.1 | 抛错 |
否 | Tomcat 8.5.0 | 抛错 |
否 | Tomcat 9.0.20 | 正常 |
总结:最后将tomcat版本更换为9就正常了,至于源码是怎么摸样的,这个就需要大家探究了。