Военный файл Spring Boot 2 пытается загрузить класс el-api v3.0 (NoClassDefFoundError: javax / el / ELManager) на tomcat 7 (el-api 2.2) - PullRequest
0 голосов
/ 24 мая 2018

У меня есть проект Gradle Spring boot 2, который я надеюсь развернуть как (неисполняемый) военный файл в экземпляре tomcat 7. (RHEL).

Я получаю NoClassDefFoundError при развертыванииwar to 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

При проверке я обнаружил, что библиотеке проверки bean-компонента не удалось найти этот конкретный класс (javax.el.ElManager) во время инициализации.

Решение здесь предлагает добавить правильную зависимость el-api v3.0 в среду выполнения, но я не уверен, что это мудрое решение, поскольку el-api v2.2 уже существует среди общих (providedRuntime в gradle)народные) библиотеки в Tomcat.Я обеспокоен проблемами ClassLoader, если у меня есть 2 версии одного и того же API (это разумная проблема?).

Обновление до tomcat 8 не требуется, так как мы запускаем tomcat7на RHEL, который в настоящее время поддерживает только tomcat 7.

Как мне сказать Spring использовать javax el-api v2.2?

Дополнительные примечания

Значение по умолчанию tomcat.version, когда оно зависит от spring-boot-starter-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

Как я понял из другого поста, установка свойства ext['tomcat.version'] gradle в 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 Ответ

0 голосов
/ 24 мая 2018

Spring Boot 2.X поддерживает только Tomcat> = 8.5.X

После попытки изменить транзитивные зависимости конфигураций Spring по умолчанию (а именно hibernate-validator) я наткнулся на документацию для Spring Boot 2 минимальные требования к серверу : Tomcat 8.5.X.Наряду с этим поддерживаются только API сервлетов 3.1+

Основная проблема, с которой я борюсь здесь - которая, несомненно, вызовет проблемы в будущем, если я изменю зависимости - заключается в том, что Tomcat 7 не поддерживается Spring Boot 2 .Любая переходная библиотека, которую я понижаю, может нарушить некоторые другие зависимости, которые требуют ее обновленной функциональности.

Spring Boot 1.5.X , тем не менее, поддерживает серверы приложений Tomcat 7 и Servlet 3.0 .Таким образом, решение состоит в том, чтобы перейти на Spring Boot 1.5.X (в настоящее время на момент написания статьи - 1.5.13).

В качестве альтернативы - и решение, которое я буду использовать здесь с системной командойна моем рабочем месте - это вместо использования встроенных контейнеров сервлетов (т. е. встроенных tomcat 8.5 / 9).К сожалению для меня, это означает длительное обсуждение модификации существующих корпоративных процессов, предполагающих механизм развертывания.Но это помимо смысла: P

...