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

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

мои шаги:

добавьте следующую зависимость в 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

Что я не так?


person gstackoverflow    schedule 24.06.2014    source источник
comment
Обновление hibernate-validator до 5.2.4.Final решило проблему для меня.   -  person fracz    schedule 21.03.2016
comment
@fracz У меня есть hibernate-validator = 5.2.4.Final, и исключение все еще существует.   -  person Alfonso Nishikawa    schedule 18.05.2016


Ответы (12)


Он работает после добавления в 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>
person gstackoverflow    schedule 24.06.2014
comment
Bean Validation 1.1 требует зависимостей языка выражений от пути к классам. См. также hibernate.org/validator/documentation/getting-started. - person Hardy; 25.06.2014
comment
‹dependency› ‹groupId›org.glassfish.web‹/groupId› ‹artifactId›javax.el‹/artifactId› ‹version›2.2.4‹/version› ‹scope›runtime‹/scope› ‹/dependency› достаточно, поскольку валидатор hibernate уже зависит от javax.el-api - person mvera; 16.07.2014
comment
<dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>2.3.1</version></dependency> мне хватило - person Sled; 25.07.2014
comment
‹dependency› ‹groupId›javax.el‹/groupId› ‹artifactId›el-api‹/artifactId› ‹version›2.2‹/version› ‹/dependency› решил мою проблему. - person zhy2002; 07.10.2014
comment
hibernate-validator использует зависимость области provided от javax.el:javax.el-api и org.glassfish.web:javax.el. Возможно, они не всегда требуются — у меня коллега работает без них, используя проверку xml вместо аннотаций. - person Sarah Phillips; 07.04.2016
comment
Похоже, они рекомендуют оба на странице github для сред SE: github.com/hibernate/hibernate-validator. Хотя мне хватило верхнего. - person vphilipnyc; 29.06.2016
comment
не требуется добавлять зависимость org.glassfish.web, проверьте ответ @Bruno Marinho. - person Vishrant; 08.11.2017
comment
Всем, кто тоже в замешательстве: если вы используете JBoss/Wildfly, это по-прежнему правильный путь, хотя использование библиотеки Glassfish противоречит здравому смыслу. - person Thomas; 31.07.2019
comment
у меня тоже <!-- https://mvnrepository.com/artifact/javax.el/el-api --> <dependency> <groupId>javax.el</groupId> <artifactId>el-api</artifactId> <version>2.2</version> </dependency> сработало - person phil; 24.03.2020

просто сделай

<dependency>
   <groupId>javax.el</groupId>
   <artifactId>javax.el-api</artifactId>
   <version>2.2.4</version>
</dependency>
person Bruno Lee    schedule 29.11.2014
comment
Почему hibernate-validator не использует эту зависимость? - person thomas.mc.work; 11.05.2015
comment
Не знаю почему, но было бы лучше - person Bruno Lee; 12.05.2015
comment
@thomas.mc.work Я думаю, чтобы избежать проблем с транзитивной зависимостью - person gstackoverflow; 20.11.2015
comment
Фактически он помечен как зависимость в файле pom, но с предоставленной областью действия maven. Это означает, что вы должны добавить его самостоятельно, если ваш сервер JavaEE не предоставляет его для вас. - person real_paul; 20.07.2017
comment
Это решение не сработало для меня, я использую валидатор спящего режима 6.0.4 и java.el версии 3.0.0, и я использую WebLogic. Может ли кто-нибудь помочь мне .. заранее оценил помощь. - person Kushwaha; 29.04.2019

Если вам не нужен javax.el (например, в приложении JavaSE), используйте ParameterMessageInterpolator из Спящий валидатор. Средство проверки 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();
person Markus Schulte    schedule 18.02.2019
comment
Да, я не хочу добавлять больше зависимости. Отличная работа - person nokieng; 27.05.2019
comment
О, это действительно хороший ответ для меня относительно библиотечных проектов. - person Jin Kwon; 30.05.2019
comment
Это должен быть выбранный ответ. - person anataliocs; 08.05.2020

Если вы используете 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>
person walkeros    schedule 25.04.2017
comment
Все еще люблю тебя. Похоже, вы можете включить только зависимость tomcat-jasper-el, поскольку она транзитивно включает зависимость tomcat-el-api. - person xdhmoore; 18.07.2019

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

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
person Michał Stochmal    schedule 06.08.2018

Что касается страницы документации валидатора Hibernate, у вас есть чтобы определить зависимость от реализации JSR-341:

<dependency>
   <groupId>org.glassfish</groupId>
   <artifactId>javax.el</artifactId>
   <version>3.0.1-b11</version>
</dependency>
person herau    schedule 19.06.2017

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

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

