Hibernate 7.0.2: javax.validation.NoProviderFoundException - java

I'm using spring-boot-starter-web:jar:2.6.2 in my project, this jar uses hibernate-validator:6.2.0.Final. Recently we decided to move to Hibernate 7.0.2.Final, so I added the following maven config:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${rest.starter.version}</version>
<exclusions>
<exclusion>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.2.Final</version>
</dependency>
But now I get the following error during integration testing or run:
javax.validation.NoProviderFoundException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
Why does it happen and how to fix it?

spring-boot-2.x uses javax.validation Annotations and so you need an implementation for javax.validation.spi.ValidationProvider.
hibernate-validator:7.0.2 has moved from javax.validation to jakarta.validation and for that it is not downward compatible.
It depends on your project now:
upgrade to spring-boot 3.x ( also upgrade from javax.* to jakarta.* - this might be a huge upgrade )
or downgrade hibernate-validator to version 6.x
I hope I have explained it well :-)

Related

Is there a way in POM to specify a higher version for dependent package?

I am using Maven to set up dependency in my app.
I am using Spring Boot v2.1.12.RELEASE which brings in Spring Core v5.1.13.
But there also a library Spring Integration v5.1.9 (which is latest) and brings Spring Core v5.1.11.RELEASE
As you can see that I want Spring Integration to not resolve to v5.1.11 of Spring Core as it has some vulnerabilities.
Is there any way to specify in POM for Spring Integration to resolve to 5.1.13 of Spring Core (instead of 5.1.11) ?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>5.1.9</version>
</dependency>
P.S I do not want to upgrade to the latest release of Spring Boot.
Use maven exclusion tag to exclude the transitive dependency, make sure the excluded library is directly added to pom or it's pulled in by some other dependency.
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>5.1.9</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.11.RELEASE</version>
</exclusion>
</exclusions>
</dependency>
DISCLAIMER: This is just a work around solution for your immediate need, use it only when no other options are possible as managing spring managed dependencies ourself is not maintainable in long run.
I used the recommendation in the post Dependency Management to overcome my challenge.
So I excluded the spring-core dependency from spring integration and also added the spring core library using below code
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.13.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>

Hibernate Validator java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.ConfigurationImpl

I have read this and this, but that didn't help...
I am using hibernate validator with the following versions/dependencies:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.FINAL</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b08</version>
</dependency>
I thought I'm doing everything correctly, and my logs (with verbose:class as a flag) tell me that:
[Loaded org.hibernate.validator.internal.engine.ConfigurationImpl from
file:.../hibernate-validator-5.4.1.Final.jar]
[Loaded javax.validation.Validation from file:.../validation-api-1.1.0.Final.jar]
But later at runtime, when I use
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
I get the classic error:
java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.ConfigurationImpl
I also tried downgrading to hibernate-validator 4.3.1 and javax.validation-api 1.0.0, but the error weirdly enough remained the same.
I have loads of other dependencies in this project(e.g. Spring etc.) , but as far as I can see, none that use hibernate-validator or the javax validation api. (If that were the case, I'd also see them loaded in the logs, wouldn't I?)
Is there any help?
For me the problem was that Hibernate Validator depended on jboss-logging.
And the jboss logging was not part of my classpath.
The exception was not telling me that the class not def found error while trying to instantiate the hibernate configuration impl was from missing jboss logging on the classpath.
Once I added it to the classpath, the class def not found error went away.
I was facing the same issue while working with JSR 303 bean validation
I have added below two jar(along with validation-api-1.1.0.final.jar and hibernate-validator-5.0.1.final.jar) and the issue got resolved
classmate-0.8.0.jar
2.jboss-logging-3.1.0.ga.jar
I would suspect multiple implementations of javax.el. That's usually what causes this sort of issues.
Check that you don't have another one with a different name.
If it's not that, add a checkpoint in the ConfigurationImpl constructor and check what's failing.
Try like this config :
<properties>
<hibernate.version>4.3.11.Final</hibernate.version>
</properties>
<dependencies>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- jsr303 validation -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
</dependencies>
For a complete example..
First, check all dependencies using mvn dependency:tree - Find hibernate-validator and add below one into pom.xml inside respective dependency - if not required.
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</exclusion>
Add this in spring-servelt.xml
<beans:bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> </beans:bean>
and following jars
hibernate-validator-6.0.17.Final.jar
validation-api-2.0.1.Final.jar
classmate-1.3.4.jar
jboss-logging-3.3.2.Final.jar
then all will work fine.
Happy to help...
I had this issue when working on a spring-boot application. The problem was caused by hibernate-validator 6.0.11 which seems to have an erroneous dependency on javax validation-api 2.0.1.Final. For me the solution was to upgrade to a higher version of hibernate-validator.
In more detail:
My application was depending on spring-boot-starter-parent 2.1.18.RELEASE. The spring-boot-starter-web package depends on hibernate-validator 6.0.11, which itself depends on validation-api-2.0.1.Final. validation-api-2.0.1.Final however requires a higher version of the hibernate validator causing the ValueExtractorManager NoClassDefFoundError.
The problem was fixed after upgrading the application to spring-boot-starter-parent 2.1.18.RELEASE which utilizes hibernate-validator 6.0.21.Final.

