configuredClockProvider = Arc.container().instance(ClockProvider.class);
if (configuredClockProvider.isAvailable()) {
configuration.clockProvider(configuredClockProvider.get());
+ } else {
+ // If user didn't provide a custom clock provider we want to set our own.
+ // This provider ensure the correct behavior in a native mode as it does not
+ // cache the time zone at a build time.
+ configuration.clockProvider(RuntimeReinitializedDefaultClockProvider.INSTANCE);
}
// Hibernate Validator-specific configuration
diff --git a/extensions/hibernate-validator/runtime/src/main/java/io/quarkus/hibernate/validator/runtime/clockprovider/HibernateValidatorClockProviderSystemZoneIdHolder.java b/extensions/hibernate-validator/runtime/src/main/java/io/quarkus/hibernate/validator/runtime/clockprovider/HibernateValidatorClockProviderSystemZoneIdHolder.java
new file mode 100644
index 0000000000000..3c7926b89efb0
--- /dev/null
+++ b/extensions/hibernate-validator/runtime/src/main/java/io/quarkus/hibernate/validator/runtime/clockprovider/HibernateValidatorClockProviderSystemZoneIdHolder.java
@@ -0,0 +1,27 @@
+package io.quarkus.hibernate.validator.runtime.clockprovider;
+
+import java.time.ZoneId;
+
+/**
+ * A helper class holding a system timezone.
+ *
+ * It is reloaded at runtime to provide the runtime-system time zone
+ * to the constraints based on a {@link jakarta.validation.ClockProvider}.
+ *
+ * Note, that we do not hold the timezone constant in the clock provider itself as we need to "reinitialize" this class,
+ * so that the timezone is set to the actual runtime-system-timezone.
+ * Having a constant in the clock provider and asking to reload the provider class leads to native build failure:
+ *
+ *
+ * Error: An object of type 'io.quarkus.hibernate.validator.runtime.clockprovider.HibernateValidatorClockProvider' was found in
+ * the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are
+ * initialized at run time by default.
+ * This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.
+ *
+ *
+ * And we do have instances of the clock provider/clock in the Hibernate Validator metadata as we eagerly initialize
+ * constraints.
+ */
+class HibernateValidatorClockProviderSystemZoneIdHolder {
+ static final ZoneId SYSTEM_ZONE_ID = ZoneId.systemDefault();
+}
diff --git a/extensions/hibernate-validator/runtime/src/main/java/io/quarkus/hibernate/validator/runtime/clockprovider/RuntimeReinitializedDefaultClockProvider.java b/extensions/hibernate-validator/runtime/src/main/java/io/quarkus/hibernate/validator/runtime/clockprovider/RuntimeReinitializedDefaultClockProvider.java
new file mode 100644
index 0000000000000..57df90b170717
--- /dev/null
+++ b/extensions/hibernate-validator/runtime/src/main/java/io/quarkus/hibernate/validator/runtime/clockprovider/RuntimeReinitializedDefaultClockProvider.java
@@ -0,0 +1,45 @@
+package io.quarkus.hibernate.validator.runtime.clockprovider;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+
+import jakarta.validation.ClockProvider;
+
+/**
+ * A Quarkus-specific clock provider that can provide a clock based on a runtime system time zone.
+ */
+public class RuntimeReinitializedDefaultClockProvider implements ClockProvider {
+
+ public static final RuntimeReinitializedDefaultClockProvider INSTANCE = new RuntimeReinitializedDefaultClockProvider();
+
+ private static final RuntimeReinitializedDefaultClock clock = new RuntimeReinitializedDefaultClock();
+
+ private RuntimeReinitializedDefaultClockProvider() {
+ }
+
+ @Override
+ public Clock getClock() {
+ return clock;
+ }
+
+ private static class RuntimeReinitializedDefaultClock extends Clock {
+
+ @Override
+ public ZoneId getZone() {
+ // we delegate getting the zone id value to a helper class that is reinitialized at runtime
+ // allowing to pick up an actual runtime timezone.
+ return HibernateValidatorClockProviderSystemZoneIdHolder.SYSTEM_ZONE_ID;
+ }
+
+ @Override
+ public Clock withZone(ZoneId zone) {
+ return Clock.system(zone);
+ }
+
+ @Override
+ public Instant instant() {
+ return Instant.now();
+ }
+ }
+}
diff --git a/extensions/jdbc/jdbc-h2/runtime/pom.xml b/extensions/jdbc/jdbc-h2/runtime/pom.xml
index 1302bc0bdc7cd..aca531e1041c0 100644
--- a/extensions/jdbc/jdbc-h2/runtime/pom.xml
+++ b/extensions/jdbc/jdbc-h2/runtime/pom.xml
@@ -21,15 +21,6 @@
com.h2database
h2
-
-
- org.apache.lucene
- lucene-core
- 9.7.0
-
org.locationtech.jts
jts-core
diff --git a/extensions/jsonb/runtime/src/main/java/io/quarkus/jsonb/JsonbProducer.java b/extensions/jsonb/runtime/src/main/java/io/quarkus/jsonb/JsonbProducer.java
index c8f7941b2adf0..4d191b7115550 100644
--- a/extensions/jsonb/runtime/src/main/java/io/quarkus/jsonb/JsonbProducer.java
+++ b/extensions/jsonb/runtime/src/main/java/io/quarkus/jsonb/JsonbProducer.java
@@ -11,6 +11,7 @@
import io.quarkus.arc.All;
import io.quarkus.arc.DefaultBean;
+import io.quarkus.jsonp.JsonProviderHolder;
@Singleton
public class JsonbProducer {
@@ -30,6 +31,6 @@ public JsonbConfig jsonbConfig(@All List customizers) {
@Singleton
@DefaultBean
public Jsonb jsonb(JsonbConfig jsonbConfig) {
- return JsonbBuilder.create(jsonbConfig);
+ return JsonbBuilder.newBuilder().withProvider(JsonProviderHolder.jsonProvider()).withConfig(jsonbConfig).build();
}
}
diff --git a/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/runtime/KafkaAdminClient.java b/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/runtime/KafkaAdminClient.java
index 1600561f3f1ef..0ced0504abcda 100644
--- a/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/runtime/KafkaAdminClient.java
+++ b/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/runtime/KafkaAdminClient.java
@@ -1,6 +1,13 @@
package io.quarkus.kafka.client.runtime;
-import java.util.*;
+import static io.quarkus.kafka.client.runtime.KafkaRuntimeConfigProducer.TLS_CONFIG_NAME_KEY;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
@@ -33,8 +40,10 @@ void init() {
Map conf = new HashMap<>();
conf.put(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, DEFAULT_ADMIN_CLIENT_TIMEOUT);
for (Map.Entry entry : config.entrySet()) {
- if (AdminClientConfig.configNames().contains(entry.getKey())) {
- conf.put(entry.getKey(), entry.getValue().toString());
+ String key = entry.getKey();
+ // include TLS config name if it has been configured
+ if (TLS_CONFIG_NAME_KEY.equals(key) || AdminClientConfig.configNames().contains(key)) {
+ conf.put(key, entry.getValue().toString());
}
}
client = AdminClient.create(conf);
diff --git a/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/runtime/KafkaRuntimeConfigProducer.java b/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/runtime/KafkaRuntimeConfigProducer.java
index 7490541fc174d..ff679cd61c80e 100644
--- a/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/runtime/KafkaRuntimeConfigProducer.java
+++ b/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/runtime/KafkaRuntimeConfigProducer.java
@@ -16,6 +16,8 @@
@Singleton
public class KafkaRuntimeConfigProducer {
+ public static final String TLS_CONFIG_NAME_KEY = "tls-configuration-name";
+
// not "kafka.", because we also inspect env vars, which start with "KAFKA_"
private static final String CONFIG_PREFIX = "kafka";
private static final String UI_CONFIG_PREFIX = CONFIG_PREFIX + ".ui";
@@ -45,7 +47,7 @@ public Map createKafkaRuntimeConfig(Config config, ApplicationCo
.replace("_", ".");
String value = config.getOptionalValue(propertyName, String.class).orElse("");
result.put(effectivePropertyName, value);
- if (effectivePropertyName.equals("tls-configuration-name")) {
+ if (effectivePropertyName.equals(TLS_CONFIG_NAME_KEY)) {
result.put("ssl.engine.factory.class", QuarkusKafkaSslEngineFactory.class.getName());
}
}
diff --git a/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/tls/QuarkusKafkaSslEngineFactory.java b/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/tls/QuarkusKafkaSslEngineFactory.java
index 42aab3be3e781..1ebd9d795aed1 100644
--- a/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/tls/QuarkusKafkaSslEngineFactory.java
+++ b/extensions/kafka-client/runtime/src/main/java/io/quarkus/kafka/client/tls/QuarkusKafkaSslEngineFactory.java
@@ -1,5 +1,7 @@
package io.quarkus.kafka.client.tls;
+import static io.quarkus.kafka.client.runtime.KafkaRuntimeConfigProducer.TLS_CONFIG_NAME_KEY;
+
import java.io.IOException;
import java.security.KeyStore;
import java.util.Map;
@@ -92,7 +94,11 @@ public void close() throws IOException {
@Override
public void configure(Map configs) {
- String tlsConfigName = (String) configs.get("tls-configuration-name");
+ String tlsConfigName = (String) configs.get(TLS_CONFIG_NAME_KEY);
+ if (tlsConfigName == null) {
+ throw new IllegalArgumentException(
+ "The 'tls-configuration-name' property is required for Kafka Quarkus TLS Registry integration.");
+ }
Instance tlsConfig = CDI.current().getBeanManager().createInstance()
.select(TlsConfigurationRegistry.class);
@@ -118,7 +124,7 @@ public void configure(Map configs) {
* @param configs the Kafka client configuration
*/
public static void checkForOtherSslConfigs(Map configs) {
- String tlsConfigName = (String) configs.get("tls-configuration-name");
+ String tlsConfigName = (String) configs.get(TLS_CONFIG_NAME_KEY);
for (String sslConfig : KAFKA_SSL_CONFIGS) {
if (configs.containsKey(sslConfig)) {
log.warnf(
diff --git a/extensions/kafka-streams/runtime/src/main/java/io/quarkus/kafka/streams/runtime/KafkaStreamsProducer.java b/extensions/kafka-streams/runtime/src/main/java/io/quarkus/kafka/streams/runtime/KafkaStreamsProducer.java
index 604017f831591..570ab735c8f07 100644
--- a/extensions/kafka-streams/runtime/src/main/java/io/quarkus/kafka/streams/runtime/KafkaStreamsProducer.java
+++ b/extensions/kafka-streams/runtime/src/main/java/io/quarkus/kafka/streams/runtime/KafkaStreamsProducer.java
@@ -1,5 +1,6 @@
package io.quarkus.kafka.streams.runtime;
+import static io.quarkus.kafka.client.runtime.KafkaRuntimeConfigProducer.TLS_CONFIG_NAME_KEY;
import static io.quarkus.kafka.streams.runtime.KafkaStreamsRuntimeConfig.DEFAULT_KAFKA_BROKER;
import java.net.InetSocketAddress;
@@ -362,6 +363,10 @@ private static void waitForTopicsToBeCreated(Admin adminClient, Collection first
diff --git a/extensions/oidc-common/runtime/pom.xml b/extensions/oidc-common/runtime/pom.xml
index 13b0ddb973f1a..f05f78506e1ed 100644
--- a/extensions/oidc-common/runtime/pom.xml
+++ b/extensions/oidc-common/runtime/pom.xml
@@ -71,6 +71,9 @@
${project.version}
+
+ -AlegacyConfigRoot=true
+
diff --git a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/test/RenderedResultsDisabledTest.java b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/test/RenderedResultsDisabledTest.java
index 867778d4ee832..805586405f21a 100644
--- a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/test/RenderedResultsDisabledTest.java
+++ b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/test/RenderedResultsDisabledTest.java
@@ -1,5 +1,6 @@
package io.quarkus.qute.deployment.test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import jakarta.enterprise.inject.Instance;
@@ -10,6 +11,7 @@
import org.junit.jupiter.api.extension.RegisterExtension;
import io.quarkus.qute.RenderedResults;
+import io.quarkus.qute.Template;
import io.quarkus.test.QuarkusUnitTest;
public class RenderedResultsDisabledTest {
@@ -25,9 +27,13 @@ public class RenderedResultsDisabledTest {
@Inject
Instance renderedResults;
+ @Inject
+ Template foo;
+
@Test
public void testRenderedResultsNotRegistered() {
assertTrue(renderedResults.isUnsatisfied());
+ assertEquals("Morna", foo.data("name", "Morna").render());
}
}
diff --git a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/TemplateProducer.java b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/TemplateProducer.java
index 55cf3151aec9a..ae7d0519d5e94 100644
--- a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/TemplateProducer.java
+++ b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/TemplateProducer.java
@@ -68,7 +68,7 @@ public class TemplateProducer {
templateVariants.put(entry.getKey(), var);
}
this.templateVariants = Collections.unmodifiableMap(templateVariants);
- this.renderedResults = launchMode == LaunchMode.TEST ? renderedResults.get() : null;
+ this.renderedResults = launchMode == LaunchMode.TEST && renderedResults.isResolvable() ? renderedResults.get() : null;
this.injectedTemplates = launchMode == LaunchMode.DEVELOPMENT ? Collections.synchronizedList(new ArrayList<>()) : null;
LOGGER.debugf("Initializing Qute variant templates: %s", templateVariants);
}
diff --git a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-welcome.js b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-welcome.js
index 74ee266f324e9..42814c4dd7c3c 100644
--- a/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-welcome.js
+++ b/extensions/vertx-http/dev-ui-resources/src/main/resources/dev-ui/qwc/qwc-welcome.js
@@ -1,10 +1,16 @@
import { LitElement, html, css } from 'lit';
import { devuiState } from 'devui-state';
+import { JsonRpc } from 'jsonrpc';
+import '@vaadin/progress-bar';
+import '@vaadin/grid';
+import { columnBodyRenderer } from '@vaadin/grid/lit.js';
+import '@vaadin/grid/vaadin-grid-sort-column.js';
/**
* This component shows the welcome screen
*/
export class QwcWelcome extends LitElement {
+ jsonRpc = new JsonRpc("devui-endpoints");
static styles = css`
a { color: inherit; }
@@ -109,14 +115,20 @@ export class QwcWelcome extends LitElement {
}
`;
- static properties = {};
+ static properties = {
+ _info: {state: true}
+ };
constructor() {
super();
+ this._info = null;
}
connectedCallback() {
super.connectedCallback();
+ this.jsonRpc.getJsonContent().then(jsonRpcResponse => {
+ this._info = jsonRpcResponse.result;
+ });
}
render() {
@@ -187,6 +199,7 @@ export class QwcWelcome extends LitElement {
Static assets: ${devuiState.welcomeData.resourcesDir}/META-INF/resources/
Code: ${devuiState.welcomeData.sourceDir}
+ ${this._renderEndpoints()}
${this._renderSelectedExtensions()}
@@ -202,6 +215,52 @@ export class QwcWelcome extends LitElement {
`;
}
+ _renderEndpoints(){
+ if (this._info) {
+ const typeTemplates = [];
+ for (const [type, list] of Object.entries(this._info)) {
+ if(type !== "Additional endpoints")
+ typeTemplates.push(html`${this._renderType(type,list)}`);
+ }
+ return html`${typeTemplates}`;
+ }else{
+ return html`
+
+
Fetching information...
+
+
+ `;
+ }
+ }
+
+ _renderType(type, items){
+ return html`${type}
+
+
+
+
+
+
+ `;
+ }
+
+ _uriRenderer(endpoint) {
+ if (endpoint.uri) {
+ return html`${endpoint.uri}`;
+ }
+ }
+
+ _descriptionRenderer(endpoint) {
+ if (endpoint.description) {
+ return html`${endpoint.description}`;
+ }
+ }
+
_renderSelectedExtensions(){
if(devuiState.welcomeData.selectedExtensions){
return html`Selected extensions
diff --git a/integration-tests/hibernate-validator/pom.xml b/integration-tests/hibernate-validator/pom.xml
index edc6814da7d6f..6e02b8854f6ad 100644
--- a/integration-tests/hibernate-validator/pom.xml
+++ b/integration-tests/hibernate-validator/pom.xml
@@ -217,6 +217,24 @@
en
+
+
+
+ test-nondefault-timezone
+
+
+ --env TZ=Europe/Helsinki
+
+
+
+ integration-test
+ verify
+
+
+
diff --git a/integration-tests/hibernate-validator/src/main/java/io/quarkus/it/hibernate/validator/HibernateValidatorTestResource.java b/integration-tests/hibernate-validator/src/main/java/io/quarkus/it/hibernate/validator/HibernateValidatorTestResource.java
index d286eeb5446d3..12a223688dfc3 100644
--- a/integration-tests/hibernate-validator/src/main/java/io/quarkus/it/hibernate/validator/HibernateValidatorTestResource.java
+++ b/integration-tests/hibernate-validator/src/main/java/io/quarkus/it/hibernate/validator/HibernateValidatorTestResource.java
@@ -4,6 +4,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -23,6 +24,7 @@
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.PastOrPresent;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.groups.ConvertGroup;
import jakarta.ws.rs.Consumes;
@@ -321,6 +323,17 @@ public MyBeanWithGroups testRestEndPointValidationGroups_Delete(@PathParam("id")
return result;
}
+ @GET
+ @Path("/rest-end-point-clock-based-constraints")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String testClockBasedConstraints() {
+ ResultBuilder result = new ResultBuilder();
+
+ result.append(formatViolations(validator.validate(new Task())));
+
+ return result.build();
+ }
+
private String formatViolations(Set extends ConstraintViolation>> violations) {
if (violations.isEmpty()) {
return "passed";
@@ -447,4 +460,9 @@ private static class NestedBeanWithoutConstraints {
@SuppressWarnings("unused")
private String property;
}
+
+ public static class Task {
+ @PastOrPresent
+ public LocalDateTime created = LocalDateTime.now();
+ }
}
diff --git a/integration-tests/hibernate-validator/src/test/java/io/quarkus/it/hibernate/validator/HibernateValidatorFunctionalityTest.java b/integration-tests/hibernate-validator/src/test/java/io/quarkus/it/hibernate/validator/HibernateValidatorFunctionalityTest.java
index 880841201ec35..8ee69d6a73368 100644
--- a/integration-tests/hibernate-validator/src/test/java/io/quarkus/it/hibernate/validator/HibernateValidatorFunctionalityTest.java
+++ b/integration-tests/hibernate-validator/src/test/java/io/quarkus/it/hibernate/validator/HibernateValidatorFunctionalityTest.java
@@ -532,4 +532,12 @@ public void testRestEndPointValidationGroups_result() {
response.body(containsString("must not be null"));
}
}
+
+ @Test
+ void testClockBasedConstraints() {
+ RestAssured.when()
+ .get("/hibernate-validator/test/rest-end-point-clock-based-constraints")
+ .then()
+ .body(is("passed"));
+ }
}
diff --git a/integration-tests/kafka-ssl/src/main/java/io/quarkus/it/kafka/ssl/SslKafkaEndpoint.java b/integration-tests/kafka-ssl/src/main/java/io/quarkus/it/kafka/ssl/SslKafkaEndpoint.java
index 8f1f00f7df085..0a6fff74a6c50 100644
--- a/integration-tests/kafka-ssl/src/main/java/io/quarkus/it/kafka/ssl/SslKafkaEndpoint.java
+++ b/integration-tests/kafka-ssl/src/main/java/io/quarkus/it/kafka/ssl/SslKafkaEndpoint.java
@@ -4,6 +4,7 @@
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.ExecutionException;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
@@ -17,6 +18,7 @@
import org.apache.kafka.common.serialization.IntegerDeserializer;
import org.apache.kafka.common.serialization.StringDeserializer;
+import io.quarkus.kafka.client.runtime.KafkaAdminClient;
import io.smallrye.common.annotation.Identifier;
/**
@@ -29,8 +31,13 @@ public class SslKafkaEndpoint {
@Identifier("default-kafka-broker")
Map kafkaConfig;
+ @Inject
+ KafkaAdminClient adminClient;
+
@GET
- public String get(@QueryParam("format") CertificateFormat format) {
+ public String get(@QueryParam("format") CertificateFormat format) throws ExecutionException, InterruptedException {
+ // prevent admin client to be removed
+ adminClient.getTopics();
Consumer consumer = createConsumer(format);
final ConsumerRecords records = consumer.poll(Duration.ofMillis(60000));
if (records.isEmpty()) {