Это требование описано в документе Начало работы с Hibernate Validator документация. В среде Java EE это будет предоставлено контейнером. В отдельном приложении, таком как ваше, это необходимо предоставить.

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

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

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

<dependency>
  <groupId>org.glassfish</groupId>
  <artifactId>jakarta.el</artifactId>
  <version>${version.jakarta.el-api}</version>
</dependency>

Реализация языка выражений

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

<dependency>
   <groupId>org.apache.tomcat.embed</groupId>
   <artifactId>tomcat-embed-el</artifactId>
   <version>9.0.48</version>
</dependency>

Как отмечено в этом комментарии, должна быть выбрана совместимая версия языка выражений. Реализация Glassfish указана как при условии-scope зависит от Hibernate Validator, поэтому указанная там версия должна работать без проблем. В частности, Hibernate Validator 7 использует версию 4 реализации Glassfish EL и Hibernate 6 использует версию 3.

Весенний ботинок

В проекте Spring Boot обычно используется зависимость spring-boot-starter-validation, а не прямое указание валидатора Hibernate и библиотек EL. Эта зависимость включает как org.hibernate.validator:hibernate-validator, так и tomcat-embed-el.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.4.3.RELEASE</version>
</dependency>
person M. Justin    schedule 02.05.2020
comment
Остерегайтесь совместимости версий: я только что узнал, что Hibernate Validator 6.1 не будет работать с org.glassfish:jakarta.el:4.0.1, мне нужно придерживаться org.glassfish:jakarta.el:3.0.3 (думаю, пока я не обновлю Hibernate Validator). - person Etienne Miret; 14.03.2021
comment
@EtienneMiret Гибернация В документации 7 используется версия 4.0.0, поэтому обновление до нее действительно позволит вам использовать реализацию EL 4. документация по Hibernate 6, с другой стороны использует 3.0.3. - person M. Justin; 14.03.2021
comment
@EtienneMiret Я обновил ответ, упомянув проблему совместимости версий и один из способов убедиться, что выбрана совместимая версия. - person M. Justin; 15.03.2021

Если вы используете 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();
    }
}
person Razor    schedule 18.08.2018

для 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"

person prathameshr    schedule 24.10.2019

Джакарта пространство имен

В рамках передачи от Oracle к Eclipse Foundation, Java EE переименовывается в Jakarta EE. В Jakarta EE 9 имена пакетов Java были изменены с javax.* на jakarta.*.

Ответ М. Джастина верен в отношении Джакарты. Я добавил этот ответ, чтобы предоставить больше объяснений и конкретных примеров.

Интерфейс против реализации

Jakarta Bean Validation — это спецификация API на Java. Бинарная библиотека для этой спецификации содержит только интерфейсы, а не исполняемый код. Поэтому нам также нужна реализация этих интерфейсов.

Я знаю только одну реализацию спецификаций Jakarta Bean Validation версий 2 и 3: Hibernate. Валидатор версий 6 и 7 (соответственно).

Настольные и консольные приложения

Для веб-приложений веб-контейнер, совместимый с Jakarta, предоставит как интерфейс, так и реализацию, необходимые для выполнения проверки компонентов.

Для настольных и консольных приложений у нас нет такого веб-контейнера, совместимого с Jakarta. Таким образом, вы должны связать с вашим приложением интерфейс jar и реализацию jar.

Вы можете использовать инструмент управления зависимостями, такой как Maven, < a href="https://en.wikipedia.org/wiki/Gradle" rel="nofollow noreferrer">Gradle или Ivy, чтобы загрузить и связать JAR-файлы интерфейса и реализации.

Джакартский язык выражений

Чтобы запустить Jakarta Bean Validation, нам нужен еще один инструмент Jakarta: Jakarta Expression Language, специальный язык программирования для внедрение и оценка выражений. Jakarta Expression Language также известен как EL.

Jakarta Expression Language определяется Jakarta EE как спецификация, для которой вы должны загрузить jar интерфейсов. И вам также нужно получить реализацию этих интерфейсов в другом банке.

У вас может быть выбор реализации. По состоянию на 2021-03 год я знаю о Eclipse Glassfish от Eclipse Foundation, предоставляющей реализацию в виде отдельной библиотеки, которую мы можем скачать бесплатно. Могут быть и другие реализации, такие как Open Liberty от IBM Corporation. Присмотритесь к реализации, которая соответствует вашим потребностям.

Зависимости Maven POM

Собрав всю эту информацию вместе, вам понадобятся четыре JAR-файла: пара JAR-файлов интерфейса и реализации для каждого из двух проектов: Jakarta Bean Validation и Jakarta Expression Language.

  • Jakarta Bean Validation
    • Interface
    • Реализация
  • Jakarta Expression Language
    • Interface
    • Реализация