SLF4J + version 1.7.x by your slf4j binding is not compatible 1.6 [duplicate]

I realised that one of my projects uses slf4j 1.5.8 and Hibernate uses slf4j 1.6. While building with Maven it downloads both jars but I guess the class files of 1.5.8 are used. So, when I run the program i get following error:
SLF4J: The requested version 1.5.8 by your slf4j binding is not compatible with [1.6]
In pom.xml I have put
<dependencyManagement>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
</dependencyManagement>
The 1.5.8 is part of dependency so it's downloaded on its own.
As you discovered yourself, there are two libraries (Hibernate and some other) transitively importing SLF4J in two different versions. Unfortunately the older version is being picked up by maven (there are some rules which dependency should be chosen by maven in this situation). The solution is to add the exclusion in the dependency that imports older version of SLF4J (com.example:foo-bar is example here):
<dependency>
<groupId>com.example</groupId>
<artifactId>foo-bar</artifactId>
<version>1.2.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
If you still experience this problem, issue:
$ mvn dependency:tree
Look for 1.5.8 version and exclude it from all libraries importing it.
Excluding is quite unnecessary and maybe quite misleading. Instead, explicitly include the slf4j-api with the desired version in your projects pom file. That's it!
This approach takes advantage of Maven's transitivity rules: the nearest dependency declaration wins.
you can exclude the wrong version with something like this:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.7.ga</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>

Which maven dependency to choose for JPA 2.1 + 'Spring Data JPA' on Weblogic 12.1.x application server?

I am trying to deploy a JPA 2.1 (Hibernate) project on Weblogic 12.1.3 on Java 8 and getting this error. But works on Tomcat 8.
Caused By: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
at org.hibernate.cfg.annotations.EntityBinder.processComplementaryTableDefinitions(EntityBinder.java:973)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:824)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3845)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3799)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1412)
Truncated. see log file for complete stacktrace
pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
<!--
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
</exclusion>
</exclusions>
</dependency>
-->
Update:-
As answered below, JPA 2.1 is not enabled in Weblogic 12.1.3 by default. And can be enabled as explained here http://www.oracle.com/webfolder/technetwork/tutorials/obe/fmw/wls/12c/01-06-004-JavaEE7andWebLogicServer/javaee7.html#section1
Weblogic is a java-ee application server and comes with the full java-ee stack (and includes so JPA).
Weblogic 12.1.3 comes with jpa 2.1 with eclipselink as provider see here
including hibernate as jpa implementation have so no sense here as the server already come with it's own implmentation (maven scope provided)
I suppose that this dependencies
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
is so sufficient (jpa 2.1 is part of java-ee 7 stack)
Could be that Weblogic is using its own library for JPA, which is older than yours. Could be that JPA 2.1 wasn't enabled during setup. You need to configure the server to enforce your libraries instead of those provided by WLS.
How to configure prefer application packages

What jar should I include to use javax.persistence package in a hibernate based application?

Is it ok to take it from Glassfish project ( glassfish-persistence-api) or may be there is a Hibernate jar?
If you are using maven, adding below dependency should work
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
If you are developing an OSGi system I would recommend you to download the "bundlefied" version from Springsource Enterprise Bundle Repository.
Otherwise its ok to use a regular jar-file containing the javax.persistence package
You can use the ejb3-persistence.jar that's bundled with hibernate. This jar only includes the javax.persistence package.
In the latest and greatest Hibernate, I was able to resolve the dependency by including the hibernate-jpa-2.0-api-1.0.0.Final.jar within lib/jpa directory. I didn't find the ejb-persistence jar in the most recent download.
hibernate.jar and hibernate-entitymanager.jar contains only the packages org.hibernate.*. So you should take it from the Glassfish project.
For JPA 2.1 the javax.persistence package can be found in here:
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
See: hibernate-jpa-2.1-api on Maven Central
The pattern seems to be to change the artefact name as the JPA version changes. If this continues new versions can be expected to arrive in Maven Central here: Hibernate JPA versions
The above JPA 2.1 APi can be used in conjunction with Hibernate 4.3.7, specifically:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.7.Final</version>
</dependency>
In general, i agree with above answers that recommend to add maven dependency, but i prefer following solution.
Add a dependency with API classes for full JavaEE profile:
<properties>
<javaee-api.version>7.0</javaee-api.version>
<hibernate-entitymanager.version>5.1.3.Final</hibernate-entitymanager.version>
</properties>
<depencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
Also add dependency with particular JPA provider like antonycc suggested:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate-entitymanager.version}</version>
</dependency>
Note <scope>provided</scope> in API dependency section: this means that corresponding jar will not be exported into artifact's lib/, but will be provided by application server. Make sure your application server implements specified version of JavaEE API.

Categories

Resources