javax.validation.ValidationException: HV000183: невозможно загрузить 'javax.el.ExpressionFactory'

103

Я пытаюсь написать очень простое приложение с валидатором гибернации:

мои шаги:

добавить в pom.xml следующую зависимость:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.1.Final</version>
</dependency>

написать код:

class Configuration {
    Range(min=1,max=100)
    int threadNumber;
    //...

    public static void main(String[] args) {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

        Validator validator = factory.getValidator();

        Configuration configuration = new Configuration();
        configuration.threadNumber = 12;
            //...

        Set<ConstraintViolation<Configuration>> constraintViolations = validator.validate(configuration);
        System.out.println(constraintViolations);

    }
}

И я получаю следующую трассировку стека:

Exception in thread "main" javax.validation.ValidationException: Unable to instantiate Configuration.
    at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:279)
    at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:110)
    ...
    at org.hibernate.validator.internal.engine.ConfigurationImpl.<init>(ConfigurationImpl.java:110)
    at org.hibernate.validator.internal.engine.ConfigurationImpl.<init>(ConfigurationImpl.java:86)
    at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:41)
    at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:276)
    ... 2 more

Что я не так?

gstackoverflow
источник
1
Обновление hibernate-validator для 5.2.4.Finalрешения проблемы для меня.
fracz
1
@fracz У меня есть hibernate-validator =, 5.2.4.Finalи исключение все еще существует.
Альфонсо Нисикава

Ответы:

154

Он работает после добавления pom.xmlследующих зависимостей:

<dependency>
   <groupId>javax.el</groupId>
   <artifactId>javax.el-api</artifactId>
   <version>2.2.4</version>
</dependency>
<dependency>
   <groupId>org.glassfish.web</groupId>
   <artifactId>javax.el</artifactId>
   <version>2.2.4</version>
</dependency>

Начало работы с Hibernate Validator :

Для Hibernate Validator также требуется реализация Unified Expression Language ( JSR 341 ) для оценки динамических выражений в сообщениях о нарушении ограничений. Когда ваше приложение выполняется в контейнере Java EE, таком как WildFly , реализация EL уже предоставляется контейнером. Однако в среде Java SE вы должны добавить реализацию как зависимость к вашему POM-файлу. Например, вы можете добавить следующие две зависимости для использования эталонной реализации JSR 341 :

<dependency>
   <groupId>javax.el</groupId>
   <artifactId>javax.el-api</artifactId>
   <version>2.2.4</version>
</dependency>
<dependency>
   <groupId>org.glassfish.web</groupId>
   <artifactId>javax.el</artifactId>
   <version>2.2.4</version>
</dependency>
gstackoverflow
источник
5
Для Bean Validation 1.1 требуются зависимости языка выражений от пути к классам. См. Также hibernate.org/validator/documentation/getting-started
Харди,
1
<dependency> <groupId> org.glassfish.web </groupId> <artifactId> javax.el </artifactId> <version> 2.2.4 </version> <scope> runtime </scope> </dependency> достаточно как валидатор спящего режима уже зависит от javax.el-api
mvera
8
<dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>2.3.1</version></dependency>мне хватило
Sled
1
<dependency> <groupId> javax.el </groupId> <artifactId> el-api </artifactId> <version> 2.2 </version> </dependency> решил мою проблему.
zhy2002 07
3
Похоже, они рекомендуют оба варианта на странице github для сред SE: github.com/hibernate/hibernate-validator . А вот верхнего мне хватило.
vphilipnyc
56

просто делай

<dependency>
   <groupId>javax.el</groupId>
   <artifactId>javax.el-api</artifactId>
   <version>2.2.4</version>
</dependency>
Бруно Ли
источник
8
Почему бы не hibernate-validatorполагаться на эту зависимость?
thomas.mc.work
Не знаю почему, но было бы лучше
Бруно Ли
@ thomas.mc.work Я думаю, чтобы избежать проблем с транзитивной зависимостью
gstackoverflow
1
Фактически он отмечен как зависимость в файле pom, но с предоставленной областью maven. Это означает, что вы несете ответственность за то, чтобы добавить его самостоятельно, если ваш сервер JavaEE не предоставляет его для вас.
real_paul
Это решение не сработало для меня, я использую валидатор спящего режима 6.0.4 и java.el версии 3.0.0, и я использую WebLogic. Может ли кто-нибудь помочь мне ... заранее признателен за руки.
Кушваха
18

