项目场景:
运行环境:
SpringBoot@2.3.1,自带tomcat9
Activiti@7.1.0M4
问题描述:
引进依赖后,尝试测试一下业务流程,结果第一行debug还没开始,就已经出现错误了
测试代码:
@Autowired
private RepositoryService repositoryService;
@Test
public void initDeploymentBPMN(){
//bpmn文件所在的文件路径
String filename="processes/2.bpmn";
//部署bpmn文件
Deployment deployment=repositoryService.createDeployment()
.addClasspathResource(filename)
.name("流程部署测试BPMN")
.deploy();
System.out.println(deployment.getName());
}
报错信息:
....
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.validation.beanvalidation.LocalValidatorFactoryBean]: Factory method 'defaultValidator' threw exception; nested exception is java.lang.NoSuchMethodError: javax.el.ELUtil.getExpressionFactory()Ljavax/el/ExpressionFactory;
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650)
... 82 more
Caused by: java.lang.NoSuchMethodError: javax.el.ELUtil.getExpressionFactory()Ljavax/el/ExpressionFactory;
at javax.el.ELManager.getExpressionFactory(ELManager.java:38)
at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.buildExpressionFactory(ResourceBundleMessageInterpolator.java:171)
at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.<init>(ResourceBundleMessageInterpolator.java:94)
at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.getDefaultMessageInterpolator(AbstractConfigurationImpl.java:570)
at org.springframework.boot.validation.MessageInterpolatorFactory.getObject(MessageInterpolatorFactory.java:53)
at org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration.defaultValidator(ValidationAutoConfiguration.java:57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 83 more
相关依赖pom.xml:
<properties>
<activiti.version>7.1.0.M4</activiti.version>
</properties>
.....
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>${activiti.version}</version>
<!-- mybatis-plus引用冲突,需要排除-->
<exclusions>
<exclusion>
<artifactId>mybatis</artifactId>
<groupId>org.mybatis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.activiti.dependencies</groupId>
<artifactId>activiti-dependencies</artifactId>
<version>${activiti.version}</version>
<type>pom</type>
</dependency>
<!--自动化生成流程 -->
<!-- https://mvnrepository.com/artifact/org.activiti/activiti-bpmn-layout -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
原因分析:
控制台抛出的是NoSuchMethodError
,javax.el.ELUtil.getExpressionFactory()
方法不存在,这种一般是冲突问题。
1.先排查有多少个重复类包
IDEA中双击shift查询类,这里发现有org.glassfish:jakarta.el:3.0.3
和javax.el:el-api:2.2
两个包,都提供了相同类名
org.glassfish.jakarta.el.ELUtil
中包含有正确方法,另外一个没有
2.通过idea的maven依赖图表排查各种引用的包
org.glassfish.jakarta.el
由tomcat引入,说明之前错误是tomcat抛出的
el-api由activiti-spring引入,这就是罪魁祸首了,排除掉即可
解决方案:
对Activiti-Spring引入的el-api进行排除
<exclusion>
<artifactId>el-api</artifactId>
<groupId>javax.el</groupId>
</exclusion>
修改后pom.xml:
<properties>
<activiti.version>7.1.0.M4</activiti.version>
</properties>
.....
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>${activiti.version}</version>
<!-- mybatis-plus引用冲突,需要排除-->
<exclusions>
<exclusion>
<artifactId>mybatis</artifactId>
<groupId>org.mybatis</groupId>
</exclusion>
<exclusion>
<artifactId>el-api</artifactId>
<groupId>javax.el</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.activiti.dependencies</groupId>
<artifactId>activiti-dependencies</artifactId>
<version>${activiti.version}</version>
<type>pom</type>
</dependency>
<!--自动化生成流程 -->
<!-- https://mvnrepository.com/artifact/org.activiti/activiti-bpmn-layout -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
后记
一开始发现这个问题时分析了很久没有头绪,百度找到篇可能相关的问题博文:activiti7 + springboot2 (十五) JSP页面使用EL表达式引起的错误解决
按文中方法看到大概是tomcat包冲突,但是排除Activiti的juel-api和juel-spi依赖后,问题仍然没有解决,反倒是增加了一堆排查变量,徒增排查时间…
后面在stackoverflow.查询相关问题,才窥得问题所在:问题链接
此问题引入不一样,但都有ELManager相关问题:java.lang.NoClassDefFoundError: javax/el/ELManager
按此答案中引入新依赖后可以解决问题了。下面讨论是el-api相关的东西,看到红框之后我才明白问题在哪:
tomcat8以上用的是el-api@3.0
,然后activiti-spring这里引入的是el-api@2.2
,升级版本后缺失方法,将el-api版本进行升级即可,后续根据这个思路理出了这篇博文