Tomcat启动报错:ClassFormatException: Invalid byte tag in constant pool: 19
一. 遇到问题❓
❗️先放一张tomcat启动时报错的日志❗️
我所用的JDK版本为:jdk8
tomcat版本为:tomcat 7.xx
从字面以后可以看到 Unable to process Jar entry xxx for annotations (无法处理注释的xx Jar包的条目)
对应的报错是**ClassFormatException **( 类格式异常)
这个异常继承了RuntimeException(运行时异常)
官方解释如下:
Thrown when the BCEL attempts to read a class file and determines that the file is malformed or otherwise cannot be interpreted as a class file (当BCEL试图读取类文件并确定该文件格式不正确或不能将其解释为类文件时抛出)
1.1 名词解释????
-
这里的BCEL为”Byte Code Engineering Library“的缩写 是java字节码操作库,它是Apache Software Foundation 的 Jakarta 项目的一部分,是Java classworking 最广泛使用的一种框架,可以让你深入JVM汇编语言进行类操作的细节 tomcat中实现了bcel的功能
-
lib/tomcat-coyote.jar中的包com.apache.tomcat.util.bcel为相关类
抛出上面异常【Invalid byte tag in constant pool: 19】的原因:
at org.apache.tomcat.util.bcel.classfile.Constant.readConstant(Constant.java:97)
at org.apache.tomcat.util.bcel.classfile.ConstantPool.(ConstantPool.java:55)
读取常量池时在Constant.readConstant方法中用switch-case对读取到的首字节进行判断(这个字节标识了常量属于哪种类型),如果无法匹配则抛出异常
(附上一一篇关于java字节码的文章 https://blog.csdn.net/umasanhao/article/details/47338623)
下面为反编译的结果,异常的抛出的值为19,在case的情况里并没有定义,所以抛出了异常
{
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);
}
}
二. 问题解决????
问题来了——这个【19】到底是个什么情况呢?
JDK9中新增了一个很重要的特性——模块化,使用JDK9创建模块并打包后会有一个module-info.class的类 其中常量结构可能有19-CONTANT_Module and 20-CONSTANT_Package两种,不在原有的11种取值之内(如上图所示)
Apache对此也有相关的bug报告 大家可以移步下方地址观看
https://bz.apache.org/bugzilla/show_bug.cgi?id=60688
并最后在如下版本做了修复
- trunk for 9.0.0.M18 onwards
- 8.5.x for 8.5.12 onwards
- 8.0.x for 8.0.42 onwards
- 7.0.x for 7.0.76 onwards
2.1 解决方案:
-
若没有用到该jar包,可以剔除
-
换一个tomcat版本
-
通过修改tomcat加载的配置,不对相应的jar包进行扫描
https://blog.csdn.net/JackRen_Developer/article/details/82288488
tomcat.util.scan.StandardJarScanFilter.jarsToSkip -
jetty也有类似的温柔,jetty新版本解决了加扫描module-info.class的问题,忽略了这个类
https://blog.csdn.net/baidu_34036884/article/details/80151963
三. Reference
1.https://blog.csdn.net/kinder10314/article/details/86629992
2.https://blog.csdn.net/umasanhao/article/details/47338623
3.http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/tomcat/util/bcel/classfile/ClassFormatException.html
4.https://bz.apache.org/bugzilla/show_bug.cgi?id=60688
上一篇: ARM之S5pv210的LCD控制
推荐阅读
-
org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool问题解决方案
-
tomcat启动报错:org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant
-
Tomcat报错之Invalid byte tag in constant pool 19
-
Tomcat启动报错:ClassFormatException: Invalid byte tag in constant pool: 19
-
ClassFormatException: Invalid byte tag in constant pool: 15问题解决
-
ClassFormatException: Invalid byte tag in constant pool: 15问题解决
-
ClassFormatException: Invalid byte tag in constant pool: 15问题解决
-
ClassFormatException: Invalid byte tag in constant pool: 15问题解决