Spring Boot 2 War文件尝试在tomcat 7(el-api 2.2)上加载el-api v3.0类(NoClassDefFoundError:javax/el/ELManager) [英] Spring Boot 2 war file attempts to load el-api v3.0 class (NoClassDefFoundError: javax/el/ELManager) on tomcat 7 (el-api 2.2)

查看:63
本文介绍了Spring Boot 2 War文件尝试在tomcat 7(el-api 2.2)上加载el-api v3.0类(NoClassDefFoundError:javax/el/ELManager)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring boot 2 gradle项目,希望将它作为(不可执行的)war文件部署到tomcat 7实例(RHEL).

I have a Spring boot 2 gradle project That I hope to deploy as a (non-executable) war file to a tomcat 7 instance (RHEL).

将战争部署到服务器上的tomcat时,我收到NoClassDefFoundError:

I am receiving a NoClassDefFoundError when deploying the war to tomcat on the server:

...
Caused by: org.hibernate.cfg.beanvalidation.IntegrationException: Error activating Bean Validation integration
        at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:138)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:281)
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892)
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390)
        ... 34 more
Caused by: java.lang.NoClassDefFoundError: javax/el/ELManager
        at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.buildExpressionFactory(ResourceBundleMessageInterpolator.java:88)
        at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.<init>(ResourceBundleMessageInterpolator.java:47)
        at org.hibernate.validator.internal.engine.ConfigurationImpl.getDefaultMessageInterpolator(ConfigurationImpl.java:474)
        at org.hibernate.validator.internal.engine.ConfigurationImpl.getDefaultMessageInterpolatorConfiguredWithClassLoader(ConfigurationImpl.java:650)
        at org.hibernate.validator.internal.engine.ConfigurationImpl.getMessageInterpolator(ConfigurationImpl.java:397)
        at org.hibernate.validator.internal.engine.ValidatorFactoryImpl.<init>(ValidatorFactoryImpl.java:183)
        at org.hibernate.validator.HibernateValidator.buildValidatorFactory(HibernateValidator.java:38)
        at org.hibernate.validator.internal.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:364)
        at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:103)
        at org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:501)
        at org.hibernate.cfg.beanvalidation.TypeSafeActivator.activate(TypeSafeActivator.java:84)
        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.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:132)
        ... 40 more

经过检查,我发现休眠bean验证库在初始化期间未能找到该特定类(javax.el.ElManager).

On inspection I find that the hibernate bean validation library has failed to find this particular class (javax.el.ElManager) during initialization.

解决方案此处建议添加正确的el- api v3.0对运行时的依赖关系,但是我不确定这是一个明智的解决方案,因为el-api v2.2已存在于Tomcat的共享库中(在gradle本地语言中为providedRuntime).如果我有2个相同的API版本,我会担心ClassLoader问题(这是合理的考虑吗?).

The solution here suggests adding the correct el-api v3.0 dependency to the runtime but I'm not sure this is a wise solution because the el-api v2.2 already exists amongst the shared (providedRuntime in gradle vernacular) libraries in Tomcat. I'm concerned about ClassLoader issues if I have 2 versions of the same API (Is this a reasonable concern?).

升级到tomcat 8是必须的,因为我们在目前仅支持tomcat 7的RHEL上运行tomcat7.

Upgrading to tomcat 8 is a no-go, as we run tomcat7 on RHEL which currently only supports tomcat 7.

如何告诉Spring使用javax el-api v2.2?

根据gradlew dependencies命令,当依赖spring-boot-starter-tomcat时,默认的tomcat.version似乎是8.5.31:

The default tomcat.version when depending on spring-boot-starter-tomcat seems to be 8.5.31 according to the gradlew dependencies command:

+--- org.springframework.boot:spring-boot-starter-tomcat:2.0.2.RELEASE
|    +--- javax.annotation:javax.annotation-api:1.3.2
|    +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.31
|    +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.31
|    \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.31

据我从另一篇帖子所了解,设置gradle ext['tomcat.version'] 7.0.76(我们服务器的版本)的属性正确解决了这些依赖关系:

As I understand from another post, settings the gradle ext['tomcat.version'] property to 7.0.76 (our server's version) resolves these dependencies correctly:

+--- org.springframework.boot:spring-boot-starter-tomcat:2.0.2.RELEASE
|    +--- javax.annotation:javax.annotation-api:1.3.2
|    +--- org.apache.tomcat.embed:tomcat-embed-core:8.5.31 -> 7.0.76
|    +--- org.apache.tomcat.embed:tomcat-embed-el:8.5.31 -> 7.0.76
|    \--- org.apache.tomcat.embed:tomcat-embed-websocket:8.5.31 -> 7.0.76
|         \--- org.apache.tomcat.embed:tomcat-embed-core:7.0.76

但是我仍然遇到这个NoClassDefFoundError.在我看来,Spring无法识别正确的api版本,并继续假设存在ElManager.

However I still run into this NoClassDefFoundError. It seems to me that Spring does not recognise the correct api version and continues assuming the ElManager is present.

谢谢您的时间.

推荐答案

Spring Boot 2.X仅支持Tomcat> = 8.5.X

尝试修改默认spring配置的可传递依赖关系(即hibernate-validator)之后,我遇到了Spring Boot 2的

Spring Boot 2.X only supports Tomcat >= 8.5.X

After trying to modify the transitive dependencies of the default spring configs (namely hibernate-validator), I came across documentation for Spring Boot 2's minimum server requirements: Tomcat 8.5.X. Alongside that, only servlet APIs of 3.1+ are supported

我在这里要解决的基本问题-如果我更改了依赖项,无疑会在生产线上产生问题-是 Spring Boot 2不支持 Tomcat 7 .我降级的任何传递库都可能破坏其他依赖关系,这需要其更新的功能.

The fundamental problem I am fighting against here - which will undoubtedly produce problems down the line if I changed the dependencies - is that Tomcat 7 is not supported by Spring Boot 2. Any transitive library I downgrade may break some other dependency which requires its updated functionality.

Spring Boot 1.5.X 却可以支持Tomcat 7和Servlet 3.0 应用服务器.因此,解决方案是降级到Spring Boot 1.5.X (在撰写本文时,当前版本为1.5.13).

Spring Boot 1.5.X does however support Tomcat 7 and Servlet 3.0 application servers. So the solution is to downgrade to Spring Boot 1.5.X (currently at 1.5.13 at time of writing).

或者-我将在这里与系统团队一起寻求的解决方案-是代替使用嵌入式servlet容器(即,嵌入的tomcat 8.5/9).对我来说不幸的是,这意味着需要对采用部署机制的现有企业流程进行的长时间讨论.但这不是重点:P

Alternatively - and the solution I will be pressing with the systems team here at my workplace - Is to instead use embedded servlet containers (i.e. tomcat 8.5/9 embedded). Unfortunately for me, That means a long discussion into the modification of existing enterprise processes that assumes a deployment mechanism. But that is besides the point :P

这篇关于Spring Boot 2 War文件尝试在tomcat 7(el-api 2.2)上加载el-api v3.0类(NoClassDefFoundError:javax/el/ELManager)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