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

[3.17] 3.17.3 backports 1 #44849

Merged
merged 11 commits into from
Dec 1, 2024
Merged
9 changes: 7 additions & 2 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<microprofile-lra.version>2.0</microprofile-lra.version>
<microprofile-openapi.version>4.0.2</microprofile-openapi.version>
<smallrye-common.version>2.8.0</smallrye-common.version>
<smallrye-config.version>3.10.1</smallrye-config.version>
<smallrye-config.version>3.10.2</smallrye-config.version>
<smallrye-health.version>4.1.0</smallrye-health.version>
<smallrye-metrics.version>4.0.0</smallrye-metrics.version>
<smallrye-open-api.version>4.0.3</smallrye-open-api.version>
Expand Down Expand Up @@ -89,7 +89,7 @@
<!-- GraalVM sdk 23.1.2 has a minimum JDK requirement of 17+ at runtime -->
<graal-sdk.version>23.1.2</graal-sdk.version>
<gizmo.version>1.8.0</gizmo.version>
<jackson-bom.version>2.18.1</jackson-bom.version>
<jackson-bom.version>2.18.2</jackson-bom.version>
<commons-logging-jboss-logging.version>1.0.0.Final</commons-logging-jboss-logging.version>
<commons-lang3.version>3.17.0</commons-lang3.version>
<commons-codec.version>1.17.1</commons-codec.version>
Expand Down Expand Up @@ -3463,6 +3463,11 @@
<artifactId>bcutil-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpg-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public String getId() {
}

