Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unregistered element accesses when using Hibernate ORM in native mode #45654

Merged
merged 4 commits into from
Jan 21, 2025

Conversation

zakkak
Copy link
Contributor

@zakkak zakkak commented Jan 16, 2025

Registers:

  • Hibernate service providers for native run-time access
  • jakarta.validation.ConstraintViolation unconditionally
  • com.github.benmanes.caffeine.cache.NodeFactory#FACTORY for reflection

Relates to #41995

@quarkus-bot quarkus-bot bot added the area/hibernate-orm Hibernate ORM label Jan 16, 2025
Copy link

quarkus-bot bot commented Jan 16, 2025

/cc @gsmet (hibernate-orm)

This comment has been minimized.

@zakkak zakkak force-pushed the 2025-01-16-fix-more-reflection-warnings branch from 4ee8cc6 to d34bed5 Compare January 16, 2025 19:37

This comment has been minimized.

@zakkak zakkak requested a review from gsmet January 17, 2025 06:45
Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me but let's make sure @yrodiere has a look at it before merging.

@gsmet gsmet requested a review from yrodiere January 17, 2025 14:44
Copy link
Member

@yrodiere yrodiere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

Some of the changes definitely make sense, but others are suspicious... it seems you end up having to register services that should only be retrieved during static init. I wonder if it's a case of misdetection? Or maybe these services are retrieved at runtime, even though they shouldn't be?

Comment on lines 244 to 249
// Accessed in org.hibernate.boot.beanvalidation.BeanValidationIntegrator.loadTypeSafeActivatorClass
reflectiveClasses.produce(ReflectiveClassBuildItem.builder("org.hibernate.boot.beanvalidation.TypeSafeActivator")
.methods().fields().build());
// Accessed in org.hibernate.boot.beanvalidation.BeanValidationIntegrator.isBeanValidationApiAvailable
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(BeanValidationIntegrator.JAKARTA_BV_CHECK_CLASS)
.constructors(false).build());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, we could skip this code when the HIBERNATE_VALIDATOR capability is not present:

And then we'd be able to keep the if in this method, because BeanValidationIntegrator.isBeanValidationApiAvailable wouldn't be called when the if condition is false.

Though maybe that "optimization" is not worth it, I don't know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable, but I don't know how to check if the validator capability is present.

@zakkak zakkak force-pushed the 2025-01-16-fix-more-reflection-warnings branch from d34bed5 to 4162a28 Compare January 20, 2025 07:19
@quarkus-bot quarkus-bot bot added the area/hibernate-reactive Hibernate Reactive label Jan 20, 2025
@zakkak
Copy link
Contributor Author

zakkak commented Jan 20, 2025

Thanks for the review @yrodiere. Comments addressed.

This comment has been minimized.

The class is accessed even when not using hibernate validator.

Relates to quarkusio#41995
Accessed by
`com.github.benmanes.caffeine.cache.LocalCacheFactory.newFactory`

Relates to quarkusio#41995
@yrodiere yrodiere force-pushed the 2025-01-16-fix-more-reflection-warnings branch from 4162a28 to ebab4ce Compare January 20, 2025 08:04
@yrodiere
Copy link
Member

I force-pushed a fix to the unordered imports in the first commit. Rebased on main while I was at it.

I'll try to add a commit to address the Hibernate Validator capability check.

This comment has been minimized.

@zakkak
Copy link
Contributor Author

zakkak commented Jan 20, 2025

I force-pushed a fix to the unordered imports in the first commit. Rebased on main while I was at it.

I'll try to add a commit to address the Hibernate Validator capability check.

@yrodiere It looks like we need the following patch as well:

diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
index f40a528c1d4..a6d0dce484f 100644
--- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
+++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
@@ -240,10 +240,13 @@ AdditionalIndexedClassesBuildItem addPersistenceUnitAnnotationToIndex() {
 
     @BuildStep
     public void enrollBeanValidationTypeSafeActivatorForReflection(Capabilities capabilities,
-            BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
+            BuildProducer<ReflectiveClassBuildItem> reflectiveClasses, BuildProducer<ServiceProviderBuildItem> services) {
         // Accessed in org.hibernate.boot.beanvalidation.BeanValidationIntegrator.loadTypeSafeActivatorClass
         reflectiveClasses.produce(ReflectiveClassBuildItem.builder("org.hibernate.boot.beanvalidation.TypeSafeActivator")
                 .methods().fields().build());
+        // Accessed in jakarta.validation.Validation$GetValidationProviderListAction.loadProviders through
+        // org.hibernate.boot.beanvalidation.BeanValidationIntegrator.integrate
+        services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("jakarta.validation.spi.ValidationProvider"));
         // Accessed in org.hibernate.boot.beanvalidation.BeanValidationIntegrator.isBeanValidationApiAvailable
         reflectiveClasses.produce(ReflectiveClassBuildItem.builder(BeanValidationIntegrator.JAKARTA_BV_CHECK_CLASS)
                 .constructors(false).build());

@yrodiere
Copy link
Member

I force-pushed a fix to the unordered imports in the first commit. Rebased on main while I was at it.
I'll try to add a commit to address the Hibernate Validator capability check.

@yrodiere It looks like we need the following patch as well:

diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
index f40a528c1d4..a6d0dce484f 100644
--- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
+++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java
@@ -240,10 +240,13 @@ AdditionalIndexedClassesBuildItem addPersistenceUnitAnnotationToIndex() {
 
     @BuildStep
     public void enrollBeanValidationTypeSafeActivatorForReflection(Capabilities capabilities,
-            BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
+            BuildProducer<ReflectiveClassBuildItem> reflectiveClasses, BuildProducer<ServiceProviderBuildItem> services) {
         // Accessed in org.hibernate.boot.beanvalidation.BeanValidationIntegrator.loadTypeSafeActivatorClass
         reflectiveClasses.produce(ReflectiveClassBuildItem.builder("org.hibernate.boot.beanvalidation.TypeSafeActivator")
                 .methods().fields().build());
+        // Accessed in jakarta.validation.Validation$GetValidationProviderListAction.loadProviders through
+        // org.hibernate.boot.beanvalidation.BeanValidationIntegrator.integrate
+        services.produce(ServiceProviderBuildItem.allProvidersFromClassPath("jakarta.validation.spi.ValidationProvider"));
         // Accessed in org.hibernate.boot.beanvalidation.BeanValidationIntegrator.isBeanValidationApiAvailable
         reflectiveClasses.produce(ReflectiveClassBuildItem.builder(BeanValidationIntegrator.JAKARTA_BV_CHECK_CLASS)
                 .constructors(false).build());

This looks like something that the Hibernate Validator extension itself should add, or bypass... do you have a precise stack trace?

@yrodiere
Copy link
Member

yrodiere commented Jan 20, 2025

Actually we set the validator factory explicitly here in Hibernate ORM:

if (this.validatorFactory != null) {
options.applyValidatorFactory(validatorFactory);
}

So I wouldn't expect us to rely on the Bean Validation bootstrap.

I suspect the problem you noticed is a result of adding the BeanValidationIntegrator even if the Hibernate Validator capability is not present: in that case we don't set the validator factory explicitly, so the integrator will fall back to trying to bootstrap Bean Validation the "standard way" -- and it should not.

Hopefully the commit I just pushed (which only adds the BeanValidationIntegrator when it makes sense) will solve this, without additional registrations needed.

This comment has been minimized.

@yrodiere
Copy link
Member

Alright, I've been too optimistic with my push. Will debug locally...

@yrodiere yrodiere force-pushed the 2025-01-16-fix-more-reflection-warnings branch from 6cc26fd to fd4e51a Compare January 20, 2025 13:58
@yrodiere
Copy link
Member

Alright, I've been too optimistic with my push. Will debug locally...

Done and pushed a fix. It was just a misnamed contructor parameter confusing the bytecode recording stuff...

@zakkak
Copy link
Contributor Author

zakkak commented Jan 20, 2025

Thank you @yrodiere

Hopefully the commit I just pushed (which only adds the BeanValidationIntegrator when it makes sense) will solve this, without additional registrations needed.

I confirm it does.

@zakkak zakkak added the triage/waiting-for-ci Ready to merge when CI successfully finishes label Jan 20, 2025
Copy link

quarkus-bot bot commented Jan 20, 2025

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit fd4e51a.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@zakkak zakkak merged commit e707431 into quarkusio:main Jan 21, 2025
43 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.19 - main milestone Jan 21, 2025
@zakkak zakkak deleted the 2025-01-16-fix-more-reflection-warnings branch January 21, 2025 08:28
@quarkus-bot quarkus-bot bot removed the triage/waiting-for-ci Ready to merge when CI successfully finishes label Jan 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants