Skip to content

Commit e707431

Browse files
authored
Merge pull request #45654 from zakkak/2025-01-16-fix-more-reflection-warnings
Fix unregistered element accesses when using Hibernate ORM in native mode
2 parents 625a0e2 + fd4e51a commit e707431

File tree

7 files changed

+46
-11
lines changed

7 files changed

+46
-11
lines changed

extensions/caffeine/runtime/src/main/java/io/quarkus/caffeine/runtime/graal/CacheConstructorsFeature.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ private void registerForReflection(
6666
final Constructor<?>[] z = aClass.getDeclaredConstructors();
6767
RuntimeReflection.register(aClass);
6868
RuntimeReflection.register(z);
69+
// Accessed by com.github.benmanes.caffeine.cache.LocalCacheFactory.newFactory
70+
RuntimeReflection.registerFieldLookup(aClass, "FACTORY");
6971
}
7072

7173
/**

extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/ClassNames.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,4 +465,18 @@ private static DotName createConstant(String fqcn) {
465465
"io.quarkus.hibernate.orm.deployment.HibernateUserTypeProcessor");
466466

467467
public static final DotName GRAAL_VM_FEATURES = createConstant("io.quarkus.hibernate.orm.deployment.GraalVMFeatures");
468+
469+
public static final List<DotName> SERVICE_PROVIDERS = List.of(
470+
// Accessed in org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder.<init>
471+
createConstant("org.hibernate.query.criteria.spi.CriteriaBuilderExtension"),
472+
// Accessed in io.quarkus.hibernate.orm.runtime.customized.QuarkusStrategySelectorBuilder.buildSelector
473+
createConstant("org.hibernate.boot.registry.selector.StrategyRegistrationProvider"),
474+
// Accessed in org.hibernate.internal.FastSessionServices.<init>
475+
createConstant("org.hibernate.event.spi.EventManager"),
476+
// Accessed in org.hibernate.query.internal.QueryEngineImpl.sortedFunctionContributors
477+
createConstant("org.hibernate.boot.model.FunctionContributor"),
478+
// Accessed in org.hibernate.event.spi.EventEngine.<init>
479+
createConstant("org.hibernate.event.spi.EventEngineContributor"),
480+
// Accessed in org.hibernate.service.internal.SessionFactoryServiceRegistryFactoryImpl.buildServiceRegistry
481+
createConstant("org.hibernate.service.spi.SessionFactoryServiceContributor"));
468482
}

extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem;
105105
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
106106
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
107+
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
107108
import io.quarkus.deployment.index.IndexingUtil;
108109
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
109110
import io.quarkus.deployment.recording.RecorderContext;
@@ -163,7 +164,11 @@ public final class HibernateOrmProcessor {
163164
private static final String INTEGRATOR_SERVICE_FILE = "META-INF/services/org.hibernate.integrator.spi.Integrator";
164165

165166
@BuildStep
166-
NativeImageFeatureBuildItem registerServicesForReflection() {
167+
NativeImageFeatureBuildItem registerServicesForReflection(BuildProducer<ServiceProviderBuildItem> services) {
168+
for (DotName serviceProvider : ClassNames.SERVICE_PROVIDERS) {
169+
services.produce(ServiceProviderBuildItem.allProvidersFromClassPath(serviceProvider.toString()));
170+
}
171+
167172
return new NativeImageFeatureBuildItem(RegisterServicesForReflectionFeature.class);
168173
}
169174

@@ -237,8 +242,12 @@ AdditionalIndexedClassesBuildItem addPersistenceUnitAnnotationToIndex() {
237242
public void enrollBeanValidationTypeSafeActivatorForReflection(Capabilities capabilities,
238243
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
239244
if (capabilities.isPresent(Capability.HIBERNATE_VALIDATOR)) {
245+
// BeanValidationIntegrator is only added if this capability is present, see FastBootMetadataBuilder
246+
247+
// Accessed in org.hibernate.boot.beanvalidation.BeanValidationIntegrator.loadTypeSafeActivatorClass
240248
reflectiveClasses.produce(ReflectiveClassBuildItem.builder("org.hibernate.boot.beanvalidation.TypeSafeActivator")
241249
.methods().fields().build());
250+
// Accessed in org.hibernate.boot.beanvalidation.BeanValidationIntegrator.isBeanValidationApiAvailable
242251
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(BeanValidationIntegrator.JAKARTA_BV_CHECK_CLASS)
243252
.constructors(false).build());
244253
}

extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/PersistenceUnitDescriptorBuildItem.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public final class PersistenceUnitDescriptorBuildItem extends MultiBuildItem {
2929
private final List<RecordableXmlMapping> xmlMappings;
3030
private final boolean isReactive;
3131
private final boolean fromPersistenceXml;
32+
private final boolean isHibernateValidatorPresent;
3233
private final Optional<FormatMapperKind> jsonMapper;
3334
private final Optional<FormatMapperKind> xmlMapper;
3435

@@ -43,6 +44,7 @@ public PersistenceUnitDescriptorBuildItem(QuarkusPersistenceUnitDescriptor descr
4344
this.xmlMappings = xmlMappings;
4445
this.isReactive = isReactive;
4546
this.fromPersistenceXml = fromPersistenceXml;
47+
this.isHibernateValidatorPresent = capabilities.isPresent(Capability.HIBERNATE_VALIDATOR);
4648
this.jsonMapper = json(capabilities);
4749
this.xmlMapper = xml(capabilities);
4850
}
@@ -79,10 +81,15 @@ public boolean isFromPersistenceXml() {
7981
return fromPersistenceXml;
8082
}
8183

84+
public boolean isHibernateValidatorPresent() {
85+
return isHibernateValidatorPresent;
86+
}
87+
8288
public QuarkusPersistenceUnitDefinition asOutputPersistenceUnitDefinition(
8389
List<HibernateOrmIntegrationStaticDescriptor> integrationStaticDescriptors) {
8490
return new QuarkusPersistenceUnitDefinition(descriptor, config,
85-
xmlMappings, isReactive, fromPersistenceXml, jsonMapper, xmlMapper, integrationStaticDescriptors);
91+
xmlMappings, isReactive, fromPersistenceXml, isHibernateValidatorPresent,
92+
jsonMapper, xmlMapper, integrationStaticDescriptors);
8693
}
8794

8895
private Optional<FormatMapperKind> json(Capabilities capabilities) {

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/FastBootMetadataBuilder.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ public class FastBootMetadataBuilder {
111111
private final MultiTenancyStrategy multiTenancyStrategy;
112112
private final boolean isReactive;
113113
private final boolean fromPersistenceXml;
114+
private final boolean isHibernateValidatorPresent;
114115
private final List<HibernateOrmIntegrationStaticDescriptor> integrationStaticDescriptors;
115116

116117
@SuppressWarnings("unchecked")
@@ -119,6 +120,7 @@ public FastBootMetadataBuilder(final QuarkusPersistenceUnitDefinition puDefiniti
119120
this.persistenceUnit = puDefinition.getPersistenceUnitDescriptor();
120121
this.isReactive = puDefinition.isReactive();
121122
this.fromPersistenceXml = puDefinition.isFromPersistenceXml();
123+
this.isHibernateValidatorPresent = puDefinition.isHibernateValidatorPresent();
122124
this.additionalIntegrators = additionalIntegrators;
123125
this.preGeneratedProxies = preGeneratedProxies;
124126
this.integrationStaticDescriptors = puDefinition.getIntegrationStaticDescriptors();
@@ -476,7 +478,9 @@ private Dialect extractDialect() {
476478

477479
private Collection<Integrator> getIntegrators() {
478480
LinkedHashSet<Integrator> integrators = new LinkedHashSet<>();
479-
integrators.add(new BeanValidationIntegrator());
481+
if (isHibernateValidatorPresent) {
482+
integrators.add(new BeanValidationIntegrator());
483+
}
480484
integrators.add(new CollectionCacheInvalidator());
481485

482486
for (Class<? extends Integrator> integratorClass : additionalIntegrators) {

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/QuarkusPersistenceUnitDefinition.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public final class QuarkusPersistenceUnitDefinition {
2121
private final List<RecordableXmlMapping> xmlMappings;
2222
private final boolean isReactive;
2323
private final boolean fromPersistenceXml;
24+
private final boolean isHibernateValidatorPresent;
2425
private final Optional<FormatMapperKind> jsonMapperCreator;
2526
private final Optional<FormatMapperKind> xmlMapperCreator;
2627
private final List<HibernateOrmIntegrationStaticDescriptor> integrationStaticDescriptors;
@@ -31,6 +32,7 @@ public QuarkusPersistenceUnitDefinition(QuarkusPersistenceUnitDescriptor persist
3132
List<RecordableXmlMapping> xmlMappings,
3233
boolean reactive,
3334
boolean fromPersistenceXml,
35+
boolean hibernateValidatorPresent,
3436
Optional<FormatMapperKind> jsonMapperCreator,
3537
Optional<FormatMapperKind> xmlMapperCreator,
3638
List<HibernateOrmIntegrationStaticDescriptor> integrationStaticDescriptors) {
@@ -41,6 +43,7 @@ public QuarkusPersistenceUnitDefinition(QuarkusPersistenceUnitDescriptor persist
4143
this.xmlMappings = xmlMappings;
4244
this.isReactive = reactive;
4345
this.fromPersistenceXml = fromPersistenceXml;
46+
this.isHibernateValidatorPresent = hibernateValidatorPresent;
4447
this.jsonMapperCreator = jsonMapperCreator;
4548
this.xmlMapperCreator = xmlMapperCreator;
4649
this.integrationStaticDescriptors = integrationStaticDescriptors;
@@ -71,6 +74,10 @@ public boolean isFromPersistenceXml() {
7174
return fromPersistenceXml;
7275
}
7376

77+
public boolean isHibernateValidatorPresent() {
78+
return isHibernateValidatorPresent;
79+
}
80+
7481
public Optional<FormatMapperKind> getJsonMapperCreator() {
7582
return jsonMapperCreator;
7683
}

extensions/hibernate-reactive/deployment/src/main/java/io/quarkus/hibernate/reactive/deployment/HibernateReactiveProcessor.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
5555
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
5656
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
57-
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
5857
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
5958
import io.quarkus.deployment.recording.RecorderContext;
6059
import io.quarkus.hibernate.orm.deployment.HibernateConfigUtil;
@@ -117,13 +116,6 @@ void reflections(BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
117116
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, REFLECTIVE_CONSTRUCTORS_NEEDED));
118117
}
119118

120-
@BuildStep
121-
void services(BuildProducer<ServiceProviderBuildItem> producer) {
122-
producer.produce(
123-
new ServiceProviderBuildItem(org.hibernate.service.spi.SessionFactoryServiceContributor.class.getName(),
124-
org.hibernate.reactive.service.internal.ReactiveSessionFactoryServiceContributor.class.getName()));
125-
}
126-
127119
@BuildStep
128120
@Record(STATIC_INIT)
129121
public void build(RecorderContext recorderContext,

0 commit comments

Comments
 (0)