diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 7ffe773060c4f..9df0e488cf3af 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -184,6 +184,7 @@ updates:
- dependency-name: biz.paluch.logging:logstash-gelf
- dependency-name: org.bitbucket.b_c:jose4j
- dependency-name: io.fabric8:maven-model-helper
+ - dependency-name: org.codejive:java-properties
ignore:
# this one cannot be upgraded due to the usage of proxies in new versions
# the proxy implements interfaces in a random order which causes issues
diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml
index ec0ced15ae954..7aaec6dcc712a 100644
--- a/.mvn/extensions.xml
+++ b/.mvn/extensions.xml
@@ -17,6 +17,6 @@
io.quarkus.develocity
quarkus-project-develocity-extension
- 1.1.1
+ 1.1.3
diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 7ada2a259ee04..a7a94b2848cd4 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -92,14 +92,14 @@
23.1.2
1.8.0
- 2.17.1
+ 2.17.2
1.0.0.Final
3.14.0
1.17.0
1.7.0
- 7.0.1.Final
+ 7.0.2.Final
2.4
8.0.0.Final
8.14.0
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/filesystem/StaticFileManager.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/filesystem/StaticFileManager.java
index d3706c1e133e5..acfad17471237 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/dev/filesystem/StaticFileManager.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/filesystem/StaticFileManager.java
@@ -31,8 +31,9 @@ public Iterable extends JavaFileObject> getJavaSources(Iterable extends File
@Override
public JavaFileObject getJavaFileForInput(Location location, String className, JavaFileObject.Kind kind)
throws IOException {
+ JavaFileObject file = this.fileManager.getJavaFileForInput(location, className, kind);
// Ignore the module info of the application in dev mode.
- if (context.ignoreModuleInfo() && "CLASS_OUTPUT".equalsIgnoreCase(location.getName())
+ if (file != null && context.ignoreModuleInfo() && "CLASS_OUTPUT".equalsIgnoreCase(location.getName())
&& "module-info".equalsIgnoreCase(className)) {
if (once.compareAndSet(false, true)) {
Logger.getLogger(StaticFileManager.class).info("Ignoring module-info.java in dev mode, " +
@@ -40,7 +41,7 @@ public JavaFileObject getJavaFileForInput(Location location, String className, J
}
return null;
}
- return this.fileManager.getJavaFileForInput(location, className, kind);
+ return file;
}
}
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java b/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java
index 651d21b79eddc..91b33a0756886 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java
@@ -1235,9 +1235,16 @@ public void prepare(MethodContext context) {
public void handle(MethodContext context, MethodCreator method,
DeferredArrayStoreParameter out) {
//get the collection
- ResultHandle prop = method.invokeVirtualMethod(
- MethodDescriptor.ofMethod(i.getReadMethod()),
- context.loadDeferred(out));
+ ResultHandle prop;
+ if (i.getReadMethod().isDefault()) {
+ prop = method.invokeInterfaceMethod(
+ MethodDescriptor.ofMethod(i.getReadMethod()),
+ context.loadDeferred(out));
+ } else {
+ prop = method.invokeVirtualMethod(
+ MethodDescriptor.ofMethod(i.getReadMethod()),
+ context.loadDeferred(out));
+ }
for (DeferredParameter i : params) {
//add the parameter
//TODO: this is not guarded against large collections, probably not an issue in practice
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageConfigBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageConfigBuildStep.java
index 2ac0440ee5137..a7507d0538468 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageConfigBuildStep.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageConfigBuildStep.java
@@ -102,6 +102,7 @@ void reinitHostNameUtil(BuildProducer runtim
// so we reinitialize this to re-compute the field (and other related fields) during native application's
// runtime
runtimeReInitClass.produce(new RuntimeReinitializedClassBuildItem("org.wildfly.common.net.HostName"));
+ runtimeReInitClass.produce(new RuntimeReinitializedClassBuildItem("io.smallrye.common.net.HostName"));
}
private Boolean isSslNativeEnabled(SslNativeConfigBuildItem sslNativeConfig,
diff --git a/docs/src/main/asciidoc/cdi-integration.adoc b/docs/src/main/asciidoc/cdi-integration.adoc
index 0ff90a1fb144a..f6775181e5a64 100644
--- a/docs/src/main/asciidoc/cdi-integration.adoc
+++ b/docs/src/main/asciidoc/cdi-integration.adoc
@@ -76,7 +76,7 @@ IMPORTANT: It is not possible to conditionally enable/disable additional beans v
----
@BuildStep
AdditionalBeanBuildItem additionalBeans() {
- return new AdditionalBeanBuildItem(SmallRyeHealthReporter.class, HealthServlet.class)); <1>
+ return new AdditionalBeanBuildItem(SmallRyeHealthReporter.class, HealthServlet.class); <1>
}
----
<1> `AdditionalBeanBuildItem.Builder` can be used for more complex use cases.
diff --git a/docs/src/main/asciidoc/security-customization.adoc b/docs/src/main/asciidoc/security-customization.adoc
index 5a0ee041e6672..b42ce570911ed 100644
--- a/docs/src/main/asciidoc/security-customization.adoc
+++ b/docs/src/main/asciidoc/security-customization.adoc
@@ -682,7 +682,7 @@ The observers can be either synchronous or asynchronous.
* `io.quarkus.oidc.SecurityEvent`
* `io.quarkus.vertx.http.runtime.security.FormAuthenticationEvent`
-[[TIP]]
+[TIP]
For more information about security events specific to the Quarkus OpenID Connect extension, please see
the xref:security-oidc-code-flow-authentication.adoc#listen-to-authentication-events[Listening to important authentication events]
section of the OIDC code flow mechanism for protecting web applications guide.
diff --git a/docs/src/main/asciidoc/security-keycloak-authorization.adoc b/docs/src/main/asciidoc/security-keycloak-authorization.adoc
index 94d844883ebc9..a4d34e1407fd5 100644
--- a/docs/src/main/asciidoc/security-keycloak-authorization.adoc
+++ b/docs/src/main/asciidoc/security-keycloak-authorization.adoc
@@ -226,7 +226,7 @@ To start a Keycloak server, use the following Docker command:
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8543:8443 -v "$(pwd)"/config/keycloak-keystore.jks:/etc/keycloak-keystore.jks quay.io/keycloak/keycloak:{keycloak.version} start --hostname-strict=false --https-key-store-file=/etc/keycloak-keystore.jks
----
-where `keycloak.version` must be `23.0.0` or later and the `keycloak-keystore.jks` can be found in https://github.com/quarkusio/quarkus-quickstarts/blob/main/security-keycloak-authorization-quickstart/config/keycloak-keystore.jks[quarkus-quickstarts/security-keycloak-authorization-quickstart/config].
+where `keycloak.version` must be `25.0.0` or later and the `keycloak-keystore.jks` can be found in https://github.com/quarkusio/quarkus-quickstarts/blob/main/security-keycloak-authorization-quickstart/config/keycloak-keystore.jks[quarkus-quickstarts/security-keycloak-authorization-quickstart/config].
Try to access your Keycloak server at https://localhost:8543[localhost:8543].
diff --git a/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc
index 6e1ffbb1d991f..6fe1d7753f41e 100644
--- a/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc
+++ b/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc
@@ -689,7 +689,7 @@ quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com
which is all what is needed for the OIDC `service` application to fetch Auth0 public verification keys and use them to verify Auth0 access tokens in JWT format.
-[[NOTE]]
+[NOTE]
====
In this tutorial you have already configured the OIDC `hybrid` application which can handle both authorization code and bearer token authentication flows. In production you will run microservices as separate servers but for the sake of simplicity `ApiEchoService` will not have to be started as a second server with its own configuration containing `quarkus.oidc.auth-server-url=https://dev-3ve0cgn7.us.auth0.com` only, and therefore the current configuration which already has the Auth0 dev tenant address configured will be reused.
diff --git a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc
index 67717da4065b1..c4a6a64a9a0e3 100644
--- a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc
+++ b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc
@@ -217,7 +217,7 @@ For more information, see the <> section.
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
----
====
-* Where the `keycloak.version` is set to version `23.0.0` or later.
+* Where the `keycloak.version` is set to version `25.0.0` or later.
. You can access your Keycloak server at http://localhost:8180[localhost:8180].
. To access the Keycloak Administration console, log in as the `admin` user by using the following login credentials:
diff --git a/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc
index 63d99eab3b2fc..f47b743a12086 100644
--- a/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc
+++ b/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc
@@ -201,7 +201,7 @@ To start a Keycloak server, use Docker and run the following command:
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
----
-where `keycloak.version` is set to `23.0.0` or later.
+where `keycloak.version` is set to `25.0.0` or later.
You can access your Keycloak Server at http://localhost:8180[localhost:8180].
diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc
index 9876031aee273..d279a870375c0 100644
--- a/docs/src/main/asciidoc/security-openid-connect-client.adoc
+++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc
@@ -535,7 +535,7 @@ To start a Keycloak Server, you can use Docker and just run the following comman
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
----
-Set `{keycloak.version}` to `23.0.0` or later.
+Set `{keycloak.version}` to `25.0.0` or later.
You can access your Keycloak Server at http://localhost:8180[localhost:8180].
diff --git a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc
index 0cca72b4f7dad..d031ecdcd0071 100644
--- a/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc
+++ b/docs/src/main/asciidoc/security-openid-connect-multitenancy.adoc
@@ -351,7 +351,7 @@ To start a Keycloak server, you can use Docker and run the following command:
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
----
-where `keycloak.version` is set to `23.0.0` or higher.
+where `keycloak.version` is set to `25.0.0` or higher.
Access your Keycloak server at http://localhost:8180[localhost:8180].
diff --git a/docs/src/main/asciidoc/telemetry-micrometer.adoc b/docs/src/main/asciidoc/telemetry-micrometer.adoc
index c986d7b46c186..a61966fa16d76 100644
--- a/docs/src/main/asciidoc/telemetry-micrometer.adoc
+++ b/docs/src/main/asciidoc/telemetry-micrometer.adoc
@@ -179,7 +179,7 @@ Given the following declaration of a timer: `registry.timer("http.server.request
=== Define dimensions for aggregation
Metrics, single numerical measurements, often have additional data captured with them. This ancillary data is used to group or aggregate metrics for analysis.
-The Micrometer API refers to this dimensional data as tags, but you may it referred to as "labels" or "attributes" in other documentation sources.
+The Micrometer API refers to this dimensional data as tags, but you may see it referred to as "labels" or "attributes" in other documentation sources.
Micrometer is built primariliy for backend monitoring systems that support dimensional data (metric names that are enchriched with key/value pairs).
For heirarchical systems that only support a flat metric name, Micrometer will flatten the set of key/value pairs (sorted by key) and add them to the name.
diff --git a/docs/src/main/java/io/quarkus/docs/generation/AssembleDownstreamDocumentation.java b/docs/src/main/java/io/quarkus/docs/generation/AssembleDownstreamDocumentation.java
index 6f23fd809cd4c..2a88d1d2b106c 100755
--- a/docs/src/main/java/io/quarkus/docs/generation/AssembleDownstreamDocumentation.java
+++ b/docs/src/main/java/io/quarkus/docs/generation/AssembleDownstreamDocumentation.java
@@ -426,7 +426,7 @@ private static String rewriteContent(String fileName,
addError(errors, fileName, "Unable to find title for: " + mr.group() + " [" + reference + "]");
title = "~~ unknown title ~~";
}
- return "xref:" + trimReference(mr.group(1)) + "[" + title.trim() + "]";
+ return "xref:" + trimReference(mr.group(1)) + "[" + escapeXrefTitleForReplaceAll(title) + "]";
});
content = ANGLE_BRACKETS_WITHOUT_DESCRIPTION_PATTERN.matcher(content).replaceAll(mr -> {
@@ -436,11 +436,11 @@ private static String rewriteContent(String fileName,
addError(errors, fileName, "Unable to find title for: " + mr.group() + " [" + reference + "]");
title = "~~ unknown title ~~";
}
- return "xref:" + trimReference(mr.group(1)) + "[" + title.trim() + "]";
+ return "xref:" + trimReference(mr.group(1)) + "[" + escapeXrefTitleForReplaceAll(title) + "]";
});
content = ANGLE_BRACKETS_WITH_DESCRIPTION_PATTERN.matcher(content).replaceAll(mr -> {
- return "xref:" + trimReference(mr.group(1)) + "[" + mr.group(2).trim() + "]";
+ return "xref:" + trimReference(mr.group(1)) + "[" + escapeXrefTitleForReplaceAll(mr.group(2)) + "]";
});
content = XREF_GUIDE_PATTERN.matcher(content).replaceAll(mr -> {
@@ -466,6 +466,10 @@ private static String rewriteContent(String fileName,
return content;
}
+ private static String escapeXrefTitleForReplaceAll(String title) {
+ return title.trim().replace("]", "\\\\]");
+ }
+
private static String trimReference(String reference) {
reference = normalizeAdoc(reference);
diff --git a/extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/gradle.properties b/extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/gradle.properties
index 644310c2b3a94..c77b7693b0052 100644
--- a/extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/gradle.properties
+++ b/extensions/amazon-lambda/maven-archetype/src/main/resources/archetype-resources/gradle.properties
@@ -1,5 +1,5 @@
-#Gradle properties
-#Tue Mar 17 10:20:48 UTC 2020
+# Gradle properties
+
quarkusPluginVersion=${project.version}
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformVersion=${project.version}
diff --git a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheResultInterceptor.java b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheResultInterceptor.java
index f635d965a518e..f16d6674ee7ed 100644
--- a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheResultInterceptor.java
+++ b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheResultInterceptor.java
@@ -1,7 +1,6 @@
package io.quarkus.cache.runtime;
import java.time.Duration;
-import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -17,10 +16,6 @@
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.TimeoutException;
import io.smallrye.mutiny.Uni;
-import io.vertx.core.Context;
-import io.vertx.core.Handler;
-import io.vertx.core.Vertx;
-import io.vertx.core.impl.ContextInternal;
@CacheResult(cacheName = "") // The `cacheName` attribute is @Nonbinding.
@Interceptor
@@ -58,7 +53,6 @@ public Object intercept(InvocationContext invocationContext) throws Throwable {
try {
ReturnType returnType = determineReturnType(invocationContext.getMethod().getReturnType());
if (returnType != ReturnType.NonAsync) {
- Context context = Vertx.currentContext();
Uni cacheValue = cache.getAsync(key, new Function>() {
@SuppressWarnings("unchecked")
@Override
@@ -76,48 +70,6 @@ public Uni apply(Object key) {
public Uni> apply(Throwable throwable) {
return cache.invalidate(key).replaceWith(throwable);
}
- }).emitOn(new Executor() {
- // We need make sure we go back to the original context when the cache value is computed.
- // Otherwise, we would always emit on the context having computed the value, which could
- // break the duplicated context isolation.
- @Override
- public void execute(Runnable command) {
- Context ctx = Vertx.currentContext();
- if (context == null) {
- // We didn't capture a context
- if (ctx == null) {
- // We are not on a context => we can execute immediately.
- command.run();
- } else {
- // We are on a context.
- // We cannot continue on the current context as we may share a duplicated context.
- // We need a new one. Note that duplicate() does not duplicate the duplicated context,
- // but the root context.
- ((ContextInternal) ctx).duplicate()
- .runOnContext(new Handler() {
- @Override
- public void handle(Void ignored) {
- command.run();
- }
- });
- }
- } else {
- // We captured a context.
- if (ctx == context) {
- // We are on the same context => we can execute immediately
- command.run();
- } else {
- // 1) We are not on a context (ctx == null) => we need to switch to the captured context.
- // 2) We are on a different context (ctx != null) => we need to switch to the captured context.
- context.runOnContext(new Handler() {
- @Override
- public void handle(Void ignored) {
- command.run();
- }
- });
- }
- }
- }
});
if (binding.lockTimeout() <= 0) {
diff --git a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheImpl.java b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheImpl.java
index dff31eb8dab1e..278c1ebc3ab15 100644
--- a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheImpl.java
+++ b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheImpl.java
@@ -8,6 +8,7 @@
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
@@ -26,6 +27,10 @@
import io.quarkus.cache.runtime.AbstractCache;
import io.quarkus.cache.runtime.NullValueConverter;
import io.smallrye.mutiny.Uni;
+import io.vertx.core.Context;
+import io.vertx.core.Handler;
+import io.vertx.core.Vertx;
+import io.vertx.core.impl.ContextInternal;
/**
* This class is an internal Quarkus cache implementation using Caffeine. Do not use it explicitly from your Quarkus
@@ -99,6 +104,7 @@ public CompletionStage get() {
@Override
public Uni getAsync(K key, Function> valueLoader) {
Objects.requireNonNull(key, NULL_KEYS_NOT_SUPPORTED_MSG);
+ Context context = Vertx.currentContext();
return Uni.createFrom()
.completionStage(new Supplier>() {
@Override
@@ -119,7 +125,51 @@ public CompletableFuture apply(Object key) {
recorder.doRecord(key);
return result;
}
- }).map(fromCacheValue());
+ })
+ .map(fromCacheValue())
+ .emitOn(new Executor() {
+ // We need make sure we go back to the original context when the cache value is computed.
+ // Otherwise, we would always emit on the context having computed the value, which could
+ // break the duplicated context isolation.
+ @Override
+ public void execute(Runnable command) {
+ Context ctx = Vertx.currentContext();
+ if (context == null) {
+ // We didn't capture a context
+ if (ctx == null) {
+ // We are not on a context => we can execute immediately.
+ command.run();
+ } else {
+ // We are on a context.
+ // We cannot continue on the current context as we may share a duplicated context.
+ // We need a new one. Note that duplicate() does not duplicate the duplicated context,
+ // but the root context.
+ ((ContextInternal) ctx).duplicate()
+ .runOnContext(new Handler() {
+ @Override
+ public void handle(Void ignored) {
+ command.run();
+ }
+ });
+ }
+ } else {
+ // We captured a context.
+ if (ctx == context) {
+ // We are on the same context => we can execute immediately
+ command.run();
+ } else {
+ // 1) We are not on a context (ctx == null) => we need to switch to the captured context.
+ // 2) We are on a different context (ctx != null) => we need to switch to the captured context.
+ context.runOnContext(new Handler() {
+ @Override
+ public void handle(Void ignored) {
+ command.run();
+ }
+ });
+ }
+ }
+ }
+ });
}
@Override
diff --git a/extensions/hibernate-search-standalone-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/standalone/elasticsearch/runtime/HibernateSearchStandaloneBuildTimeConfig.java b/extensions/hibernate-search-standalone-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/standalone/elasticsearch/runtime/HibernateSearchStandaloneBuildTimeConfig.java
index 8ef6845e7aa04..fc3de18ff9b91 100644
--- a/extensions/hibernate-search-standalone-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/standalone/elasticsearch/runtime/HibernateSearchStandaloneBuildTimeConfig.java
+++ b/extensions/hibernate-search-standalone-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/standalone/elasticsearch/runtime/HibernateSearchStandaloneBuildTimeConfig.java
@@ -269,7 +269,7 @@ interface MappingConfig {
* Associations between entities must be bi-directional:
* specifying the inverse side of associations through `@AssociationInverseSide` *is required*,
* unless reindexing is disabled for that association through `@IndexingDependency(reindexOnUpdate = ...)`.
- * `tree`::
+ * `document`::
* Entities indexed through Hibernate Search are the root of a document,
* i.e. an indexed entity "owns" other entities it references through associations,
* which *cannot* be updated independently of the indexed entity.
diff --git a/extensions/infinispan-cache/runtime/src/main/java/io/quarkus/cache/infinispan/runtime/InfinispanCacheImpl.java b/extensions/infinispan-cache/runtime/src/main/java/io/quarkus/cache/infinispan/runtime/InfinispanCacheImpl.java
index a92f6f4e70fd7..cc0ea14720eb6 100644
--- a/extensions/infinispan-cache/runtime/src/main/java/io/quarkus/cache/infinispan/runtime/InfinispanCacheImpl.java
+++ b/extensions/infinispan-cache/runtime/src/main/java/io/quarkus/cache/infinispan/runtime/InfinispanCacheImpl.java
@@ -5,6 +5,7 @@
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
import java.util.concurrent.Flow;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@@ -24,6 +25,10 @@
import io.quarkus.infinispan.client.runtime.InfinispanClientUtil;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
+import io.vertx.core.Context;
+import io.vertx.core.Handler;
+import io.vertx.core.Vertx;
+import io.vertx.core.impl.ContextInternal;
/**
* This class is an internal Quarkus cache implementation using Infinispan.
@@ -111,6 +116,8 @@ public Uni get(K key, Function valueLoader) {
@Override
public Uni getAsync(K key, Function> valueLoader) {
+ Context context = Vertx.currentContext();
+
return Uni.createFrom().completionStage(CompletionStages.handleAndCompose(remoteCache.getAsync(key), (v1, ex1) -> {
if (ex1 != null) {
return CompletableFuture.failedFuture(ex1);
@@ -145,7 +152,49 @@ public Uni getAsync(K key, Function> valueLoader) {
}
});
return resultAsync;
- }));
+ })).emitOn(new Executor() {
+ // We need make sure we go back to the original context when the cache value is computed.
+ // Otherwise, we would always emit on the context having computed the value, which could
+ // break the duplicated context isolation.
+ @Override
+ public void execute(Runnable command) {
+ Context ctx = Vertx.currentContext();
+ if (context == null) {
+ // We didn't capture a context
+ if (ctx == null) {
+ // We are not on a context => we can execute immediately.
+ command.run();
+ } else {
+ // We are on a context.
+ // We cannot continue on the current context as we may share a duplicated context.
+ // We need a new one. Note that duplicate() does not duplicate the duplicated context,
+ // but the root context.
+ ((ContextInternal) ctx).duplicate()
+ .runOnContext(new Handler() {
+ @Override
+ public void handle(Void ignored) {
+ command.run();
+ }
+ });
+ }
+ } else {
+ // We captured a context.
+ if (ctx == context) {
+ // We are on the same context => we can execute immediately
+ command.run();
+ } else {
+ // 1) We are not on a context (ctx == null) => we need to switch to the captured context.
+ // 2) We are on a different context (ctx != null) => we need to switch to the captured context.
+ context.runOnContext(new Handler() {
+ @Override
+ public void handle(Void ignored) {
+ command.run();
+ }
+ });
+ }
+ }
+ }
+ });
}
@Override
diff --git a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanDevServicesConfig.java b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanDevServicesConfig.java
index 1a2a55c4a637e..5296d468953d6 100644
--- a/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanDevServicesConfig.java
+++ b/extensions/infinispan-client/runtime/src/main/java/io/quarkus/infinispan/client/runtime/InfinispanDevServicesConfig.java
@@ -148,7 +148,7 @@ public boolean equals(Object o) {
Objects.equals(shared, that.shared) &&
Objects.equals(serviceName, that.serviceName) &&
Objects.equals(imageName, that.imageName) &&
- Objects.equals(artifacts, this.artifacts) &&
+ Objects.equals(artifacts, that.artifacts) &&
Objects.equals(containerEnv, that.containerEnv);
}
diff --git a/extensions/jackson/deployment/src/main/java/io/quarkus/jackson/deployment/JacksonProcessor.java b/extensions/jackson/deployment/src/main/java/io/quarkus/jackson/deployment/JacksonProcessor.java
index d7e1b79843231..5460754feb9cf 100644
--- a/extensions/jackson/deployment/src/main/java/io/quarkus/jackson/deployment/JacksonProcessor.java
+++ b/extensions/jackson/deployment/src/main/java/io/quarkus/jackson/deployment/JacksonProcessor.java
@@ -34,6 +34,7 @@
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -83,6 +84,7 @@ public class JacksonProcessor {
private static final DotName JSON_TYPE_ID_RESOLVER = DotName.createSimple(JsonTypeIdResolver.class.getName());
private static final DotName JSON_SUBTYPES = DotName.createSimple(JsonSubTypes.class.getName());
+ private static final DotName JACKSON_NAMING = DotName.createSimple(JsonNaming.class.getName());
private static final DotName JSON_CREATOR = DotName.createSimple("com.fasterxml.jackson.annotation.JsonCreator");
private static final DotName JSON_NAMING = DotName.createSimple("com.fasterxml.jackson.databind.annotation.JsonNaming");
@@ -298,6 +300,18 @@ void register(
.methods().fields().build());
}
+ // register @JsonNaming for reflection
+ Set namingTypesNames = new HashSet<>();
+ for (AnnotationInstance namingInstance : index.getAnnotations(JSON_NAMING)) {
+ AnnotationValue namingValue = namingInstance.value();
+ if (namingValue != null) {
+ namingTypesNames.add(namingValue.asClass().name().toString());
+ }
+ }
+ if (!namingTypesNames.isEmpty()) {
+ reflectiveClass.produce(ReflectiveClassBuildItem.builder(namingTypesNames.toArray(EMPTY_STRING)).build());
+ }
+
// this needs to be registered manually since the runtime module is not indexed by Jandex
additionalBeans.produce(new AdditionalBeanBuildItem(ObjectMapperProducer.class));
}
diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToKnativeConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToKnativeConfig.java
index bb89510d27d3a..6a5cd38ce4d8e 100644
--- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToKnativeConfig.java
+++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToKnativeConfig.java
@@ -29,7 +29,7 @@ public void visit(KnativeConfigFluent> config) {
*/
private boolean hasPort(KnativeConfigFluent> config) {
for (Port p : config.buildPorts()) {
- if (p.getContainerPort() == port.getContainerPort()) {
+ if (Objects.equals(p.getContainerPort(), port.getContainerPort())) {
return true;
}
}
diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToKubernetesConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToKubernetesConfig.java
index c2305c8227fc6..13ac4c240335c 100644
--- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToKubernetesConfig.java
+++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToKubernetesConfig.java
@@ -29,7 +29,7 @@ public void visit(KubernetesConfigFluent> config) {
*/
private boolean hasPort(KubernetesConfigFluent> config) {
for (Port p : config.buildPorts()) {
- if (p.getContainerPort() == port.getContainerPort()) {
+ if (Objects.equals(p.getContainerPort(), port.getContainerPort())) {
return true;
}
}
diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToOpenshiftConfig.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToOpenshiftConfig.java
index 6235424c3a43c..e8077aed4ebd4 100644
--- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToOpenshiftConfig.java
+++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddPortToOpenshiftConfig.java
@@ -29,7 +29,7 @@ public void visit(OpenshiftConfigFluent> config) {
*/
private boolean hasPort(OpenshiftConfigFluent> config) {
for (Port p : config.buildPorts()) {
- if (p.getContainerPort() == port.getContainerPort()) {
+ if (Objects.equals(p.getContainerPort(), port.getContainerPort())) {
return true;
}
}
diff --git a/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java b/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java
index 66e45af582ff9..8b415d41106e4 100644
--- a/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java
+++ b/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java
@@ -3,6 +3,7 @@
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;
import static java.util.function.Predicate.not;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
@@ -61,8 +62,10 @@
import io.quarkus.liquibase.LiquibaseDataSource;
import io.quarkus.liquibase.LiquibaseFactory;
import io.quarkus.liquibase.runtime.LiquibaseBuildTimeConfig;
+import io.quarkus.liquibase.runtime.LiquibaseDataSourceBuildTimeConfig;
import io.quarkus.liquibase.runtime.LiquibaseFactoryProducer;
import io.quarkus.liquibase.runtime.LiquibaseRecorder;
+import io.quarkus.runtime.util.StringUtil;
import liquibase.change.Change;
import liquibase.change.DatabaseChangeProperty;
import liquibase.change.core.CreateProcedureChange;
@@ -77,6 +80,9 @@
import liquibase.parser.ChangeLogParserFactory;
import liquibase.plugin.AbstractPluginFactory;
import liquibase.resource.ClassLoaderResourceAccessor;
+import liquibase.resource.CompositeResourceAccessor;
+import liquibase.resource.DirectoryResourceAccessor;
+import liquibase.resource.ResourceAccessor;
class LiquibaseProcessor {
@@ -360,57 +366,89 @@ private List getChangeLogs(Collection dataSourceNames, Liquibase
return Collections.emptyList();
}
- ChangeLogParameters changeLogParameters = new ChangeLogParameters();
+ List liquibaseDataSources = new ArrayList<>();
- ChangeLogParserFactory changeLogParserFactory = ChangeLogParserFactory.getInstance();
+ if (DataSourceUtil.hasDefault(dataSourceNames)) {
+ liquibaseDataSources.add(liquibaseBuildConfig.defaultDataSource);
+ }
+
+ for (String dataSourceName : dataSourceNames) {
+ if (!DataSourceUtil.isDefault(dataSourceName)) {
+ liquibaseDataSources.add(liquibaseBuildConfig.getConfigForDataSourceName(dataSourceName));
+ }
+ }
+ ChangeLogParameters changeLogParameters = new ChangeLogParameters();
+ ChangeLogParserFactory changeLogParserFactory = ChangeLogParserFactory.getInstance();
Set resources = new LinkedHashSet<>();
+ for (LiquibaseDataSourceBuildTimeConfig liquibaseDataSourceConfig : liquibaseDataSources) {
- ClassLoaderResourceAccessor classLoaderResourceAccessor = new ClassLoaderResourceAccessor(
- Thread.currentThread().getContextClassLoader());
+ Optional> oSearchPaths = liquibaseDataSourceConfig.searchPath;
+ String changeLog = liquibaseDataSourceConfig.changeLog;
+ String parsedChangeLog = parseChangeLog(oSearchPaths, changeLog);
- try {
- // default datasource
- if (DataSourceUtil.hasDefault(dataSourceNames)) {
- resources.addAll(findAllChangeLogFiles(liquibaseBuildConfig.defaultDataSource.changeLog, changeLogParserFactory,
- classLoaderResourceAccessor, changeLogParameters));
+ try (ResourceAccessor resourceAccessor = resolveResourceAccessor(oSearchPaths, changeLog)) {
+ resources.addAll(findAllChangeLogFiles(parsedChangeLog, changeLogParserFactory,
+ resourceAccessor, changeLogParameters));
+ } catch (Exception ex) {
+ throw new IllegalStateException(ex);
}
+ }
- // named datasources
- Collection namedDataSourceChangeLogs = dataSourceNames.stream()
- .filter(n -> !DataSourceUtil.isDefault(n))
- .map(liquibaseBuildConfig::getConfigForDataSourceName)
- .map(c -> c.changeLog)
- .collect(Collectors.toCollection(LinkedHashSet::new));
-
- for (String namedDataSourceChangeLog : namedDataSourceChangeLogs) {
- resources.addAll(
- findAllChangeLogFiles(namedDataSourceChangeLog, changeLogParserFactory, classLoaderResourceAccessor,
- changeLogParameters));
- }
+ LOGGER.debugf("Liquibase changeLogs: %s", resources);
+ return new ArrayList<>(resources);
+ }
- LOGGER.debugf("Liquibase changeLogs: %s", resources);
+ private ResourceAccessor resolveResourceAccessor(Optional> oSearchPaths, String changeLog)
+ throws FileNotFoundException {
- return new ArrayList<>(resources);
+ CompositeResourceAccessor compositeResourceAccessor = new CompositeResourceAccessor();
+ compositeResourceAccessor
+ .addResourceAccessor(new ClassLoaderResourceAccessor(Thread.currentThread().getContextClassLoader()));
- } finally {
- try {
- classLoaderResourceAccessor.close();
- } catch (Exception ignored) {
- // close() really shouldn't declare that exception, see also https://github.com/liquibase/liquibase/pull/2576
- }
+ if (!changeLog.startsWith("filesystem:") && oSearchPaths.isEmpty()) {
+ return compositeResourceAccessor;
}
+
+ if (oSearchPaths.isEmpty()) {
+ compositeResourceAccessor.addResourceAccessor(
+ new DirectoryResourceAccessor(
+ Paths.get(StringUtil.changePrefix(changeLog, "filesystem:", "")).getParent()));
+ return compositeResourceAccessor;
+ }
+
+ for (String searchPath : oSearchPaths.get()) {
+ compositeResourceAccessor.addResourceAccessor(new DirectoryResourceAccessor(Paths.get(searchPath)));
+ }
+
+ return compositeResourceAccessor;
+ }
+
+ private String parseChangeLog(Optional> oSearchPaths, String changeLog) {
+
+ if (changeLog.startsWith("filesystem:") && oSearchPaths.isEmpty()) {
+ return Paths.get(StringUtil.changePrefix(changeLog, "filesystem:", "")).getFileName().toString();
+ }
+
+ if (changeLog.startsWith("filesystem:")) {
+ return StringUtil.changePrefix(changeLog, "filesystem:", "");
+ }
+
+ if (changeLog.startsWith("classpath:")) {
+ return StringUtil.changePrefix(changeLog, "classpath:", "");
+ }
+
+ return changeLog;
}
/**
* Finds all resource files for the given change log file
*/
private Set findAllChangeLogFiles(String file, ChangeLogParserFactory changeLogParserFactory,
- ClassLoaderResourceAccessor classLoaderResourceAccessor,
- ChangeLogParameters changeLogParameters) {
+ ResourceAccessor resourceAccessor, ChangeLogParameters changeLogParameters) {
try {
- ChangeLogParser parser = changeLogParserFactory.getParser(file, classLoaderResourceAccessor);
- DatabaseChangeLog changelog = parser.parse(file, changeLogParameters, classLoaderResourceAccessor);
+ ChangeLogParser parser = changeLogParserFactory.getParser(file, resourceAccessor);
+ DatabaseChangeLog changelog = parser.parse(file, changeLogParameters, resourceAccessor);
if (changelog != null) {
Set result = new LinkedHashSet<>();
diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java
index 84290b257abb7..899c6f454fc4d 100644
--- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java
+++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java
@@ -94,8 +94,7 @@ public class OidcTenantConfig extends OidcCommonConfig {
/**
* The paths which must be secured by this tenant. Tenant with the most specific path wins.
- * Please see the xref:security-openid-connect-multitenancy.adoc#configuration-based-tenant-resolver[Resolve with
- * configuration]
+ * Please see the xref:security-openid-connect-multitenancy.adoc#configure-tenant-paths[Configure tenant paths]
* section of the OIDC multitenancy guide for explanation of allowed path patterns.
*
* @asciidoclet
diff --git a/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java b/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java
index 07d3e0cebed69..3ccb72cce6088 100644
--- a/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java
+++ b/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/RestClientReactiveProcessor.java
@@ -311,6 +311,10 @@ void registerProvidersFromAnnotations(CombinedIndexBuildItem indexBuildItem,
int.class),
constructor.getThis(), constructor.loadClassFromTCCL(providerDotName.toString()),
constructor.load(priority));
+
+ // when the server is not included, providers are not automatically registered for reflection,
+ // so we need to always do it for the client to be on the safe side
+ reflectiveClassesProducer.produce(ReflectiveClassBuildItem.builder(providerDotName.toString()).build());
}
}
diff --git a/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/InheritanceTest.java b/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/InheritanceTest.java
index cda6508920086..2e7b03c59807b 100644
--- a/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/InheritanceTest.java
+++ b/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/InheritanceTest.java
@@ -16,6 +16,8 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
+import io.quarkus.resteasy.reactive.server.test.resource.basic.resource.InheritanceAbstractParentImplResource;
+import io.quarkus.resteasy.reactive.server.test.resource.basic.resource.InheritanceAbstractParentResource;
import io.quarkus.resteasy.reactive.server.test.resource.basic.resource.InheritanceParentResource;
import io.quarkus.resteasy.reactive.server.test.resource.basic.resource.InheritanceParentResourceImpl;
import io.quarkus.resteasy.reactive.server.test.simple.PortProviderUtil;
@@ -39,6 +41,8 @@ public class InheritanceTest {
public JavaArchive get() {
JavaArchive war = ShrinkWrap.create(JavaArchive.class);
war.addClass(InheritanceParentResource.class);
+ war.addClass(InheritanceAbstractParentResource.class);
+ war.addClass(InheritanceAbstractParentImplResource.class);
war.addClasses(PortProviderUtil.class, InheritanceParentResourceImpl.class);
return war;
}
@@ -67,4 +71,13 @@ public void Test1() throws Exception {
Assertions.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
Assertions.assertEquals(response.readEntity(String.class), "First");
}
+
+ @Test
+ public void testAbstractParent() {
+ Builder builder = client.target(generateURL("/inheritance-abstract-parent-test")).request();
+ builder.header("Accept", "text/plain");
+ Response response = builder.get();
+ Assertions.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+ Assertions.assertEquals(response.readEntity(String.class), "works");
+ }
}
diff --git a/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/resource/InheritanceAbstractParentImplResource.java b/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/resource/InheritanceAbstractParentImplResource.java
new file mode 100644
index 0000000000000..4b740f37a38fc
--- /dev/null
+++ b/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/resource/InheritanceAbstractParentImplResource.java
@@ -0,0 +1,10 @@
+package io.quarkus.resteasy.reactive.server.test.resource.basic.resource;
+
+public class InheritanceAbstractParentImplResource extends InheritanceAbstractParentResource {
+
+ @Override
+ public String get() {
+ return "works";
+ }
+
+}
diff --git a/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/resource/InheritanceAbstractParentResource.java b/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/resource/InheritanceAbstractParentResource.java
new file mode 100644
index 0000000000000..26560c777eb26
--- /dev/null
+++ b/extensions/resteasy-reactive/rest/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/resource/basic/resource/InheritanceAbstractParentResource.java
@@ -0,0 +1,12 @@
+package io.quarkus.resteasy.reactive.server.test.resource.basic.resource;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+
+@Path("/inheritance-abstract-parent-test")
+public abstract class InheritanceAbstractParentResource {
+
+ @GET
+ public abstract String get();
+
+}
diff --git a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLExecutionHandler.java b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLExecutionHandler.java
index d0ffbc1901c95..7d97c18bd090c 100644
--- a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLExecutionHandler.java
+++ b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLExecutionHandler.java
@@ -309,7 +309,7 @@ private String readQueryParameter(RoutingContext ctx, String parameterName) {
return null;
}
- private static final Pattern PATTERN_NEWLINE_OR_TAB = Pattern.compile("\\n|\\t");
+ private static final Pattern PATTERN_NEWLINE_OR_TAB = Pattern.compile("\\n|\\t|\\r");
/**
* Strip away unescaped tabs and line breaks from the incoming JSON document so that it can be
diff --git a/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/VertxCoreProcessor.java b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/VertxCoreProcessor.java
index d376eb44e13ef..ab09839b74d15 100644
--- a/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/VertxCoreProcessor.java
+++ b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/VertxCoreProcessor.java
@@ -369,7 +369,7 @@ private Filter createDebuggerFilter() {
debugPort = Integer.parseInt(m.group(2));
String host = m.group(1);
if (host.equals("*")) {
- host.equals("localhost");
+ host = "localhost";
}
bindAddress = InetAddress.getByName(host);
}
diff --git a/extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/devui/WebSocketServerDevUIProcessor.java b/extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/devui/WebSocketServerDevUIProcessor.java
index 5f89d5cfd0482..2785efe1fbdd4 100644
--- a/extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/devui/WebSocketServerDevUIProcessor.java
+++ b/extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/devui/WebSocketServerDevUIProcessor.java
@@ -40,7 +40,7 @@ public void pages(List endpoints, List root
+ .addClass(MyBean.class));
+
+ @Test
+ public void testConnectorIsInjected() {
+ assertEquals("1", RestAssured.get("mybeantest").then().statusCode(200).extract().body().asString());
+ }
+
+ @Singleton
+ public static class MyBean {
+
+ @Inject
+ BasicWebSocketConnector connector;
+
+ void addRoute(@Observes Router router) {
+ router.get("/mybeantest").handler(rc -> {
+ rc.end(connector != null ? "1" : "0");
+ });
+ }
+
+ }
+
+}
diff --git a/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/BasicWebSocketConnectorImpl.java b/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/BasicWebSocketConnectorImpl.java
index fb33732ca6c47..7d2487783ccf1 100644
--- a/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/BasicWebSocketConnectorImpl.java
+++ b/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/BasicWebSocketConnectorImpl.java
@@ -117,10 +117,7 @@ public Uni connect() {
// TODO would it make sense to share clients?
WebSocketClient client = vertx.createWebSocketClient(populateClientOptions());
- WebSocketConnectOptions connectOptions = new WebSocketConnectOptions()
- .setSsl(baseUri.getScheme().equals("https"))
- .setHost(baseUri.getHost())
- .setPort(baseUri.getPort());
+ WebSocketConnectOptions connectOptions = newConnectOptions(baseUri);
StringBuilder requestUri = new StringBuilder();
String mergedPath = mergePath(baseUri.getPath(), replacePathParameters(path));
requestUri.append(mergedPath);
diff --git a/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorBase.java b/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorBase.java
index ee098d6a43d16..1556899636c9f 100644
--- a/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorBase.java
+++ b/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorBase.java
@@ -21,6 +21,7 @@
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.WebSocketClientOptions;
+import io.vertx.core.http.WebSocketConnectOptions;
import io.vertx.core.net.SSLOptions;
abstract class WebSocketConnectorBase> {
@@ -191,4 +192,21 @@ protected WebSocketClientOptions populateClientOptions() {
}
return clientOptions;
}
+
+ protected WebSocketConnectOptions newConnectOptions(URI serverEndpointUri) {
+ WebSocketConnectOptions connectOptions = new WebSocketConnectOptions()
+ .setSsl(isHttps(serverEndpointUri))
+ .setHost(serverEndpointUri.getHost());
+ if (serverEndpointUri.getPort() != -1) {
+ connectOptions.setPort(serverEndpointUri.getPort());
+ } else if (isHttps(serverEndpointUri)) {
+ // If port is undefined and https is used then use 443 by default
+ connectOptions.setPort(443);
+ }
+ return connectOptions;
+ }
+
+ protected boolean isHttps(URI uri) {
+ return "https".equals(uri.getScheme());
+ }
}
diff --git a/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorImpl.java b/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorImpl.java
index 359a400f5160a..1b6d9a6af32ec 100644
--- a/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorImpl.java
+++ b/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/WebSocketConnectorImpl.java
@@ -73,10 +73,7 @@ public Uni connect() {
throw new WebSocketClientException(e);
}
- WebSocketConnectOptions connectOptions = new WebSocketConnectOptions()
- .setSsl(serverEndpointUri.getScheme().equals("https"))
- .setHost(serverEndpointUri.getHost())
- .setPort(serverEndpointUri.getPort());
+ WebSocketConnectOptions connectOptions = newConnectOptions(serverEndpointUri);
StringBuilder uri = new StringBuilder();
if (serverEndpointUri.getPath() != null) {
uri.append(serverEndpointUri.getRawPath());
diff --git a/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/devui/WebSocketNextJsonRPCService.java b/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/devui/WebSocketNextJsonRPCService.java
index 5df2e1d395b28..b54992fae08bd 100644
--- a/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/devui/WebSocketNextJsonRPCService.java
+++ b/extensions/websockets-next/runtime/src/main/java/io/quarkus/websockets/next/runtime/devui/WebSocketNextJsonRPCService.java
@@ -12,6 +12,7 @@
import java.util.concurrent.ConcurrentMap;
import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.inject.Instance;
import org.jboss.logging.Logger;
@@ -53,16 +54,18 @@ public class WebSocketNextJsonRPCService implements ConnectionListener {
private final WebSocketsServerRuntimeConfig.DevMode devModeConfig;
- WebSocketNextJsonRPCService(ConnectionManager connectionManager, Vertx vertx, HttpConfiguration httpConfig,
+ WebSocketNextJsonRPCService(Instance connectionManager, Vertx vertx, HttpConfiguration httpConfig,
WebSocketsServerRuntimeConfig config) {
this.connectionStatus = BroadcastProcessor.create();
this.connectionMessages = BroadcastProcessor.create();
- this.connectionManager = connectionManager;
+ this.connectionManager = connectionManager.isResolvable() ? connectionManager.get() : null;
this.vertx = vertx;
this.httpConfig = httpConfig;
this.devModeConfig = config.devMode();
this.sockets = new ConcurrentHashMap<>();
- connectionManager.addListener(this);
+ if (this.connectionManager != null) {
+ this.connectionManager.addListener(this);
+ }
}
public Multi connectionStatus() {
@@ -75,14 +78,16 @@ public Multi connectionMessages() {
public JsonObject getConnections(List endpoints) {
JsonObject json = new JsonObject();
- for (String endpoint : endpoints) {
- List connections = new ArrayList<>(connectionManager.getConnections(endpoint));
- connections.sort(Comparator.comparing(WebSocketConnection::creationTime));
- JsonArray array = new JsonArray();
- for (WebSocketConnection c : connections) {
- array.add(toJsonObject(endpoint, c));
+ if (connectionManager != null) {
+ for (String endpoint : endpoints) {
+ List connections = new ArrayList<>(connectionManager.getConnections(endpoint));
+ connections.sort(Comparator.comparing(WebSocketConnection::creationTime));
+ JsonArray array = new JsonArray();
+ for (WebSocketConnection c : connections) {
+ array.add(toJsonObject(endpoint, c));
+ }
+ json.put(endpoint, array);
}
- json.put(endpoint, array);
}
json.put("connectionMessagesLimit", devModeConfig.connectionMessagesLimit());
return json;
@@ -104,6 +109,9 @@ public JsonArray getMessages(String connectionKey) {
}
public Uni openDevConnection(String path, String endpointPath) {
+ if (connectionManager == null) {
+ return failureUni();
+ }
if (isInvalidPath(path, endpointPath)) {
LOG.errorf("Invalid path %s; original endpoint path %s", path, endpointPath);
return failureUni();
@@ -179,6 +187,9 @@ private static String normalize(String path) {
}
public Uni closeDevConnection(String connectionKey) {
+ if (connectionManager == null) {
+ return failureUni();
+ }
DevWebSocket socket = sockets.remove(connectionKey);
if (socket != null) {
Uni uni = UniHelper.toUni(socket.socket.close());
diff --git a/independent-projects/extension-maven-plugin/pom.xml b/independent-projects/extension-maven-plugin/pom.xml
index 58e411d44e4c9..d311962a02a9b 100644
--- a/independent-projects/extension-maven-plugin/pom.xml
+++ b/independent-projects/extension-maven-plugin/pom.xml
@@ -38,7 +38,7 @@
11
11
3.9.8
- 2.17.1
+ 2.17.2
1.5.2
5.10.2
diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java
index cbb3f8f91dbad..e97bacc60b9a9 100644
--- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java
+++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/scanning/ResteasyReactiveScanner.java
@@ -262,6 +262,22 @@ public static ResourceScanningResult scanResources(
}
}
+ // handle abstract classes
+ var abstractClasses = scannedResources.values().stream().filter(ClassInfo::isAbstract).toList();
+ abstractClasses.forEach(abstractScannedResource -> {
+ Collection allSubclasses = index.getAllKnownSubclasses(abstractScannedResource.name());
+ if (allSubclasses.size() != 1) {
+ return; // don't do anything with this case as it's not evident how it's supposed to be handled
+ }
+ ClassInfo subclass = allSubclasses.iterator().next();
+ if (!scannedResources.containsKey(subclass.name())) {
+ scannedResources.put(subclass.name(), subclass);
+ scannedResources.remove(abstractScannedResource.name());
+ scannedResourcePaths.put(subclass.name(), scannedResourcePaths.get(abstractScannedResource.name()));
+ scannedResourcePaths.remove(abstractScannedResource.name());
+ }
+ });
+
Map clientInterfaces = new HashMap<>(pathInterfaces);
// for clients it is enough to have @PATH annotations on methods only
for (DotName interfaceName : interfacesWithPathOnMethods) {
diff --git a/independent-projects/resteasy-reactive/pom.xml b/independent-projects/resteasy-reactive/pom.xml
index e835ae4c528b3..a0c6c5cb6097a 100644
--- a/independent-projects/resteasy-reactive/pom.xml
+++ b/independent-projects/resteasy-reactive/pom.xml
@@ -61,7 +61,7 @@
4.5.7
5.4.0
1.0.0.Final
- 2.17.1
+ 2.17.2
2.6.0
3.0.2
3.0.3
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/AsyncResponseImpl.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/AsyncResponseImpl.java
index 23f4964be8ea0..1e307e0349cbb 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/AsyncResponseImpl.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/AsyncResponseImpl.java
@@ -153,7 +153,7 @@ public Map, Collection>> register(Class> callback, Class>.
Objects.requireNonNull(callback);
Objects.requireNonNull(callbacks);
Map, Collection>> ret = new HashMap<>();
- ret.put(callback.getClass(), register(callback));
+ ret.put(callback, register(callback));
for (Class> cb : callbacks) {
ret.put(cb, register(cb));
}
diff --git a/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus/buildtool/gradle-kotlin-dsl/base/gradle.tpl.qute.properties b/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus/buildtool/gradle-kotlin-dsl/base/gradle.tpl.qute.properties
index d3160667382c5..80d94672c2262 100644
--- a/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus/buildtool/gradle-kotlin-dsl/base/gradle.tpl.qute.properties
+++ b/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus/buildtool/gradle-kotlin-dsl/base/gradle.tpl.qute.properties
@@ -1,6 +1,7 @@
-#Gradle properties
+# Gradle properties
+
quarkusPluginId={quarkus.gradle-plugin.id}
quarkusPluginVersion={quarkus.gradle-plugin.version}
quarkusPlatformGroupId={quarkus.platform.group-id}
quarkusPlatformArtifactId={quarkus.platform.artifact-id}
-quarkusPlatformVersion={quarkus.platform.version}
\ No newline at end of file
+quarkusPlatformVersion={quarkus.platform.version}
diff --git a/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus/buildtool/gradle/base/gradle.tpl.qute.properties b/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus/buildtool/gradle/base/gradle.tpl.qute.properties
index d3160667382c5..80d94672c2262 100644
--- a/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus/buildtool/gradle/base/gradle.tpl.qute.properties
+++ b/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus/buildtool/gradle/base/gradle.tpl.qute.properties
@@ -1,6 +1,7 @@
-#Gradle properties
+# Gradle properties
+
quarkusPluginId={quarkus.gradle-plugin.id}
quarkusPluginVersion={quarkus.gradle-plugin.version}
quarkusPlatformGroupId={quarkus.platform.group-id}
quarkusPlatformArtifactId={quarkus.platform.artifact-id}
-quarkusPlatformVersion={quarkus.platform.version}
\ No newline at end of file
+quarkusPlatformVersion={quarkus.platform.version}
diff --git a/independent-projects/tools/devtools-common/pom.xml b/independent-projects/tools/devtools-common/pom.xml
index 2e5832fddb6af..e7b70a29daea2 100644
--- a/independent-projects/tools/devtools-common/pom.xml
+++ b/independent-projects/tools/devtools-common/pom.xml
@@ -106,6 +106,10 @@
jakarta.enterprise
jakarta.enterprise.cdi-api
+
+ org.codejive
+ java-properties
+
org.junit.jupiter
junit-jupiter
diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFile.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFile.java
index dd5ea2931ce1e..d9ad8bdb7eb79 100644
--- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFile.java
+++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFile.java
@@ -1,18 +1,19 @@
package io.quarkus.devtools.project.buildfile;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Properties;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.codejive.properties.Properties;
+
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.maven.dependency.ArtifactKey;
import io.quarkus.registry.catalog.ExtensionCatalog;
@@ -47,22 +48,22 @@ public void writeToDisk() throws IOException {
if (rootProjectPath != null) {
Files.write(rootProjectPath.resolve(getSettingsGradlePath()), getModel().getRootSettingsContent().getBytes());
if (hasRootProjectFile(GRADLE_PROPERTIES_PATH)) {
- try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
- getModel().getRootPropertiesContent().store(out, "Gradle properties");
- Files.write(rootProjectPath.resolve(GRADLE_PROPERTIES_PATH),
- out.toByteArray());
+ try (StringWriter sw = new StringWriter()) {
+ getModel().getRootPropertiesContent().store(sw, "Gradle properties");
+ Files.writeString(rootProjectPath.resolve(GRADLE_PROPERTIES_PATH),
+ sw.toString());
}
}
} else {
writeToProjectFile(getSettingsGradlePath(), getModel().getSettingsContent().getBytes());
if (hasProjectFile(GRADLE_PROPERTIES_PATH)) {
- try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
- getModel().getPropertiesContent().store(out, "Gradle properties");
- writeToProjectFile(GRADLE_PROPERTIES_PATH, out.toByteArray());
+ try (StringWriter sw = new StringWriter()) {
+ getModel().getPropertiesContent().store(sw, "Gradle properties");
+ writeToProjectFile(GRADLE_PROPERTIES_PATH, sw.toString());
}
}
}
- writeToProjectFile(getBuildGradlePath(), getModel().getBuildContent().getBytes());
+ writeToProjectFile(getBuildGradlePath(), getModel().getBuildContent());
}
static boolean containsProperty(ArtifactCoords coords) {
diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFilesCreator.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFilesCreator.java
index 5d6ad5618536f..e3c8f24cf8069 100644
--- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFilesCreator.java
+++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFilesCreator.java
@@ -8,9 +8,10 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
-import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
+import org.codejive.properties.Properties;
+
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.devtools.project.buildfile.AbstractGradleBuildFile.Model;
import io.quarkus.maven.dependency.ArtifactCoords;
@@ -122,6 +123,10 @@ protected void writeToProjectFile(final String fileName, final byte[] content) t
Files.write(quarkusProject.getProjectDirPath().resolve(fileName), content);
}
+ protected void writeToProjectFile(final String fileName, final String content) throws IOException {
+ Files.writeString(quarkusProject.getProjectDirPath().resolve(fileName), content);
+ }
+
private void createProperties() throws IOException {
final ExtensionCatalog platform = quarkusProject.getExtensionsCatalog();
Properties props = getModel().getPropertiesContent();
diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/BuildFile.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/BuildFile.java
index a05d32b9e103a..ce9cb33e71f3f 100644
--- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/BuildFile.java
+++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/buildfile/BuildFile.java
@@ -155,6 +155,10 @@ protected void writeToProjectFile(final String fileName, final byte[] content) t
Files.write(projectDirPath.resolve(fileName), content);
}
+ protected void writeToProjectFile(final String fileName, final String content) throws IOException {
+ Files.writeString(projectDirPath.resolve(fileName), content);
+ }
+
private Set getDependenciesKeys() throws IOException {
return getDependencies().stream().map(ArtifactCoords::getKey).collect(Collectors.toSet());
}
diff --git a/independent-projects/tools/pom.xml b/independent-projects/tools/pom.xml
index ba3d735485840..9432bc380b5fe 100644
--- a/independent-projects/tools/pom.xml
+++ b/independent-projects/tools/pom.xml
@@ -49,7 +49,7 @@
3.26.0
- 2.17.1
+ 2.17.2
4.1.0
5.10.2
1.26.2
@@ -60,6 +60,7 @@
3.2.0
2.0.2
4.2.1
+ 0.0.7
registry-client
@@ -175,6 +176,11 @@
jboss-logging
${jboss-logging.version}
+
+ org.codejive
+ java-properties
+ ${java-properties.version}
+
org.junit.jupiter
junit-jupiter
diff --git a/integration-tests/gradle/src/main/resources/compile-only-lombok/gradle.properties b/integration-tests/gradle/src/main/resources/compile-only-lombok/gradle.properties
index cac35f5608ec1..542d9cf933db7 100644
--- a/integration-tests/gradle/src/main/resources/compile-only-lombok/gradle.properties
+++ b/integration-tests/gradle/src/main/resources/compile-only-lombok/gradle.properties
@@ -1,6 +1,6 @@
-#Gradle properties
-#Tue Aug 04 17:04:55 CEST 2020
+# Gradle properties
+
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformGroupId=io.quarkus
org.gradle.logging.level=INFO
-lombokVersion=1.18.12
\ No newline at end of file
+lombokVersion=1.18.12
diff --git a/integration-tests/gradle/src/main/resources/multi-module-included-build/gradle.properties b/integration-tests/gradle/src/main/resources/multi-module-included-build/gradle.properties
index a0bb7cd4da3b4..0b9b349582ac3 100644
--- a/integration-tests/gradle/src/main/resources/multi-module-included-build/gradle.properties
+++ b/integration-tests/gradle/src/main/resources/multi-module-included-build/gradle.properties
@@ -1,4 +1,4 @@
-#Gradle properties
-#Tue Aug 25 06:41:36 GMT 2020
+# Gradle properties
+
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformGroupId=io.quarkus
diff --git a/integration-tests/gradle/src/main/resources/multi-module-kotlin-project/gradle.properties b/integration-tests/gradle/src/main/resources/multi-module-kotlin-project/gradle.properties
index b8ff81712a497..d54b9c8a6b92b 100644
--- a/integration-tests/gradle/src/main/resources/multi-module-kotlin-project/gradle.properties
+++ b/integration-tests/gradle/src/main/resources/multi-module-kotlin-project/gradle.properties
@@ -1,5 +1,5 @@
-#Gradle properties
-#Wed May 06 08:31:08 UTC 2020
+# Gradle properties
+
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformGroupId=io.quarkus
diff --git a/integration-tests/gradle/src/main/resources/multi-module-with-empty-module/gradle.properties b/integration-tests/gradle/src/main/resources/multi-module-with-empty-module/gradle.properties
index e6b64c6a56957..0b9b349582ac3 100644
--- a/integration-tests/gradle/src/main/resources/multi-module-with-empty-module/gradle.properties
+++ b/integration-tests/gradle/src/main/resources/multi-module-with-empty-module/gradle.properties
@@ -1,3 +1,4 @@
-#Gradle properties
+# Gradle properties
+
quarkusPlatformArtifactId=quarkus-bom
-quarkusPlatformGroupId=io.quarkus
\ No newline at end of file
+quarkusPlatformGroupId=io.quarkus
diff --git a/integration-tests/jackson/src/main/java/io/quarkus/it/jackson/model/Mammal.java b/integration-tests/jackson/src/main/java/io/quarkus/it/jackson/model/Mammal.java
index dc622346349f2..3fd7ff7f5f5ca 100644
--- a/integration-tests/jackson/src/main/java/io/quarkus/it/jackson/model/Mammal.java
+++ b/integration-tests/jackson/src/main/java/io/quarkus/it/jackson/model/Mammal.java
@@ -5,11 +5,14 @@
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
@JsonTypeInfo(use = NAME, include = PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(value = Elephant.class, name = "Elephant"),
@JsonSubTypes.Type(value = Whale.class, name = "Whale"),
})
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public interface Mammal {
}
diff --git a/integration-tests/jackson/src/test/java/io/quarkus/it/jackson/JsonSubTypesResourceTest.java b/integration-tests/jackson/src/test/java/io/quarkus/it/jackson/JsonSubTypesResourceTest.java
index fe1979b72db7a..16f25157b5976 100644
--- a/integration-tests/jackson/src/test/java/io/quarkus/it/jackson/JsonSubTypesResourceTest.java
+++ b/integration-tests/jackson/src/test/java/io/quarkus/it/jackson/JsonSubTypesResourceTest.java
@@ -23,5 +23,6 @@ void test() {
.extract().response();
assertThat(response.jsonPath().getString("mammals[0].color")).isEqualTo("white");
assertThat(response.jsonPath().getString("mammals[1].continent")).isEqualTo("africa");
+ assertThat(response.jsonPath().getString("mammals[1].horn_length")).isEqualTo("10");
}
}
diff --git a/integration-tests/opentelemetry-vertx-exporter/src/test/java/io/quarkus/it/opentelemetry/vertx/exporter/OtelCollectorLifecycleManager.java b/integration-tests/opentelemetry-vertx-exporter/src/test/java/io/quarkus/it/opentelemetry/vertx/exporter/OtelCollectorLifecycleManager.java
index 1c2df7c6a0df1..bcb6bd7eda002 100644
--- a/integration-tests/opentelemetry-vertx-exporter/src/test/java/io/quarkus/it/opentelemetry/vertx/exporter/OtelCollectorLifecycleManager.java
+++ b/integration-tests/opentelemetry-vertx-exporter/src/test/java/io/quarkus/it/opentelemetry/vertx/exporter/OtelCollectorLifecycleManager.java
@@ -33,7 +33,8 @@
public class OtelCollectorLifecycleManager implements QuarkusTestResourceLifecycleManager {
- private static final String COLLECTOR_IMAGE = "ghcr.io/open-telemetry/opentelemetry-java/otel-collector";
+ private static final String COLLECTOR_IMAGE = "ghcr.io/open-telemetry/opentelemetry-java/" +
+ "otel-collector@sha256:0d928e02b0ef5abbba775da205eb102f58b29aa75ea623465ec42445dfc5c443";
private static final Integer COLLECTOR_OTLP_GRPC_PORT = 4317;
private static final Integer COLLECTOR_OTLP_HTTP_PORT = 4318;
private static final Integer COLLECTOR_OTLP_GRPC_MTLS_PORT = 5317;
diff --git a/integration-tests/test-extension/extension/deployment/src/main/java/io/quarkus/extest/deployment/ControllerConfigurationBuildStep.java b/integration-tests/test-extension/extension/deployment/src/main/java/io/quarkus/extest/deployment/ControllerConfigurationBuildStep.java
new file mode 100644
index 0000000000000..8e89f1256de0b
--- /dev/null
+++ b/integration-tests/test-extension/extension/deployment/src/main/java/io/quarkus/extest/deployment/ControllerConfigurationBuildStep.java
@@ -0,0 +1,20 @@
+package io.quarkus.extest.deployment;
+
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
+import io.quarkus.extest.runtime.def.ControllerConfigurationProducer;
+import io.quarkus.extest.runtime.def.ControllerConfigurationRecorder;
+import io.quarkus.extest.runtime.def.QuarkusControllerConfiguration;
+
+public class ControllerConfigurationBuildStep {
+
+ @BuildStep
+ @Record(ExecutionTime.RUNTIME_INIT)
+ public void record(ControllerConfigurationRecorder recorder, BuildProducer producer) {
+ producer.produce(AdditionalBeanBuildItem.builder().addBeanClasses(ControllerConfigurationProducer.class).build());
+ recorder.setControllerConfiguration(new QuarkusControllerConfiguration("test1", "test2"));
+ }
+}
diff --git a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/def/ControllerConfigurationTest.java b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/def/ControllerConfigurationTest.java
new file mode 100644
index 0000000000000..8538a8d2c859d
--- /dev/null
+++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/def/ControllerConfigurationTest.java
@@ -0,0 +1,35 @@
+package io.quarkus.def;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import jakarta.inject.Inject;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.quarkus.extest.runtime.def.ControllerConfiguration;
+import io.quarkus.extest.runtime.def.QuarkusControllerConfiguration;
+import io.quarkus.test.QuarkusUnitTest;
+
+public class ControllerConfigurationTest {
+
+ @RegisterExtension
+ static final QuarkusUnitTest config = new QuarkusUnitTest()
+ .withEmptyApplication();
+
+ @Inject
+ ControllerConfiguration controllerConfiguration;
+
+ @Test
+ public void test() {
+ assertThat(controllerConfiguration).isInstanceOfSatisfying(QuarkusControllerConfiguration.class,
+ quarkusControllerConfiguration -> {
+ assertThat(quarkusControllerConfiguration.getName()).isEqualTo("test1");
+ assertThat(quarkusControllerConfiguration.getResourceTypeName()).isEqualTo("test2");
+ assertThat(controllerConfiguration.getNamespaces()).containsOnly("foo", "bar");
+ assertThat(controllerConfiguration.getInformerListLimit()).isEmpty();
+ });
+
+ }
+
+}
diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfiguration.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfiguration.java
new file mode 100644
index 0000000000000..3c95427b9c1b5
--- /dev/null
+++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfiguration.java
@@ -0,0 +1,8 @@
+package io.quarkus.extest.runtime.def;
+
+public interface ControllerConfiguration extends ResourceConfiguration {
+
+ default String getName() {
+ return "name";
+ }
+}
diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfigurationProducer.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfigurationProducer.java
new file mode 100644
index 0000000000000..4cf319b5c24c8
--- /dev/null
+++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfigurationProducer.java
@@ -0,0 +1,11 @@
+package io.quarkus.extest.runtime.def;
+
+import jakarta.inject.Singleton;
+
+public class ControllerConfigurationProducer {
+
+ @Singleton
+ public ControllerConfiguration produce() {
+ return ControllerConfigurationRecorder.controllerConfiguration;
+ }
+}
diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfigurationRecorder.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfigurationRecorder.java
new file mode 100644
index 0000000000000..00b9ce1e760e2
--- /dev/null
+++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ControllerConfigurationRecorder.java
@@ -0,0 +1,13 @@
+package io.quarkus.extest.runtime.def;
+
+import io.quarkus.runtime.annotations.Recorder;
+
+@Recorder
+public class ControllerConfigurationRecorder {
+
+ public static volatile ControllerConfiguration controllerConfiguration;
+
+ public void setControllerConfiguration(QuarkusControllerConfiguration controllerConfiguration) {
+ ControllerConfigurationRecorder.controllerConfiguration = controllerConfiguration;
+ }
+}
diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/QuarkusControllerConfiguration.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/QuarkusControllerConfiguration.java
new file mode 100644
index 0000000000000..55eb7689b14bc
--- /dev/null
+++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/QuarkusControllerConfiguration.java
@@ -0,0 +1,24 @@
+package io.quarkus.extest.runtime.def;
+
+import io.quarkus.runtime.annotations.RecordableConstructor;
+
+public class QuarkusControllerConfiguration implements ControllerConfiguration {
+
+ private final String name;
+ private final String resourceTypeName;
+
+ @RecordableConstructor
+ public QuarkusControllerConfiguration(String name, String resourceTypeName) {
+ this.name = name;
+ this.resourceTypeName = resourceTypeName;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ public String getResourceTypeName() {
+ return resourceTypeName;
+ }
+}
diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ResourceConfiguration.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ResourceConfiguration.java
new file mode 100644
index 0000000000000..8244e21e124e1
--- /dev/null
+++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/def/ResourceConfiguration.java
@@ -0,0 +1,19 @@
+package io.quarkus.extest.runtime.def;
+
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+public interface ResourceConfiguration {
+
+ default Set getNamespaces() {
+ HashSet set = new HashSet<>();
+ set.add("foo");
+ set.add("bar");
+ return set;
+ }
+
+ default Optional getInformerListLimit() {
+ return Optional.empty();
+ }
+}
diff --git a/pom.xml b/pom.xml
index 38d0eecf473a4..a20c1b2742848 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,7 +69,7 @@
0.8.12
- 6.13.0
+ 6.13.1
5.4.0
6.5.2.Final
4.13.0
diff --git a/test-framework/common/src/main/java/io/quarkus/test/common/DefaultDockerContainerLauncher.java b/test-framework/common/src/main/java/io/quarkus/test/common/DefaultDockerContainerLauncher.java
index 2d01ef727fd4a..533048d795934 100644
--- a/test-framework/common/src/main/java/io/quarkus/test/common/DefaultDockerContainerLauncher.java
+++ b/test-framework/common/src/main/java/io/quarkus/test/common/DefaultDockerContainerLauncher.java
@@ -118,7 +118,9 @@ public void start() throws IOException {
args.add("-i"); // Interactive, write logs to stdout
args.add("--rm");
- args.addAll(NativeImageBuildLocalContainerRunner.getVolumeAccessArguments(containerRuntime));
+ if (!volumeMounts.isEmpty()) {
+ args.addAll(NativeImageBuildLocalContainerRunner.getVolumeAccessArguments(containerRuntime));
+ }
args.add("-p");
args.add(httpPort + ":" + httpPort);