javax.validation.ValidationException: HV000183: Nie można załadować „javax.el.ExpressionFactory”

103

Próbuję napisać bardzo prostą aplikację z walidatorem hibernacji:

moje kroki:

dodaj następującą zależność w pom.xml:

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

napisz kod:

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

    }
}

Otrzymuję następujący stacktrace:

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

Co się mylę?

gstackoverflow
źródło
1
Aktualizacja hibernacji-walidatora do 5.2.4.Finalrozwiązania dla mnie problemu.
fracz
1
@fracz Mam hibernate-validator = 5.2.4.Finali wyjątek nadal istnieje.
Alfonso Nishikawa

Odpowiedzi:

154

Działa po dodaniu do pom.xmlnastępujących zależności:

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

Pierwsze kroki z Hibernate Validator :

Hibernate Validator wymaga również implementacji Unified Expression Language ( JSR 341 ) do oceny dynamicznych wyrażeń w komunikatach o naruszeniu ograniczeń. Gdy aplikacja działa w kontenerze Java EE, takim jak WildFly , implementacja EL jest już dostarczona przez kontener. Jednak w środowisku Java SE musisz dodać implementację jako zależność do pliku POM. Na przykład możesz dodać następujące dwie zależności, aby użyć implementacji referencyjnej 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
źródło
5
Bean Validation 1.1 wymaga zależności języka wyrażeń w ścieżce klas. Zobacz także hibernate.org/validator/documentation/getting-started
Hardy.
1
<dependency> <groupId> org.glassfish.web </groupId> <artifactId> javax.el </artifactId> <version> 2.2.4 </version> <scope> runtime </scope> </dependency> jest wystarczające, ponieważ walidator hibernacji już zależy od javax.el-api
mvera
8
<dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>2.3.1</version></dependency>było dla mnie wystarczające
Sanki
1
<dependency> <groupId> javax.el </groupId> <artifactId> el-api </artifactId> <version> 2.2 </version> </dependency> rozwiązał mój problem.
zhy2002,
3
Wygląda na to, że polecają oba na stronie github dla środowisk SE: github.com/hibernate/hibernate-validator . Jednak górny mi wystarczył.
vphilipnyc
56

rób po prostu

<dependency>
   <groupId>javax.el</groupId>
   <artifactId>javax.el-api</artifactId>
   <version>2.2.4</version>
</dependency>
Bruno Lee
źródło
8
Dlaczego nie hibernate-validatorpolegać na tej zależności?
thomas.mc.work
Nie wiem dlaczego, ale byłoby lepiej
Bruno Lee
@ thomas.mc.work Myślę, że uniknę problemów z zależnością przechodnią
gstackoverflow
1
W rzeczywistości jest oznaczony jako zależność w pliku pom, ale z podanym zakresem maven. Oznacza to, że jesteś odpowiedzialny za dodanie go samodzielnie, jeśli Twój serwer JavaEE go nie udostępnia.
real_paul
To rozwiązanie nie działa dla mnie, używam walidatora hibernacji 6.0.4 i java.el w wersji 3.0.0 i używam WebLogic. Czy ktoś może mi pomóc .. docenione pomocne ręce z góry.
Kushwaha
18

Jeśli używasz tomcat jako środowiska wykonawczego serwera i otrzymujesz ten błąd w testach (ponieważ środowisko uruchomieniowe tomcat nie jest dostępne podczas testów), sensowne jest włączenie tomcat el runtime zamiast tego z glassfish). To byłoby:

    <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
źródło
Kocham Cię. Tak.
xdhmoore,
Wciąż cię kocham. Wygląda na to, że możesz uwzględnić tylko tomcat-jasper-elzależność, ponieważ wydaje się, że zawiera ona przejściowo tomcat-el-apizależność.
xdhmoore
13

Jeśli używasz rozruchu sprężynowego ze starterami - ta zależność dodaje oba tomcat-embed-eli hibernate-validatorzależności:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Michał Stochmal
źródło
13

Jeśli nie potrzebujesz javax.el (na przykład w aplikacji JavaSE), użyj ParameterMessageInterpolator z walidatora Hibernate . Walidator Hibernate jest samodzielnym komponentem, którego można używać bez samego Hibernacji .

Zależy od hibernacji-walidatora

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

Użyj 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();
Markus Schulte
źródło
Tak, nie chcę dodawać więcej zależności. Dobra robota
nokieng
Och, to naprawdę dobra odpowiedź, jeśli chodzi o projekty biblioteczne.
Jin Kwon
To powinna być wybrana odpowiedź.
anataliocs
12

Jeśli chodzi o stronę dokumentacji walidatora Hibernate , musisz zdefiniować zależność od JSR-341implementacji:

<dependency>
   <groupId>org.glassfish</groupId>
   <artifactId>javax.el</artifactId>
   <version>3.0.1-b11</version>
</dependency>
herau
źródło
4

Jeśli używasz Spring Boot, działa to dobrze. Nawet z Spring Reactive Mongo.

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

i konfiguracja walidacji:

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();
    }
}
Brzytwa
źródło
2

dla sbt użyj poniższych wersji

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"
prathameshr
źródło
1

Zgodnie z dokumentacją Getting started with Hibernate Validator , należy zapewnić implementację języka wyrażeń (EL) . W środowisku Java EE byłoby to dostarczane przez kontener. Jednak w przypadku samodzielnej aplikacji, takiej jak Twoja, należy ją podać.

Hibernate Validator wymaga również implementacji Unified Expression Language (JSR 341) do oceny dynamicznych wyrażeń w komunikatach o naruszeniu ograniczeń.

Gdy aplikacja działa w kontenerze Java EE, takim jak WildFly, implementacja EL jest już dostarczona przez kontener.

Jednak w środowisku Java SE musisz dodać implementację jako zależność do pliku POM. Na przykład możesz dodać następującą zależność, aby użyć implementacji referencyjnej JSR 341:

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

Przykład zależności w dokumentacji jest nieco przestarzały, ponieważ język wyrażeń został przeniesiony do projektu Jakarta EE w 2018 r. Aby użyć wersji Jakarta EE języka wyrażeń, dodaj następującą zależność Eclipse Glassfish EL:

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

Istnieją inne implementacje EL, które mogą być użyte, inne niż Glassfish. Na przykład Spring Boot domyślnie używa wbudowanego Tomcata . Ta wersja EL może być używana w następujący sposób:

<dependency>
   <groupId>org.apache.tomcat.embed</groupId>
   <artifactId>tomcat-embed-el</artifactId>
   <version>9.0.30</version>
</dependency>
M. Justin
źródło
0

dla gradle:

compile 'javax.el:javax.el-api:2.2.4'
borino
źródło