迁移至Linux后使用Drools 6出现Java VerifyError启动异常
问题分析与解决方案
问题背景
应用从Solaris迁移到Linux环境后启动失败,抛出java.lang.VerifyError,核心报错:
Caused by: java.lang.VerifyError: (class: ASMAccessorImpl_17883800501688417666490, method: getKnownEgressType signature: ()Ljava/lang/Class;) Illegal type in constant pool
两个环境均使用Java 8,但Solaris版本为1.8.0_152,Linux为1.8.0_191;依赖版本为Drools 6.0.1.Final、mvel2-2.1.8.Final,规则来自包含400+条规则的XLS文件。
根本原因
Oracle在Java 8 Update 181版本中加强了字节码验证的严格性,而MVEL 2.1.8.Final的ASM优化器生成的动态字节码无法通过新版本JVM的验证。Solaris上的Java 8u152未引入该严格校验规则,因此可以正常运行。
解决方案
按优先级推荐以下解决办法:
1. 升级MVEL版本
MVEL后续版本修复了该字节码兼容性问题,建议升级到2.2.8.Final或更高版本,该版本与Drools 6.0.1.Final兼容良好。
以Maven为例修改依赖:
<dependency> <groupId>org.mvel</groupId> <artifactId>mvel2</artifactId> <version>2.2.8.Final</version> </dependency>
2. 降级Linux环境Java版本
若暂时无法升级依赖,可将Linux上的Java版本降级至与Solaris一致的1.8.0_152,避开严格字节码校验的版本。此为临时方案,长期不推荐。
3. 禁用MVEL的ASM优化器
通过配置强制MVEL使用动态优化器,绕过字节码生成的验证问题,代价是性能略有下降,适合紧急场景:
- 代码中初始化前设置:
System.setProperty("mvel2.disable.asm", "true");
- 或添加JVM启动参数:
-Dmvel2.disable.asm=true
验证步骤
- 应用解决方案后重新编译打包
- 在Linux环境启动应用,确认
VerifyError不再抛出 - 测试核心规则业务逻辑,确保功能正常
内容的提问来源于stack exchange,提问作者Michael Starkie
相关产品推荐
相关产品推荐

