Tomcat 8.0下Restful服务突发报错:Invalid byte tag in constant pool:19
这个问题我之前帮同事排查过,核心原因很明确:Tomcat 8.0自带的BCEL组件不支持Java 9及以上版本的字节码格式,而你用的yasson-1.0.jar包含了Java 9+才有的模块描述文件module-info.class,两者不兼容就触发了这个错误。
下面给你几个可行的解决方案,按推荐程度排序:
方案一:替换为兼容Java 8的yasson版本
yasson从部分版本开始引入了Java模块支持,你可以换成不包含模块信息的旧版本,比如yasson-1.0.3——这个版本基于Java 8编译,没有module-info.class,能完美适配Tomcat 8.0。
只需要把当前WEB-INF/lib下的yasson-1.0.jar替换成yasson-1.0.3.jar即可,Maven依赖可以这么写:
<dependency> <groupId>javax.json.bind</groupId> <artifactId>yasson</artifactId> <version>1.0.3</version> </dependency>
方案二:升级Tomcat到9.0及以上版本
如果项目允许的话,直接升级Tomcat是更彻底的解决办法。Tomcat 9.0开始对Java 9+的字节码做了适配,自带的BCEL库已经能识别常量池标签19(Java 9的动态常量),自然就不会再报这个错误了。
方案三:手动移除jar中的module-info.class(不推荐)
如果暂时没法换版本或升级Tomcat,你可以用jar命令手动删除yasson-1.0.jar里的module-info.class:
# 先解压jar到临时目录 jar xf yasson-1.0.jar # 删除module-info.class rm module-info.class # 重新打包jar jar cf yasson-1.0-fixed.jar .
然后用这个修改后的jar替换原文件。不过这个方法属于临时 workaround,可能会引发其他依赖问题,不建议作为长期方案。
错误原因详解
报错信息里的
Invalid byte tag in constant pool: 19,是因为Java 9新增了CONSTANT_Dynamic常量类型,对应的标签就是19。Tomcat 8.0的BCEL库是为Java 8设计的,根本不知道这个新常量类型,所以在扫描yasson-1.0.jar里的module-info.class(Java模块的描述文件,用Java 9+编译)时,就直接抛出了格式异常。
内容的提问来源于stack exchange,提问作者Vishal