Если вы используете tomcat в качестве среды выполнения сервера и получаете эту ошибку в тестах (поскольку среда выполнения tomcat недоступна во время тестов), имеет смысл включить среду выполнения tomcat el вместо среды выполнения из glassfish). Это было бы:

    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-el-api</artifactId>
        <version>8.5.14</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-jasper-el</artifactId>
        <version>8.5.14</version>
        <scope>test</scope>
    </dependency>
Walkeros
источник
Все еще люблю тебя. Похоже, вы можете включить только tomcat-jasper-elзависимость, поскольку она, кажется, транзитивно включает tomcat-el-apiзависимость.
xdhmoore
13

Если вы используете весеннюю загрузку со стартерами - эта зависимость добавляет оба tomcat-embed-elи hibernate-validatorзависимости:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Михал Стохмаль
источник
13

Если вам не нужен javax.el (например, в приложении JavaSE), используйте ParameterMessageInterpolator из валидатора Hibernate . Валидатор Hibernate - это отдельный компонент, который можно использовать без самого Hibernate .

Зависит от hibernate-валидатора

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>6.0.16.Final</version>
</dependency>

Используйте ParameterMessageInterpolator

import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;

private static final Validator VALIDATOR =
  Validation.byDefaultProvider()
    .configure()
    .messageInterpolator(new ParameterMessageInterpolator())
    .buildValidatorFactory()
    .getValidator();
Маркус Шульте
источник
Да, я не хочу добавлять больше зависимости. Хорошая работа
nokieng
О, для меня это действительно хороший ответ относительно библиотечных проектов.
Джин Квон
Это должен быть выбранный ответ.
anataliocs
4

При использовании Spring Boot это хорошо работает. Даже с Spring Reactive Mongo.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

и конфигурация проверки:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@Configuration
public class MongoValidationConfig {

    @Bean
    public ValidatingMongoEventListener validatingMongoEventListener() {
        return new ValidatingMongoEventListener(validator());
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }
}
Бритва
источник
2

для sbt используйте версии ниже

val glassfishEl = "org.glassfish" % "javax.el" % "3.0.1-b09"

val hibernateValidator = "org.hibernate.validator" % "hibernate-validator" % "6.0.17.Final"

val hibernateValidatorCdi = "org.hibernate.validator" % "hibernate-validator-cdi" % "6.0.17.Final"
пратамешр
источник
1

Согласно документации по началу работы с Hibernate Validator , необходимо предоставить реализацию языка выражений (EL) . В среде Java EE он будет предоставляться контейнером. Однако в автономном приложении, таком как ваше, его необходимо предоставить.

Для Hibernate Validator также требуется реализация Unified Expression Language (JSR 341) для оценки динамических выражений в сообщениях о нарушении ограничений.

Когда ваше приложение выполняется в контейнере Java EE, таком как WildFly, реализация EL уже предоставляется контейнером.

Однако в среде Java SE вы должны добавить реализацию как зависимость к вашему POM-файлу. Например, вы можете добавить следующую зависимость для использования эталонной реализации JSR 341:

<dependency>
  <groupId>org.glassfish</groupId>
  <artifactId>javax.el</artifactId>
  <version></version>
</dependency>

Пример зависимости в документации немного устарел, так как в 2018 году язык выражений был переведен на проект Jakarta EE. Чтобы использовать версию языка выражений Jakarta EE, добавьте следующую зависимость Eclipse Glassfish EL:

<dependency>
   <groupId>org.glassfish</groupId>
   <artifactId>jakarta.el</artifactId>
   <version>3.0.3</version>
</dependency>

Существуют и другие реализации EL, которые можно использовать, кроме Glassfish. Например, Spring Boot по умолчанию использует встроенный Tomcat . Эта версия EL может использоваться следующим образом:

<dependency>
   <groupId>org.apache.tomcat.embed</groupId>
   <artifactId>tomcat-embed-el</artifactId>
   <version>9.0.30</version>
</dependency>
М. Джастин
источник
0

для gradle:

compile 'javax.el:javax.el-api:2.2.4'
борино
источник