Ниже приведены четыре зависимости, которые необходимо добавить в файл Maven POM, если Maven является вашим предпочтительным инструментом.

Как упоминалось выше, вы можете найти другую реализацию EL, чтобы заменить библиотеку Glassfish, которую я использую здесь.

<!--********| Jakarta Bean Validation  |********-->

<!-- Interface -->

<!-- https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api -->
<dependency>
    <groupId>jakarta.validation</groupId>
    <artifactId>jakarta.validation-api</artifactId>
    <version>3.0.0</version>
</dependency>

<!-- Implementation -->

<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>7.0.1.Final</version>
</dependency>

<!-- Jakarta Expression Language -->

<!-- Interface -->

<!-- https://mvnrepository.com/artifact/jakarta.el/jakarta.el-api -->
<dependency>
    <groupId>jakarta.el</groupId>
    <artifactId>jakarta.el-api</artifactId>
    <version>4.0.0</version>
</dependency>

<!-- Implementation -->

<!-- https://mvnrepository.com/artifact/org.glassfish/jakarta.el -->
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>jakarta.el</artifactId>
    <version>4.0.1</version>
</dependency>

Это должно устранить ошибку javax.validation.ValidationException: HV000183: Unable to load 'javax.el.ExpressionFactory'.

Пример использования

Вы можете протестировать свою установку с помощью следующего простого класса Car. У нас есть проверки для каждого из трех полей-членов.

package work.basil.example.beanval;

import jakarta.validation.constraints.*;

public class Car
{
    // ---------------|  Member fields  |----------------------------
    @NotNull
    private String manufacturer;

    @NotNull
    @Size ( min = 2, max = 14 )
    private String licensePlate;

    @Min ( 2 )
    private int seatCount;

    // ---------------|  Constructors  |----------------------------
    public Car ( String manufacturer , String licensePlate , int seatCount )
    {
        this.manufacturer = manufacturer;
        this.licensePlate = licensePlate;
        this.seatCount = seatCount;
    }

    // ---------------|  Object overrides  |----------------------------

    @Override
    public String toString ( )
    {
        return "Car{ " +
                "manufacturer='" + manufacturer + '\'' +
                " | licensePlate='" + licensePlate + '\'' +
                " | seatCount=" + seatCount +
                " }";
    }
}

Или, если вы используете Java 16 и более поздние версии, вместо этого используйте более краткое record.

package work.basil.example.beanval;

import jakarta.validation.constraints.*;

public record Car (
        @NotNull
        String manufacturer ,
        @NotNull
        @Size ( min = 2, max = 14 )
        String licensePlate ,
        @Min ( 2 )
        int seatCount
)
{
}

Запустите проверку. Сначала мы запускаем успешно настроенный объект Car. Затем мы создаем экземпляр второго объекта Car, который неисправен, нарушая одно ограничение в каждом из трех полей.

package work.basil.example.beanval;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;

import java.util.Set;

public class App
{
    public static void main ( String[] args )
    {
        App app = new App();
        app.demo();
    }

    private void demo ( )
    {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        // No violations.
        {
            Car car = new Car( "Honda" , "ABC-789" , 4 );
            System.out.println( "car = " + car );

            Set < ConstraintViolation < Car > > violations = validator.validate( car );
            System.out.format( "INFO - Found %d violations.\n" , violations.size() );
        }

        // 3 violations.
        {
            Car car = new Car( null , "X" , 1 );
            System.out.println( "car = " + car );

            Set < ConstraintViolation < Car > > violations = validator.validate( car );
            System.out.format( "INFO - Found %d violations.\n" , violations.size() );
            violations.forEach( carConstraintViolation -> System.out.println( carConstraintViolation.getMessage() ) );
        }
    }
}

Когда бег.

car = Car{ manufacturer='Honda' | licensePlate='ABC-789' | seatCount=4 }
INFO - Found 0 violations.
car = Car{ manufacturer='null' | licensePlate='X' | seatCount=1 }
INFO - Found 3 violations.
must be greater than or equal to 2
must not be null
size must be between 2 and 14
person Basil Bourque    schedule 08.03.2021

для градиента:

compile 'javax.el:javax.el-api:2.2.4'
person borino    schedule 09.07.2018

Я столкнулся с той же проблемой, и приведенные выше ответы не помогли. Мне нужно отладить и найти его.

 <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.6.0-cdh5.13.1</version>
        <exclusions>
            <exclusion>
                <artifactId>jsp-api</artifactId>
                <groupId>javax.servlet.jsp</groupId>
            </exclusion>
        </exclusions>
    </dependency>

После исключения jsp-api у меня это сработало.

person Java Carzy    schedule 29.01.2021