// ConfigMapping
ConfigClass mapping = readResult.getAllMappings().get(entry.getKey());
ConfigClass mapping = readResult.getAllMappingsByClass().get(entry.getKey());
if (mapping != null) {
mappingClasses.put(entry.getValue(), mapping);
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ public Builder classes(boolean classes) {
}

public Builder classes() {
return fields(true);
return classes(true);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -628,9 +629,9 @@ ReadResult run() {
objectsByClass.put(mapping.getKlass(), config.getConfigMapping(mapping.getKlass(), mapping.getPrefix()));
}

Set<PropertyName> buildTimeNames = getMappingsNames(buildTimeMappings);
Set<PropertyName> buildTimeRunTimeNames = getMappingsNames(buildTimeRunTimeMappings);
Set<PropertyName> runTimeNames = getMappingsNames(runTimeMappings);
Set<PropertyName> buildTimeNames = mappingsToNames(buildTimeMappings).keySet();
Set<PropertyName> buildTimeRunTimeNames = mappingsToNames(buildTimeRunTimeMappings).keySet();
Set<PropertyName> runTimeNames = mappingsToNames(runTimeMappings).keySet();
for (String property : allProperties) {
PropertyName name = new PropertyName(property);
if (buildTimeNames.contains(name)) {
Expand Down Expand Up @@ -1222,12 +1223,27 @@ private static void getDefaults(
}
}

private static Set<PropertyName> getMappingsNames(final List<ConfigClass> configMappings) {
private static Map<PropertyName, String> mappingsToNames(final List<ConfigClass> configMappings) {
Set<String> names = new HashSet<>();
for (ConfigClass configMapping : configMappings) {
names.addAll(ConfigMappings.getProperties(configMapping).keySet());
}
return PropertiesUtil.toPropertyNames(names);
Map<PropertyName, String> propertyNames = new HashMap<>();
for (String name : names) {
PropertyName propertyName = new PropertyName(name);
if (propertyNames.containsKey(propertyName)) {
List<String> duplicates = new ArrayList<>();
duplicates.add(name);
while (propertyNames.containsKey(propertyName)) {
duplicates.add(propertyNames.remove(propertyName));
}
String minName = Collections.min(duplicates, Comparator.comparingInt(String::length));
propertyNames.put(new PropertyName(minName), minName);
} else {
propertyNames.put(propertyName, name);
}
}
return propertyNames;
}
}

Expand All @@ -1249,7 +1265,9 @@ public static final class ReadResult {
final List<ConfigClass> buildTimeMappings;
final List<ConfigClass> buildTimeRunTimeMappings;
final List<ConfigClass> runTimeMappings;
final Map<Class<?>, ConfigClass> allMappings;
final List<ConfigClass> allMappings;
final Map<Class<?>, ConfigClass> allMappingsByClass;
final Map<PropertyName, String> allMappingsNames;

final Set<String> unknownBuildProperties;
final Set<String> deprecatedRuntimeProperties;
Expand All @@ -1273,7 +1291,9 @@ public ReadResult(final Builder builder) {
this.buildTimeMappings = builder.getBuildTimeMappings();
this.buildTimeRunTimeMappings = builder.getBuildTimeRunTimeMappings();
this.runTimeMappings = builder.getRunTimeMappings();
this.allMappings = mappingsToMap(builder);
this.allMappings = new ArrayList<>(mappingsToMap(builder).values());
this.allMappingsByClass = mappingsToMap(builder);
this.allMappingsNames = ReadOperation.mappingsToNames(allMappings);

this.unknownBuildProperties = builder.getUnknownBuildProperties();
this.deprecatedRuntimeProperties = builder.deprecatedRuntimeProperties;
Expand Down Expand Up @@ -1355,10 +1375,18 @@ public List<ConfigClass> getRunTimeMappings() {
return runTimeMappings;
}

public Map<Class<?>, ConfigClass> getAllMappings() {
public List<ConfigClass> getAllMappings() {
return allMappings;
}

public Map<Class<?>, ConfigClass> getAllMappingsByClass() {
return allMappingsByClass;
}

public Map<PropertyName, String> getAllMappingsNames() {
return allMappingsNames;
}

public Set<String> getUnknownBuildProperties() {
return unknownBuildProperties;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
Expand Down Expand Up @@ -63,6 +64,7 @@
import io.quarkus.runtime.configuration.NameIterator;
import io.quarkus.runtime.configuration.PropertiesUtil;
import io.quarkus.runtime.configuration.QuarkusConfigFactory;
import io.smallrye.config.ConfigMappingInterface;
import io.smallrye.config.ConfigMappings;
import io.smallrye.config.ConfigMappings.ConfigClass;
import io.smallrye.config.Converters;
Expand All @@ -88,9 +90,6 @@ public final class RunTimeConfigurationGenerator {
public static final MethodDescriptor C_READ_CONFIG = MethodDescriptor.ofMethod(CONFIG_CLASS_NAME, "readConfig", void.class);

static final FieldDescriptor C_MAPPED_PROPERTIES = FieldDescriptor.of(CONFIG_CLASS_NAME, "mappedProperties", Set.class);
static final MethodDescriptor C_GENERATE_MAPPED_PROPERTIES = MethodDescriptor.ofMethod(CONFIG_CLASS_NAME,
"generateMappedProperties", Set.class);
static final MethodDescriptor PN_NEW = MethodDescriptor.ofConstructor(PropertyName.class, String.class);
static final FieldDescriptor C_UNKNOWN = FieldDescriptor.of(CONFIG_CLASS_NAME, "unknown", Set.class);
static final FieldDescriptor C_UNKNOWN_RUNTIME = FieldDescriptor.of(CONFIG_CLASS_NAME, "unknownRuntime", Set.class);

Expand Down Expand Up @@ -192,9 +191,13 @@ public final class RunTimeConfigurationGenerator {
static final MethodDescriptor PU_IS_PROPERTY_IN_ROOTS = MethodDescriptor.ofMethod(PropertiesUtil.class, "isPropertyInRoots",
boolean.class, String.class, Set.class);
static final MethodDescriptor HS_NEW = MethodDescriptor.ofConstructor(HashSet.class);
static final MethodDescriptor HS_NEW_SIZED = MethodDescriptor.ofConstructor(HashSet.class, int.class);
static final MethodDescriptor HS_ADD = MethodDescriptor.ofMethod(HashSet.class, "add", boolean.class, Object.class);
static final MethodDescriptor HS_ADD_ALL = MethodDescriptor.ofMethod(HashSet.class, "addAll", boolean.class,
Collection.class);
static final MethodDescriptor HS_CONTAINS = MethodDescriptor.ofMethod(HashSet.class, "contains", boolean.class,
Object.class);
static final MethodDescriptor PN_NEW = MethodDescriptor.ofConstructor(PropertyName.class, String.class);

// todo: more space-efficient sorted map impl
static final MethodDescriptor TM_NEW = MethodDescriptor.ofConstructor(TreeMap.class);
Expand Down Expand Up @@ -262,7 +265,6 @@ public static final class GenerateOperation implements AutoCloseable {
roots = Assert.checkNotNullParam("builder.roots", builder.getBuildTimeReadResult().getAllRoots());
additionalTypes = Assert.checkNotNullParam("additionalTypes", builder.getAdditionalTypes());
cc = ClassCreator.builder().classOutput(classOutput).className(CONFIG_CLASS_NAME).setFinal(true).build();
generateMappedProperties();
generateEmptyParsers();
// not instantiable
try (MethodCreator mc = cc.getMethodCreator(MethodDescriptor.ofConstructor(CONFIG_CLASS_NAME))) {
Expand All @@ -282,14 +284,17 @@ public static final class GenerateOperation implements AutoCloseable {
clinit.setModifiers(Opcodes.ACC_STATIC);

cc.getFieldCreator(C_MAPPED_PROPERTIES).setModifiers(Opcodes.ACC_STATIC);
clinit.writeStaticField(C_MAPPED_PROPERTIES, clinit.invokeStaticMethod(C_GENERATE_MAPPED_PROPERTIES));
clinit.writeStaticField(C_MAPPED_PROPERTIES, clinit.newInstance(HS_NEW_SIZED,
clinit.load((int) ((float) buildTimeConfigResult.getAllMappingsNames().size() / 0.75f + 1.0f))));

cc.getFieldCreator(C_UNKNOWN).setModifiers(Opcodes.ACC_STATIC);
clinit.writeStaticField(C_UNKNOWN, clinit.newInstance(HS_NEW));

cc.getFieldCreator(C_UNKNOWN_RUNTIME).setModifiers(Opcodes.ACC_STATIC);
clinit.writeStaticField(C_UNKNOWN_RUNTIME, clinit.newInstance(HS_NEW));

generateMappedProperties();

clinitNameBuilder = clinit.newInstance(SB_NEW);

// the build time config, which is for user use only (not used by us other than for loading converters)
Expand Down Expand Up @@ -1181,26 +1186,32 @@ private FieldDescriptor getOrCreateConverterInstance(Field field, ConverterType
}

private void generateMappedProperties() {
Set<String> names = new HashSet<>();
for (ConfigClass buildTimeMapping : buildTimeConfigResult.getBuildTimeMappings()) {
names.addAll(ConfigMappings.getProperties(buildTimeMapping).keySet());
}
for (ConfigClass staticConfigMapping : buildTimeConfigResult.getBuildTimeRunTimeMappings()) {
names.addAll(ConfigMappings.getProperties(staticConfigMapping).keySet());
}
for (ConfigClass runtimeConfigMapping : buildTimeConfigResult.getRunTimeMappings()) {
names.addAll(ConfigMappings.getProperties(runtimeConfigMapping).keySet());
MethodDescriptor method = MethodDescriptor.ofMethod(CONFIG_CLASS_NAME, "addMappedProperties", void.class);
MethodCreator mc = cc.getMethodCreator(method);
mc.setModifiers(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC);
for (ConfigClass mapping : buildTimeConfigResult.getAllMappings()) {
mc.invokeStaticMethod(generateMappedProperties(mapping, buildTimeConfigResult.getAllMappingsNames()));
}
Set<PropertyName> propertyNames = PropertiesUtil.toPropertyNames(names);
mc.returnVoid();
mc.close();
clinit.invokeStaticMethod(method);
}

MethodCreator mc = cc.getMethodCreator(C_GENERATE_MAPPED_PROPERTIES);
private MethodDescriptor generateMappedProperties(final ConfigClass mapping,
final Map<PropertyName, String> propertyNames) {
MethodDescriptor method = MethodDescriptor.ofMethod(CONFIG_CLASS_NAME,
"addMappedProperties$" + mapping.getKlass().getName().replace('.', '$'), void.class);
MethodCreator mc = cc.getMethodCreator(method);
mc.setModifiers(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC);
ResultHandle set = mc.newInstance(HS_NEW);
for (PropertyName propertyName : propertyNames) {
mc.invokeVirtualMethod(HS_ADD, set, mc.newInstance(PN_NEW, mc.load(propertyName.getName())));
Map<String, ConfigMappingInterface.Property> properties = ConfigMappings.getProperties(mapping);
ResultHandle set = mc.readStaticField(C_MAPPED_PROPERTIES);
for (String propertyName : properties.keySet()) {
String name = propertyNames.get(new PropertyName(propertyName));
mc.invokeVirtualMethod(HS_ADD, set, mc.newInstance(PN_NEW, mc.load(name)));
}
mc.returnValue(set);
mc.returnVoid();
mc.close();
return method;
}

private void reportUnknown(BytecodeCreator bc, ResultHandle unknownProperty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ public void accept(LogRecord logRecord, Consumer<LogRecord> logRecordConsumer) {
Object[] np = p != null ? Arrays.copyOf(p, p.length + 1) : new Object[1];
np[np.length - 1] = decoratedString;
elr.setParameters(np);
elr.setMessage(elr.getMessage() + "\n\n%" + (np.length - 1) + "$s",
elr.setMessage(elr.getMessage() + "\n\n%" + np.length + "$s",
ExtLogRecord.FormatStyle.PRINTF);
}
case NO_FORMAT -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,17 @@ public synchronized static void uninstallRedirects() {
redirectsInstalled = false;
}

private static void checkAndSetJdkConsole() {
// the JLine console in JDK 23+ causes significant startup slowdown,
// so we avoid it unless the user opted into it
String res = System.getProperty("jdk.console");
if (res == null) {
System.setProperty("jdk.console", "java.base");
}
}

public static boolean hasColorSupport() {
checkAndSetJdkConsole();
if (Boolean.getBoolean(FORCE_COLOR_SUPPORT)) {
return true; //assume the IDE run window has color support
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package io.quarkus.runtime.configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import io.smallrye.config.PropertyName;

public class PropertiesUtil {
private PropertiesUtil() {
throw new IllegalStateException("Utility class");
Expand Down Expand Up @@ -48,28 +44,4 @@ public static boolean isPropertyInRoot(final String property, final String root)
public static boolean isPropertyQuarkusCompoundName(NameIterator propertyName) {
return propertyName.getName().startsWith("\"quarkus.");
}

public static Set<PropertyName> toPropertyNames(final Set<String> names) {
Map<PropertyName, String> propertyNames = new HashMap<>();
for (String name : names) {
PropertyName propertyName = new PropertyName(name);
if (propertyNames.containsKey(propertyName)) {
String existing = propertyNames.remove(propertyName);
if (existing.length() < name.length()) {
propertyNames.put(new PropertyName(existing), existing);
} else if (existing.length() > name.length()) {
propertyNames.put(propertyName, name);
} else {
if (existing.indexOf('*') <= name.indexOf('*')) {
propertyNames.put(new PropertyName(existing), existing);
} else {
propertyNames.put(propertyName, name);
}
}
} else {
propertyNames.put(propertyName, name);
}
}
return propertyNames.keySet();
}
}
2 changes: 1 addition & 1 deletion devtools/gradle/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugin-publish = "1.3.0"

# updating Kotlin here makes QuarkusPluginTest > shouldNotFailOnProjectDependenciesWithoutMain(Path) fail
kotlin = "2.0.21"
smallrye-config = "3.10.1"
smallrye-config = "3.10.2"

junit5 = "5.10.5"
assertj = "3.26.3"
Expand Down
25 changes: 11 additions & 14 deletions docs/src/main/asciidoc/hibernate-search-orm-elasticsearch.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -627,32 +627,29 @@ Edit `src/main/resources/application.properties` and inject the following config

[source,properties]
----
quarkus.ssl.native=false <1>
quarkus.datasource.db-kind=postgresql <1>

quarkus.datasource.db-kind=postgresql <2>
quarkus.hibernate-orm.sql-load-script=import.sql <2>

quarkus.hibernate-orm.sql-load-script=import.sql <3>
quarkus.hibernate-search-orm.elasticsearch.version=8 <3>
quarkus.hibernate-search-orm.indexing.plan.synchronization.strategy=sync <4>

quarkus.hibernate-search-orm.elasticsearch.version=8 <4>
quarkus.hibernate-search-orm.indexing.plan.synchronization.strategy=sync <5>

%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost/quarkus_test <6>
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost/quarkus_test
%prod.quarkus.datasource.username=quarkus_test
%prod.quarkus.datasource.password=quarkus_test
%prod.quarkus.hibernate-orm.database.generation=create
%prod.quarkus.hibernate-search-orm.elasticsearch.hosts=localhost:9200 <6>
%prod.quarkus.hibernate-search-orm.elasticsearch.hosts=localhost:9200 <5>
----
<1> We won't use SSL, so we disable it to have a more compact native executable.
<2> Let's create a PostgreSQL datasource.
<3> We load some initial data on startup (see <<automatic-import-script>>).
<4> We need to tell Hibernate Search about the version of Elasticsearch we will use.
<1> Let's create a PostgreSQL datasource.
<2> We load some initial data on startup (see <<automatic-import-script>>).
<3> We need to tell Hibernate Search about the version of Elasticsearch we will use.
It is important because there are significant differences between Elasticsearch mapping syntax depending on the version.
Since the mapping is created at build time to reduce startup time, Hibernate Search cannot connect to the cluster to automatically detect the version.
Note that, for OpenSearch, you need to prefix the version with `opensearch:`; see <<opensearch>>.
<5> This means that we wait for the entities to be searchable before considering a write complete.
<4> This means that we wait for the entities to be searchable before considering a write complete.
On a production setup, the `write-sync` default will provide better performance.
Using `sync` is especially important when testing as you need the entities to be searchable immediately.
<6> For development and tests, we rely on <<dev-services,Dev Services>>,
<5> For development and tests, we rely on <<dev-services,Dev Services>>,
which means Quarkus will start a PostgreSQL database and Elasticsearch cluster automatically.
In production mode, however,
we will want to start a PostgreSQL database and Elasticsearch cluster manually,
Expand Down
Loading
Loading