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

Switch Hibernate ORM/Reactive/Envers extensions to @ConfigMapping #38731

Merged
merged 4 commits into from
Feb 14, 2024

Conversation

yrodiere
Copy link
Member

Fixes #38321 (I checked manually)

Three reasons for this change:

  1. As far as I can tell, the old @ConfigItem stuff is more or less deprecated. At least it's not supposed to evolve anymore.
  2. Avoid bugs like Configuration ignored when using config maps and the prefix conflicts with a "static" config group #38321 in the future. Believe me, Configuration ignored when using config maps and the prefix conflicts with a "static" config group #38321 is just one among many. I have not-so-fond memories of bugs related to names containing dots, in particular; those are supposed to work much better with @ConfigMapping.
  3. Get nicer documentation; thanks to what @radcortez did a few months ago, we no longer get duplicate entries in the config property list for the default persistence unit vs. named persistence units.

@yrodiere yrodiere requested a review from gsmet February 12, 2024 11:44
@quarkus-bot quarkus-bot bot added area/core area/hibernate-orm Hibernate ORM area/hibernate-reactive Hibernate Reactive area/persistence OBSOLETE, DO NOT USE labels Feb 12, 2024
Copy link

quarkus-bot bot commented Feb 12, 2024

/cc @gsmet (hibernate-orm)

Comment on lines +42 to +43
@WithDefault("_AUD")
Optional<String> auditTableSuffix();
Copy link
Member Author

Choose a reason for hiding this comment

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

Yes it's very weird to have defaults on Optional properties, but as you can see that was already the case before. I didn't want to go into that rabbit hole for this PR, since my changes are unrelated.

This comment has been minimized.

@yrodiere
Copy link
Member Author

Hey @zakkak , looks like native image size drifted off again... is that a new problem, or one that should be solved after a rebase? I'm really not sure why this PR would trigger this, so I assume it's also affecting main...

org.opentest4j.AssertionFailedError: Expected analysis_results.methods.reflection to be within range [4495 +- 3%] but was 4707 ==> expected: <true> but was: <false>

@gsmet
Copy link
Member

gsmet commented Feb 12, 2024

Except if @ConfigMapping creates some additional reflection entries. But let's hear from @zakkak before pinging Roberto if needed.

@zakkak
Copy link
Contributor

zakkak commented Feb 12, 2024

Except if @ConfigMapping creates some additional reflection entries. But let's hear from @zakkak before pinging Roberto if needed.

AFAIU this is exactly what's happening in

@geoand geoand requested a review from radcortez February 13, 2024 07:28
@yrodiere
Copy link
Member Author

yrodiere commented Feb 13, 2024

Still, +200 methods with reflection enabled? We don't have that many enums in that config. Unless it also enables reflection on every single method of every single configuration interface?

Let's see if @radcortez (hey!) notices something wrong in this PR or in the reflection-enabling code, and if not I'll just raise the baseline.

@zakkak
Copy link
Contributor

zakkak commented Feb 13, 2024

Still, +200 methods with reflection enabled?

FWIW The actual difference (between this PR and main) is:

  • jpa-postgresql 4707-4591= 116
  • jpa-postgresql-withxml 4893-4776 = 117

The rest of the difference is carried over from previous changes that resulted in differences < 3%.

It still seems quite a lot.

@yrodiere
Copy link
Member Author

Except if @ConfigMapping creates some additional reflection entries. But let's hear from @zakkak before pinging Roberto if needed.

AFAIU this is exactly what's happening in

Just noticed this code was taken from a "quarkus-spring" extension, which isn't relevant here.

I'll need to find the full list of methods enabled for reflection, before and after this PR. Then we can start asking ourselves if the new ones really are necessary.

@radcortez
Copy link
Member

If I remember correctly, we enable reflection on every mapping method because of Bean Validation. Most extensions don't use it, so maybe we can be smarter and only register the BVal annotations methods.

Anyway, let me confirm if this is the case and adjust.

@radcortez
Copy link
Member

Hum... BTW, we are looking into the wrong code. That code is from the old @ConfigProperties. The @ConfigMapping registration is in:

private static void processConfigClass(
ConfigClassWithPrefix configClassWithPrefix,
Kind configClassKind,
boolean isApplicationClass,
CombinedIndexBuildItem combinedIndex,
BuildProducer<GeneratedClassBuildItem> generatedClasses,
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses,
BuildProducer<ConfigClassBuildItem> configClasses) {
Class<?> configClass = configClassWithPrefix.getKlass();
String prefix = configClassWithPrefix.getPrefix();
List<ConfigMappingMetadata> configMappingsMetadata = ConfigMappingLoader.getConfigMappingsMetadata(configClass);
Set<String> generatedClassesNames = new HashSet<>();
configMappingsMetadata.forEach(mappingMetadata -> {
generatedClassesNames.add(mappingMetadata.getClassName());
// This is the generated implementation of the mapping by SmallRye Config.
generatedClasses.produce(new GeneratedClassBuildItem(isApplicationClass, mappingMetadata.getClassName(),
mappingMetadata.getClassBytes()));
// Register the interface and implementation methods for reflection. This is required for Bean Validation.
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getInterfaceType()).methods().build());
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(mappingMetadata.getClassName()).methods().build());
// Register also the interface hierarchy
for (Class<?> parent : getHierarchy(mappingMetadata.getInterfaceType())) {
reflectiveClasses.produce(ReflectiveClassBuildItem.builder(parent).methods().build());
}
processProperties(mappingMetadata.getInterfaceType(), reflectiveClasses);
});
configClasses.produce(new ConfigClassBuildItem(configClass, collectTypes(combinedIndex, configClass),
generatedClassesNames, prefix, configClassKind));
}

