javax.validation.ValidationException: HV000183: Không thể tải 'javax.el.ExpressionFactory'


103

Tôi cố gắng viết ứng dụng rất đơn giản với trình xác thực ngủ đông:

các bước của tôi:

thêm phụ thuộc sau vào pom.xml:

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

viết mã:

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);

    }
}

Và tôi nhận được stacktrace sau:

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

Tôi làm gì sai?


1
Đang nâng cấp trình xác thực ngủ đông để 5.2.4.Finalgiải quyết vấn đề với tôi.
fracz

1
@fracz Tôi có hibernate-validator = 5.2.4.Finalvà ngoại lệ vẫn ở đó.
Alfonso Nishikawa

Câu trả lời:


154

Nó đang hoạt động sau khi thêm vào pom.xmlcác phụ thuộc sau:

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

Bắt đầu với Hibernate Validator :

Hibernate Validator cũng yêu cầu triển khai Ngôn ngữ biểu thức thống nhất ( JSR 341 ) để đánh giá các biểu thức động trong các thông báo vi phạm ràng buộc. Khi ứng dụng của bạn chạy trong vùng chứa Java EE chẳng hạn như WildFly , một triển khai EL đã được cung cấp bởi vùng chứa. Tuy nhiên, trong môi trường Java SE, bạn phải thêm một triển khai làm phụ thuộc vào tệp POM của mình. Ví dụ: bạn có thể thêm hai phần phụ thuộc sau để sử dụng triển khai tham chiếu 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>

5
Bean Validation 1.1 yêu cầu các phụ thuộc Ngôn ngữ Biểu thức vào classpath. Xem thêm hibernate.org/validator/documentation/getting-started
Hardy

1
<dependency> <groupId> org.glassfish.web </groupId> <artifactId> javax.el </artifactId> <version> 2.2.4 </version> <scope> thời gian chạy </scope> </dependency> là đủ như ngủ đông validator đã phụ thuộc vào javax.el-api
mvera

8
<dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>2.3.1</version></dependency>là đủ đối với tôi
Sled vào

1
<dependency> <groupId> javax.el </groupId> <artifactId> el-api </artifactId> <version> 2.2 </version> </dependency> đã giải quyết được vấn đề của tôi.
zhy2002

3
Có vẻ như họ đề xuất cả hai trên trang github cho môi trường SE: github.com/hibernate/hibernate-validator . Mặc dù vậy, cái trên cùng là đủ cho tôi.
vphilipnyc

56

chỉ làm

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

8
Tại sao không hibernate-validatordựa vào sự phụ thuộc đó?
thomas.mc.work

Tôi không biết tại sao nhưng sẽ tốt hơn
Bruno Lee

@ thomas.mc.work Tôi nghĩ rằng để tránh các vấn đề phụ thuộc
bắc cầu

1
Nó thực sự được đánh dấu là phụ thuộc trong tệp pom nhưng với phạm vi maven được cung cấp. Điều này có nghĩa là bạn có trách nhiệm tự thêm nó vào nếu máy chủ JavaEE của bạn không cung cấp cho bạn.
real_paul

Giải pháp này không hiệu quả với tôi, tôi đang sử dụng trình xác thực ngủ đông 6.0.4 và java.el của phiên bản 3.0.0 và tôi đang sử dụng WebLogic. Bất kỳ ai có thể xin vui lòng giúp tôi .. đánh giá cao giúp tay trước.
Kushwaha

18

Nếu bạn đang sử dụng tomcat làm thời gian chạy máy chủ của mình và bạn gặp lỗi này trong các bài kiểm tra (vì thời gian chạy tomcat không khả dụng trong các bài kiểm tra) thì việc bao gồm thời gian chạy tomcat thay vì thời gian chạy từ glassfish là rất hợp lý. Điều này sẽ:

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

Tôi mến bạn. Đúng.
xdhmoore

Vẫn yêu bạn. Có vẻ như bạn có thể chỉ bao gồm phần tomcat-jasper-elphụ thuộc, vì nó dường như sẽ bao gồm cả phần tomcat-el-apiphụ thuộc.
xdhmoore

13

Nếu bạn đang sử dụng khởi động mùa xuân với trình khởi động - phần phụ thuộc này thêm cả hai tomcat-embed-elhibernate-validatorphụ thuộc:

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

13

Trong trường hợp bạn không cần javax.el (ví dụ: trong ứng dụng JavaSE), hãy sử dụng ParameterMessageInterpolator từ trình xác thực Hibernate . Trình xác thực Hibernate là một thành phần độc lập, có thể được sử dụng mà không cần chính chế độ Hibernate .

Phụ thuộc vào trình xác thực ngủ đông

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

Sử dụng 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();

Vâng, tôi không muốn thêm phụ thuộc. Làm tốt lắm
nokieng

Ồ, đây thực sự là một câu trả lời tốt cho tôi về các dự án thư viện.
Jin Kwon

Đây nên là câu trả lời được chọn.
anataliocs


4

Nếu sử dụng Spring Boot, điều này hoạt động tốt. Ngay cả với Spring Reactive Mongo.

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

và cấu hình xác thực:

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

cho sbt, sử dụng các phiên bản dưới đây

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

Theo tài liệu Bắt đầu với Trình xác thực Hibernate , cần phải cung cấp triển khai Ngôn ngữ biểu thức (EL) . Trong môi trường Java EE, nó sẽ được cung cấp bởi vùng chứa. Tuy nhiên, trong một ứng dụng độc lập như của bạn, nó cần phải được cung cấp.

Hibernate Validator cũng yêu cầu triển khai Ngôn ngữ biểu thức thống nhất (JSR 341) để đánh giá các biểu thức động trong các thông báo vi phạm ràng buộc.

Khi ứng dụng của bạn chạy trong vùng chứa Java EE chẳng hạn như WildFly, một triển khai EL đã được cung cấp bởi vùng chứa.

Tuy nhiên, trong môi trường Java SE, bạn phải thêm một triển khai làm phụ thuộc vào tệp POM của mình. Ví dụ: bạn có thể thêm phần phụ thuộc sau để sử dụng triển khai tham chiếu JSR 341:

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

Ví dụ về phụ thuộc của tài liệu đã hơi cũ, vì ngôn ngữ biểu thức được chuyển sang dự án Jakarta EE vào năm 2018. Để sử dụng phiên bản Jakarta EE của ngôn ngữ biểu thức, hãy thêm phụ thuộc Eclipse Glassfish EL sau:

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

Có những cách triển khai EL khác có thể được sử dụng ngoài Glassfish. Ví dụ, Spring Boot theo mặc định sử dụng Tomcat nhúng . Phiên bản EL này có thể được sử dụng như sau:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.