某一天线上突然出现如下报错(不影响应用启动和访问,但就是报错了!!):


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就正常了,至于源码是怎么摸样的,这个就需要大家探究了。