It even has a comment about BVal, which confirms my initial thoughts.

@gsmet
Copy link
Member

gsmet commented Feb 14, 2024

FWIW, there is a build item with all the Bean Validation annotations we detected. So we could probably check if a method has a Bean Validation annotation.

@yrodiere
Copy link
Member Author

Hum... BTW, we are looking into the wrong code

Right; see my previous comment.

It even has a comment about BVal, which confirms my initial thoughts.

I think the BV extension already registers the interfaces for reflection. And I'd expect it to register the implementations as well, it's completely its responsibility.
So I think this is some sort of workaround... Maybe mapping implementation classes are not in the Jandex index and BV "forgets" to register them? Something like that? In that case perhaps a better solution would be to make BV aware of these implementation classes... somehow.

@gsmet
Copy link
Member

gsmet commented Feb 14, 2024

For me the ConfigMapping optimization problem is orthogonal to this PR. Given the size of it and the possibility of conflicts, I would prefer we raise the threshold for now (in a separate commit) and that we create an issue with a reference to this commit, that we would revert once the problem is fixed.

If by chance, we significantly improve things, we could even lower the thresholds.

…ration

It was taken into account in ExtensionAnnotationProcessor,
but not in ConfigDocItemFinder.

Don't ask me what the difference is, or why there are two places where
we parse such annotations, but I know we did end up with
supposedly "ignored" config properties in the generated asciidoc.
Numbers for version 23.1 updated from numbers reported by the build
here: quarkusio#38731 (comment)

Numbers for version 23.0 simply incremented by the difference reported
by Foivos here: quarkusio#38731 (comment)
@radcortez
Copy link
Member

I think the BV extension already registers the interfaces for reflection. And I'd expect it to register the implementations as well, it's completely its responsibility. So I think this is some sort of workaround... Maybe mapping implementation classes are not in the Jandex index and BV "forgets" to register them? Something like that? In that case perhaps a better solution would be to make BV aware of these implementation classes... somehow.

Mappings are in Jandex, and there is a build item that carries the mapping information. We even use that in BVal, to start its own validator (to avoid circular dependencies).

In the initial implementations, I've probably added the full registration preemptively, because I knew it was going to be needed and didn't think about optimizations :)

@yrodiere
Copy link
Member Author

For me the ConfigMapping optimization problem is orthogonal to this PR. Given the size of it and the possibility of conflicts, I would prefer we raise the threshold for now (in a separate commit) and that we create an issue with a reference to this commit, that we would revert once the problem is fixed.

Right. I added a commit to update the thresholds.

Let's merge if the build passes now.

@radcortez
Copy link
Member

I've looked, and here I've changed to register the methods: https://github.com/quarkusio/quarkus/pull/12501/files#diff-26708186baae4b2358b51f3bc3c5731740eff57a0a63fb3a150d15183e817f55R214

Looking into the commit, it seems I added it to allow returning the mapping directly in a REST resource with Jackson. That is probably not required anymore. Let me remove that and see what fails and adjust.

@zakkak
Copy link
Contributor

zakkak commented Feb 14, 2024

I'll need to find the full list of methods enabled for reflection, before and after this PR. Then we can start asking ourselves if the new ones really are necessary.

FWIW to do this you can extract the reflect-config.json from the generated jar files that are passed to native-image and compare them (between main and your branch), e.g.:

unzip -j target/code-with-quarkus-1.0.0-SNAPSHOT-native-image-source-jar/code-with-quarkus-1.0.0-SNAPSHOT-runner.jar META-INF/native-image/reflect-config.json

@gsmet
Copy link
Member

gsmet commented Feb 14, 2024

If you're adding reflection solely for Bean Validation requirements, then you can drop it.
The HV extension should take care of it and if not, we need to fix the bug as it would be one.

@yrodiere yrodiere added the triage/waiting-for-ci Ready to merge when CI successfully finishes label Feb 14, 2024
Copy link

quarkus-bot bot commented Feb 14, 2024

Status for workflow Quarkus CI

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

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


Flaky tests - Develocity

⚙️ JVM Tests - JDK 17

📦 extensions/smallrye-reactive-messaging-kafka/deployment

io.quarkus.smallrye.reactivemessaging.kafka.deployment.dev.KafkaDevServicesDevModeTestCase.sseStream - History

  • Assertion condition defined as a io.quarkus.smallrye.reactivemessaging.kafka.deployment.dev.KafkaDevServicesDevModeTestCase Expecting size of: [] to be greater than or equal to 2 but was 0 within 10 seconds. - org.awaitility.core.ConditionTimeoutException
org.awaitility.core.ConditionTimeoutException: 
Assertion condition defined as a io.quarkus.smallrye.reactivemessaging.kafka.deployment.dev.KafkaDevServicesDevModeTestCase 
Expecting size of:
  []
to be greater than or equal to 2 but was 0 within 10 seconds.
	at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
	at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:119)
	at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:31)

@gastaldi gastaldi merged commit bd90be2 into quarkusio:main Feb 14, 2024
49 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.9 - main milestone Feb 14, 2024
@quarkus-bot quarkus-bot bot added kind/bugfix and removed triage/waiting-for-ci Ready to merge when CI successfully finishes labels Feb 14, 2024
@yrodiere yrodiere deleted the orm-new-config branch June 21, 2024 09:14
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.

Configuration ignored when using config maps and the prefix conflicts with a "static" config group
5 participants