代码之家  ›  专栏  ›  技术社区  ›  coderatchet

Springboot2 war文件尝试在Tomcat7(Elapi2.2)上加载Elapiv3.0类(noclasDeffoundError:javax/el/elmanager)

  •  4
  • coderatchet  · 技术社区  · 6 年前

    我有一个SpringBoot2Gradle项目,我希望将其作为(不可执行的)war文件部署到Tomcat7实例(RHEL)中。

    我收到一个 NoClassDefFoundError 向服务器上的Tomcat部署战争时:

    ...
    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
    

    在检查时,我发现HibernateBean验证库找不到这个特定的类( javax.el.ElManager )初始化期间。

    解决方案 here 建议向运行时添加正确的EL API v3.0依赖项,但我不确定这是一个明智的解决方案,因为EL API v2.2已经存在于共享的( providedRuntime 在格拉德尔的地方图书馆里。我很担心 ClassLoader 如果我有相同API的两个版本(这是合理的考虑吗?).

    升级到tomcat 8是不可行的,因为我们在目前只支持tomcat7的RHEL上运行tomcat7。

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

    附加说明

    违约 tomcat.version 当依靠弹簧启动时,Tomcat似乎 8.5.31 根据 gradlew dependencies 命令:

    +--- 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
    

    据我所知 another post ,设置渐变 ext['tomcat.version'] 属性到 7.0.76 (我们的服务器版本)正确解析这些依赖项:

    +--- 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 存在。

    谢谢你抽出时间来。

    1 回复  |  直到 6 年前
        1
  •  7
  •   coderatchet    6 年前

    弹簧护套2.x仅支持Tomcat>=8.5.x

    在尝试修改默认Spring配置的可传递依赖项之后(即 hibernate-validator )我看到了SpringBoot2的文档 minimum server requirements : Tomcat 8.5.X . 除此之外,只有3.1的servlet API+ are supported

    我在这里所反对的基本问题——如果我改变依赖关系,无疑会产生问题——是这样的 弹簧引导2不支持Tomcat 7 . 我降级的任何可传递库都可能破坏其他需要更新功能的依赖项。

    弹簧套1.5.x does however support Tomcat 7 and Servlet 3.0 应用服务器。所以 解决方案是降级到Spring Boot 1.5.x (目前写作时为1.5.13)。

    或者——我将在我的工作场所向系统团队提出的解决方案是 而是使用嵌入的servlet容器 (即嵌入式Tomcat 8.5/9)。不幸的是,这意味着对假定部署机制的现有企业流程的修改进行了长时间的讨论。但这也不是重点:p