diff --git a/core/deployment/src/main/java/io/quarkus/deployment/Capability.java b/core/deployment/src/main/java/io/quarkus/deployment/Capability.java index 776b85fcb21cf..5f8d5a41a4e0f 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/Capability.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/Capability.java @@ -42,6 +42,7 @@ public interface Capability { String REST = QUARKUS_PREFIX + "rest"; String REST_CLIENT = REST + ".client"; String REST_CLIENT_REACTIVE = REST_CLIENT + ".reactive"; + String REST_CLIENT_REACTIVE_JACKSON = REST_CLIENT_REACTIVE + ".jackson"; String REST_JACKSON = REST + ".jackson"; String REST_JSONB = REST + ".jsonb"; diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java index 080ac28efb2e2..2dd58393dc4d2 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java @@ -354,6 +354,7 @@ public void suppressNonRuntimeConfigChanged( suppressNonRuntimeConfigChanged.produce(new SuppressNonRuntimeConfigChangedWarningBuildItem("quarkus.uuid")); suppressNonRuntimeConfigChanged.produce(new SuppressNonRuntimeConfigChangedWarningBuildItem("quarkus.default-locale")); suppressNonRuntimeConfigChanged.produce(new SuppressNonRuntimeConfigChangedWarningBuildItem("quarkus.locales")); + suppressNonRuntimeConfigChanged.produce(new SuppressNonRuntimeConfigChangedWarningBuildItem("quarkus.test.arg-line")); } /** diff --git a/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java b/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java index 1ef4fb6b8e3b3..000b96d0fede8 100644 --- a/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java +++ b/core/processor/src/main/java/io/quarkus/annotation/processor/ExtensionAnnotationProcessor.java @@ -512,7 +512,7 @@ private void processCtorConfigItem(ExecutableElement ctor, Properties javadocPro final String docComment = getRequiredJavadoc(ctor); final StringBuilder buf = new StringBuilder(); appendParamTypes(ctor, buf); - javadocProps.put(className + Constants.DOT + buf.toString(), docComment); + javadocProps.put(className + Constants.DOT + buf, docComment); } private void processMethodConfigItem(ExecutableElement method, Properties javadocProps, String className) { @@ -520,12 +520,14 @@ private void processMethodConfigItem(ExecutableElement method, Properties javado final StringBuilder buf = new StringBuilder(); buf.append(method.getSimpleName().toString()); appendParamTypes(method, buf); - javadocProps.put(className + Constants.DOT + buf.toString(), docComment); + javadocProps.put(className + Constants.DOT + buf, docComment); } private void processMethodConfigMapping(ExecutableElement method, Properties javadocProps, String className) { - final String docComment = getRequiredJavadoc(method); - javadocProps.put(className + Constants.DOT + method.getSimpleName().toString(), docComment); + if (method.getModifiers().contains(Modifier.ABSTRACT)) { + final String docComment = getRequiredJavadoc(method); + javadocProps.put(className + Constants.DOT + method.getSimpleName().toString(), docComment); + } } private void processConfigGroup(RoundEnvironment roundEnv, TypeElement annotation) { diff --git a/docs/src/main/asciidoc/lra.adoc b/docs/src/main/asciidoc/lra.adoc index fb584080fe4e5..0f3fcf9402d0a 100644 --- a/docs/src/main/asciidoc/lra.adoc +++ b/docs/src/main/asciidoc/lra.adoc @@ -96,7 +96,7 @@ quarkus.lra.coordinator-url=http://localhost:8080/lra-coordinator ---- For a Narayana coordinator the path component of the url is normally `lra-coordinator`. -Coordinators can be obtained from `https://hub.docker.com/r/jbosstm/lra-coordinator` +Coordinators can be obtained from https://quay.io/repository/jbosstm/lra-coordinator or you can build your own coordinator using a maven pom that includes the appropriate dependencies. A Quarkus quickstart will be provided to show how to do this, or you can take a look at one of the https://github.com/jbosstm/quickstart/tree/master/rts/lra-examples/lra-coordinator[Narayana quickstarts]. diff --git a/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/ConfigRecorder.java b/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/ConfigRecorder.java index 5b5331cd74f53..a94e21620999a 100644 --- a/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/ConfigRecorder.java +++ b/extensions/arc/runtime/src/main/java/io/quarkus/arc/runtime/ConfigRecorder.java @@ -60,7 +60,7 @@ public void validateConfigProperties(Set properties) { ConfigProducerUtil.getValue(property.getName(), effectivePropertyType, property.getDefaultValue(), config); } catch (Exception e) { msg.append("Failed to load config value of type ").append(effectivePropertyType).append(" for: ") - .append(property.getName()); + .append(property.getName()).append(System.lineSeparator()); problems.add(property.getName()); suppressed.add(e); } diff --git a/extensions/caffeine/runtime/src/main/java/io/quarkus/caffeine/runtime/graal/CacheConstructorsFeature.java b/extensions/caffeine/runtime/src/main/java/io/quarkus/caffeine/runtime/graal/CacheConstructorsFeature.java index 8456a80860cf2..ac2bf2db5b498 100644 --- a/extensions/caffeine/runtime/src/main/java/io/quarkus/caffeine/runtime/graal/CacheConstructorsFeature.java +++ b/extensions/caffeine/runtime/src/main/java/io/quarkus/caffeine/runtime/graal/CacheConstructorsFeature.java @@ -80,6 +80,8 @@ public static String[] typesNeedingConstructorsRegistered() { "com.github.benmanes.caffeine.cache.PSMS", "com.github.benmanes.caffeine.cache.PSW", "com.github.benmanes.caffeine.cache.PSMW", + "com.github.benmanes.caffeine.cache.PSAMW", + "com.github.benmanes.caffeine.cache.PSAWMW", "com.github.benmanes.caffeine.cache.PSWMS", "com.github.benmanes.caffeine.cache.PSWMW", "com.github.benmanes.caffeine.cache.SILMS", @@ -88,6 +90,7 @@ public static String[] typesNeedingConstructorsRegistered() { "com.github.benmanes.caffeine.cache.SSLMS", "com.github.benmanes.caffeine.cache.SSMS", "com.github.benmanes.caffeine.cache.SSMSA", + "com.github.benmanes.caffeine.cache.SSMSAW", "com.github.benmanes.caffeine.cache.SSMSW", "com.github.benmanes.caffeine.cache.SSW", }; @@ -102,6 +105,7 @@ public static String[] typesNeedingConstructorsRegisteredWhenRecordingStats() { "com.github.benmanes.caffeine.cache.SSSMS", "com.github.benmanes.caffeine.cache.SSSMSA", "com.github.benmanes.caffeine.cache.SSSMSW", + "com.github.benmanes.caffeine.cache.SSSMSAW", "com.github.benmanes.caffeine.cache.SSSW" }; } diff --git a/extensions/jdbc/jdbc-oracle/deployment/src/main/java/io/quarkus/jdbc/oracle/deployment/OracleMetadataOverrides.java b/extensions/jdbc/jdbc-oracle/deployment/src/main/java/io/quarkus/jdbc/oracle/deployment/OracleMetadataOverrides.java index fbabaecceb2d5..892ef190c539f 100644 --- a/extensions/jdbc/jdbc-oracle/deployment/src/main/java/io/quarkus/jdbc/oracle/deployment/OracleMetadataOverrides.java +++ b/extensions/jdbc/jdbc-oracle/deployment/src/main/java/io/quarkus/jdbc/oracle/deployment/OracleMetadataOverrides.java @@ -9,6 +9,7 @@ import io.quarkus.deployment.builditem.nativeimage.NativeImageAllowIncompleteClasspathBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem; +import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem; import io.quarkus.maven.dependency.ArtifactKey; /** @@ -66,7 +67,8 @@ void build(BuildProducer reflectiveClass) { } @BuildStep - void runtimeInitializeDriver(BuildProducer runtimeInitialized) { + void runtimeInitializeDriver(BuildProducer runtimeInitialized, + BuildProducer runtimeReinitialized) { //These re-implement all the "--initialize-at-build-time" arguments found in the native-image.properties : // Override: the original metadata marks the drivers as "runtime initialized" but this makes it incompatible with @@ -93,10 +95,14 @@ void runtimeInitializeDriver(BuildProducer run runtimeInitialized.produce(new RuntimeInitializedClassBuildItem("oracle.net.nt.TcpMultiplexer")); runtimeInitialized.produce(new RuntimeInitializedClassBuildItem("oracle.net.nt.TcpMultiplexer")); runtimeInitialized.produce(new RuntimeInitializedClassBuildItem("oracle.net.nt.TcpMultiplexer$LazyHolder")); - runtimeInitialized - .produce(new RuntimeInitializedClassBuildItem("oracle.jdbc.driver.BlockSource$ThreadedCachingBlockSource")); - runtimeInitialized.produce(new RuntimeInitializedClassBuildItem( + + // Needs to be REinitialized to avoid problems when also using the Elasticsearch Java client + // See https://github.com/quarkusio/quarkus/issues/31624#issuecomment-1457706253 + runtimeReinitialized.produce(new RuntimeReinitializedClassBuildItem( + "oracle.jdbc.driver.BlockSource$ThreadedCachingBlockSource")); + runtimeReinitialized.produce(new RuntimeReinitializedClassBuildItem( "oracle.jdbc.driver.BlockSource$ThreadedCachingBlockSource$BlockReleaser")); + runtimeInitialized.produce(new RuntimeInitializedClassBuildItem("oracle.jdbc.xa.client.OracleXADataSource")); runtimeInitialized.produce(new RuntimeInitializedClassBuildItem("oracle.jdbc.replay.OracleXADataSourceImpl")); runtimeInitialized.produce(new RuntimeInitializedClassBuildItem("oracle.jdbc.datasource.OracleXAConnection")); diff --git a/extensions/jdbc/jdbc-oracle/deployment/src/main/java/io/quarkus/jdbc/oracle/deployment/OracleNativeImage.java b/extensions/jdbc/jdbc-oracle/deployment/src/main/java/io/quarkus/jdbc/oracle/deployment/OracleNativeImage.java index 8778e677ca104..51053a2fb0765 100644 --- a/extensions/jdbc/jdbc-oracle/deployment/src/main/java/io/quarkus/jdbc/oracle/deployment/OracleNativeImage.java +++ b/extensions/jdbc/jdbc-oracle/deployment/src/main/java/io/quarkus/jdbc/oracle/deployment/OracleNativeImage.java @@ -3,7 +3,6 @@ import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem; /** * @author Sanne Grinovero @@ -35,10 +34,4 @@ void reflection(BuildProducer reflectiveClass) { reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, "com.sun.jndi.rmi.registry.RegistryContextFactory")); } - @BuildStep - void runtimeInitialization(BuildProducer runtimeInitializedClass) { - runtimeInitializedClass - .produce(new RuntimeInitializedClassBuildItem("oracle.jdbc.driver.BlockSource$ThreadedCachingBlockSource")); - } - } diff --git a/extensions/keycloak-admin-client-reactive/runtime/src/main/java/resources/META-INF/quarkus-extension.yaml b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/resources/META-INF/quarkus-extension.yaml new file mode 100644 index 0000000000000..92570a014faf2 --- /dev/null +++ b/extensions/keycloak-admin-client-reactive/runtime/src/main/java/resources/META-INF/quarkus-extension.yaml @@ -0,0 +1,14 @@ +--- +artifact: ${project.groupId}:${project.artifactId}:${project.version} +name: "Reactive Keycloak Admin Client" +metadata: + keywords: + - "keycloak" + - "keycloak-admin-client" + - "admin" + - "openid-connect" + - "reactive" + categories: + - "security" + - "reactive" + status: "stable" \ No newline at end of file diff --git a/extensions/kubernetes-client/deployment-internal/pom.xml b/extensions/kubernetes-client/deployment-internal/pom.xml index cdc98dd79a965..439a68d1f9472 100644 --- a/extensions/kubernetes-client/deployment-internal/pom.xml +++ b/extensions/kubernetes-client/deployment-internal/pom.xml @@ -38,16 +38,6 @@ io.quarkus quarkus-devservices-deployment - - com.dajudge.kindcontainer - kindcontainer - - - junit - junit - - - diff --git a/extensions/kubernetes-client/deployment/pom.xml b/extensions/kubernetes-client/deployment/pom.xml index 8e0de1efd6ad2..285cecb1f4da4 100644 --- a/extensions/kubernetes-client/deployment/pom.xml +++ b/extensions/kubernetes-client/deployment/pom.xml @@ -25,6 +25,21 @@ io.quarkus quarkus-jackson-deployment + + com.dajudge.kindcontainer + kindcontainer + + + junit + junit + + + + + io.quarkus + quarkus-junit5-internal + test + diff --git a/extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/NoQuarkusTestKubernetesClient.java b/extensions/kubernetes-client/deployment/src/main/java/io/quarkus/kubernetes/client/deployment/NoQuarkusTestKubernetesClient.java similarity index 100% rename from extensions/kubernetes-client/deployment-internal/src/main/java/io/quarkus/kubernetes/client/deployment/NoQuarkusTestKubernetesClient.java rename to extensions/kubernetes-client/deployment/src/main/java/io/quarkus/kubernetes/client/deployment/NoQuarkusTestKubernetesClient.java diff --git a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/LiquibaseLenientZipPathHandler.java b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/LiquibaseLenientZipPathHandler.java new file mode 100644 index 0000000000000..143dd5e291ba8 --- /dev/null +++ b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/LiquibaseLenientZipPathHandler.java @@ -0,0 +1,24 @@ +package io.quarkus.liquibase; + +import java.io.FileNotFoundException; + +import liquibase.resource.ResourceAccessor; +import liquibase.resource.ZipPathHandler; + +// https://github.com/liquibase/liquibase/issues/3524#issuecomment-1465282155 +public class LiquibaseLenientZipPathHandler extends ZipPathHandler { + + @Override + public int getPriority(String root) { + if (root != null && root.startsWith("jar:") && root.contains("!/")) { + return PRIORITY_SPECIALIZED; + } + return PRIORITY_NOT_APPLICABLE; + } + + @Override + public ResourceAccessor getResourceAccessor(String root) throws FileNotFoundException { + int idx = root.indexOf("!/"); + return super.getResourceAccessor(idx > 0 ? root.substring(0, idx) : root); + } +} \ No newline at end of file diff --git a/extensions/liquibase/runtime/src/main/resources/META-INF/services/liquibase.resource.PathHandler b/extensions/liquibase/runtime/src/main/resources/META-INF/services/liquibase.resource.PathHandler new file mode 100644 index 0000000000000..3ab18217b94b6 --- /dev/null +++ b/extensions/liquibase/runtime/src/main/resources/META-INF/services/liquibase.resource.PathHandler @@ -0,0 +1 @@ +io.quarkus.liquibase.LiquibaseLenientZipPathHandler diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java index 7af0eb4bcea36..721d56e9f8350 100644 --- a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/QuteProcessor.java @@ -647,6 +647,7 @@ public void beforeParsing(ParserHelper parserHelper) { @BuildStep void validateCheckedFragments(List validations, List expressionMatches, + List templateGlobals, BeanArchiveIndexBuildItem beanArchiveIndex, BuildProducer validationErrors) { @@ -657,6 +658,8 @@ void validateCheckedFragments(List validatio Map assignableCache = new HashMap<>(); String[] hintPrefixes = { LoopSectionHelper.Factory.HINT_PREFIX, WhenSectionHelper.Factory.HINT_PREFIX, SetSectionHelper.Factory.HINT_PREFIX }; + Set globals = templateGlobals.stream().map(TemplateGlobalBuildItem::getName) + .collect(Collectors.toUnmodifiableSet()); for (CheckedFragmentValidationBuildItem validation : validations) { Map paramNamesToTypes = new HashMap<>(); @@ -672,33 +675,40 @@ void validateCheckedFragments(List validatio } for (Expression expression : validation.fragmentExpressions) { - // Note that we ignore literals and expressions with no type info and expressions with a hint referencing an expression from inside the fragment - if (expression.isLiteral()) { + // Note that we ignore: + // - literals, + // - globals, + // - expressions with no type info, + // - loop metadata; e.g. |java.lang.Integer| + // - expressions with a hint referencing an expression from inside the fragment + if (expression.isLiteral() || globals.contains(expression.getParts().get(0).getName())) { continue; } - if (expression.hasTypeInfo()) { - Info info = TypeInfos.create(expression, index, null).get(0); - if (info.isTypeInfo()) { - // |org.acme.Foo|.name - paramNamesToTypes.put(expression.getParts().get(0).getName(), info.asTypeInfo().resolvedType); - } else if (info.hasHints()) { - // foo.name - hintLoop: for (String helperHint : info.asHintInfo().hints) { - for (String prefix : hintPrefixes) { - if (helperHint.startsWith(prefix)) { - int generatedId = parseHintId(helperHint, prefix); - Expression localExpression = findExpression(generatedId, validation.fragmentExpressions); - if (localExpression == null) { - Match match = matchResults.getMatch(generatedId); - if (match == null) { - throw new IllegalStateException( - "Match result not found for expression [" + expression.toOriginalString() - + "] in: " - + validation.templateId); - } - paramNamesToTypes.put(expression.getParts().get(0).getName(), match.type); - break hintLoop; + String typeInfo = expression.getParts().get(0).getTypeInfo(); + if (typeInfo == null || (typeInfo != null && typeInfo.endsWith(LoopSectionHelper.Factory.HINT_METADATA))) { + continue; + } + Info info = TypeInfos.create(expression, index, null).get(0); + if (info.isTypeInfo()) { + // |org.acme.Foo|.name + paramNamesToTypes.put(expression.getParts().get(0).getName(), info.asTypeInfo().resolvedType); + } else if (info.hasHints()) { + // foo.name + hintLoop: for (String helperHint : info.asHintInfo().hints) { + for (String prefix : hintPrefixes) { + if (helperHint.startsWith(prefix)) { + int generatedId = parseHintId(helperHint, prefix); + Expression localExpression = findExpression(generatedId, validation.fragmentExpressions); + if (localExpression == null) { + Match match = matchResults.getMatch(generatedId); + if (match == null) { + throw new IllegalStateException( + "Match result not found for expression [" + expression.toOriginalString() + + "] in: " + + validation.templateId); } + paramNamesToTypes.put(expression.getParts().get(0).getName(), match.type); + break hintLoop; } } } diff --git a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/typesafe/fragment/CheckedTemplateFragmentTest.java b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/typesafe/fragment/CheckedTemplateFragmentTest.java index 6f7f7ba7af2cb..c5a7cb3502be3 100644 --- a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/typesafe/fragment/CheckedTemplateFragmentTest.java +++ b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/typesafe/fragment/CheckedTemplateFragmentTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import io.quarkus.qute.CheckedTemplate; +import io.quarkus.qute.TemplateGlobal; import io.quarkus.qute.TemplateInstance; import io.quarkus.test.QuarkusUnitTest; @@ -20,21 +21,30 @@ public class CheckedTemplateFragmentTest { .addClasses(Templates.class, Item.class) .addAsResource(new StringAsset( "{#each items}{#fragment id='item'}{it.name}{#if it.name.length > 5} is a long name{/if}{/fragment}{/each}"), - "templates/CheckedTemplateFragmentTest/items.html")); + "templates/CheckedTemplateFragmentTest/items.html") + .addAsResource(new StringAsset( + "{#fragment id=foo}{#for i in bar}{i_count}. <{i}>{#if i_hasNext}, {/if}{/for}{/fragment}"), + "templates/CheckedTemplateFragmentTest/foos.html")); @Test public void testFragment() { assertEquals("Foo", Templates.items(null).getFragment("item").data("it", new Item("Foo")).render()); assertEquals("Foo", Templates.items$item(new Item("Foo")).render()); assertEquals("FooAndBar is a long name", Templates.items$item(new Item("FooAndBar")).render()); + assertEquals("1. <1>, 2. <2>, 3. <3>, 4. <4>, 5. <5>", Templates.foos$foo().render()); } @CheckedTemplate public static class Templates { + @TemplateGlobal + static int bar = 5; + static native TemplateInstance items(List items); static native TemplateInstance items$item(Item it); + + static native TemplateInstance foos$foo(); } } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSortedSetCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSortedSetCommands.java index d0e63dee9960c..b6bf0d93c508d 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSortedSetCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSortedSetCommands.java @@ -734,6 +734,9 @@ protected String getScoreAsString(double score) { final List> decodeAsListOfScoredValues(Response response) { List> list = new ArrayList<>(); + if (!response.iterator().hasNext()) { + return Collections.emptyList(); + } if (response.iterator().next().type() == ResponseType.BULK) { // Redis 5 V current = null; diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortedSetCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortedSetCommandsTest.java index bb59e5f8acd19..b5f14cfad65de 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortedSetCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/SortedSetCommandsTest.java @@ -468,6 +468,12 @@ void zrevrange() { .isEqualTo(List.of(Place.suze, Place.grignan, Place.crussol)); } + @Test + @RequiresRedis6OrHigher + void zrevrangeWithScoreEmpty() { + assertThat(ds.sortedSet(String.class).zrangeWithScores("top-products", 0, 2, new ZRangeArgs().rev())).isEmpty(); + } + @Test @RequiresRedis6OrHigher void zrevrangeWithScores() { diff --git a/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientConfig.java b/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientConfig.java index 7d85ffc3f58e6..1b290a754a214 100644 --- a/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientConfig.java +++ b/extensions/resteasy-classic/rest-client-config/runtime/src/main/java/io/quarkus/restclient/config/RestClientConfig.java @@ -200,7 +200,7 @@ public class RestClientConfig { /** * If set to false disables the keep alive completely. */ - @ConfigItem(defaultValue = "true") + @ConfigItem public Optional keepAliveEnabled; /** diff --git a/extensions/resteasy-classic/resteasy/deployment/src/test/java/io/quarkus/resteasy/test/config/ProviderConfigInjectionWarningsTest.java b/extensions/resteasy-classic/resteasy/deployment/src/test/java/io/quarkus/resteasy/test/config/ProviderConfigInjectionWarningsTest.java index 0eb3bdd0d6bd0..3a9cc5435455b 100644 --- a/extensions/resteasy-classic/resteasy/deployment/src/test/java/io/quarkus/resteasy/test/config/ProviderConfigInjectionWarningsTest.java +++ b/extensions/resteasy-classic/resteasy/deployment/src/test/java/io/quarkus/resteasy/test/config/ProviderConfigInjectionWarningsTest.java @@ -36,8 +36,13 @@ public class ProviderConfigInjectionWarningsTest { static final QuarkusUnitTest TEST = new QuarkusUnitTest() .setLogRecordPredicate(record -> record.getLevel().intValue() >= Level.WARNING.intValue()) .assertLogRecords(logRecords -> { - assertEquals(4, logRecords.size()); - Set messages = logRecords.stream().map(LogRecord::getMessage).collect(Collectors.toSet()); + Set messages = logRecords.stream() + .map(LogRecord::getMessage) + // filter out noise coming from RESTEasy + .filter(m -> !m.contains("RESTEASY004687")) + .collect(Collectors.toSet()); + + assertEquals(4, messages.size()); assertTrue(messages.contains( "Directly injecting a org.eclipse.microprofile.config.Config into a javax.ws.rs.ext.Provider may lead to unexpected results. To ensure proper results, please change the type of the field to javax.enterprise.inject.Instance. Offending field is 'config' of class 'io.quarkus.resteasy.test.config.ProviderConfigInjectionWarningsTest$FooProvider'")); assertTrue(messages.contains( diff --git a/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java b/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java index db778f22b64cb..f58d6841b0dca 100644 --- a/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java +++ b/extensions/resteasy-reactive/jaxrs-client-reactive/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java @@ -941,7 +941,7 @@ A more full example of generated client (with sub-resource) can is at the bottom MethodDescriptor handleHeaderDescriptor = MethodDescriptor.ofMethod(name, method.getName() + "$$" + methodIndex + "$$handleHeader$$" + paramIdx, Invocation.Builder.class, - Invocation.Builder.class, param.type); + Invocation.Builder.class, param.declaredType); MethodCreator handleHeaderMethod = classContext.classCreator.getMethodCreator( handleHeaderDescriptor).setModifiers(Modifier.PRIVATE); @@ -1358,7 +1358,7 @@ private void handleSubResourceMethod(List subMethod.getName() + "$$" + subMethodIndex + "$$handleHeader$$param" + inheritedParamIndex + "$" + subParamField.paramIndex, Invocation.Builder.class, - Invocation.Builder.class, param.type); + Invocation.Builder.class, param.declaredType); MethodCreator handleHeaderMethod = subContext.classCreator.getMethodCreator( handleHeaderDescriptor).setModifiers(Modifier.PRIVATE); @@ -1464,7 +1464,7 @@ private void handleSubResourceMethod(List MethodDescriptor handleHeaderDescriptor = MethodDescriptor.ofMethod(subName, subMethod.getName() + "$$" + subMethodIndex + "$$handleHeader$$" + paramIdx, Invocation.Builder.class, - Invocation.Builder.class, param.type); + Invocation.Builder.class, param.declaredType); MethodCreator handleHeaderMethod = subContext.classCreator.getMethodCreator( handleHeaderDescriptor).setModifiers(Modifier.PRIVATE); diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestResource.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestResource.java index 895a728bbd143..d186fce0e127a 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestResource.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestResource.java @@ -2,9 +2,13 @@ import java.math.BigDecimal; import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.Set; +import java.util.SortedSet; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.json.JsonArray; @@ -143,6 +147,42 @@ public Response filters(@Context HttpHeaders headers, @RestHeader("filter-reques return Response.ok().header("filter-request", header).build(); } + @GET + @Path("header-param-list") + public Object headerParamWithList(@HeaderParam("header") List list) { + return collectionToString(list); + } + + @GET + @Path("rest-header-list") + public Object restHeaderWithList(@RestHeader List header) { + return collectionToString(header); + } + + @GET + @Path("header-param-set") + public Object headerParamWithSet(@HeaderParam("header") Set list) { + return collectionToString(list); + } + + @GET + @Path("rest-header-set") + public Object restHeaderWithSet(@RestHeader Set header) { + return collectionToString(header); + } + + @GET + @Path("header-param-sorted-set") + public Object headerParamWithSortedSet(@HeaderParam("header") SortedSet list) { + return collectionToString(list); + } + + @GET + @Path("rest-header-sorted-set") + public String restHeaderWithSortedSet(@RestHeader SortedSet header) { + return collectionToString(header); + } + @GET @Path("feature-filters") public Response featureFilters(@Context HttpHeaders headers) { @@ -380,4 +420,8 @@ public String simplifiedResourceInfo(@Context SimpleResourceInfo simplifiedResou public String bigDecimalConverter(BigDecimal val) { return val.toString(); } + + private String collectionToString(Collection list) { + return (String) list.stream().map(Object::toString).collect(Collectors.joining(", ")); + } } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestTestCase.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestTestCase.java index ecadb812402d4..0281067a255c7 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestTestCase.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestTestCase.java @@ -17,6 +17,8 @@ import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import io.quarkus.test.QuarkusUnitTest; import io.restassured.RestAssured; @@ -313,6 +315,34 @@ public void testHeaderParamInCtor() { .then().body(Matchers.is(emptyString())); } + @ParameterizedTest + @ValueSource(strings = { + "rest-header-list", + "rest-header-set", + "rest-header-sorted-set" + }) + public void testRestHeaderUsingCollection(String path) { + RestAssured.with().header("header", "a", "b") + .get("/simple/" + path) + .then() + .statusCode(HttpStatus.SC_OK) + .body(Matchers.equalTo("a, b")); + } + + @ParameterizedTest + @ValueSource(strings = { + "header-param-list", + "header-param-set", + "header-param-sorted-set" + }) + public void testHeaderParamUsingCollection(String path) { + RestAssured.with().header("header", "a", "b") + .get("/simple/" + path) + .then() + .statusCode(HttpStatus.SC_OK) + .body(Matchers.equalTo("a, b")); + } + @Test public void testFormMap() { RestAssured diff --git a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/pom.xml b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/pom.xml index b075ab7f76f30..cf12a23456091 100644 --- a/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/pom.xml +++ b/extensions/resteasy-reactive/rest-client-reactive-jackson/runtime/pom.xml @@ -32,6 +32,11 @@ io.quarkus quarkus-extension-maven-plugin + + + io.quarkus.rest.client.reactive.jackson + + maven-compiler-plugin diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/HeaderTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/HeaderTest.java index 22d902c8e8406..24c585cf67b8c 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/HeaderTest.java +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/HeaderTest.java @@ -3,6 +3,13 @@ import static org.assertj.core.api.Assertions.assertThat; import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Collectors; import javax.enterprise.context.ApplicationScoped; import javax.ws.rs.GET; @@ -40,6 +47,15 @@ void testNullHeaders() { assertThat(client.cookieSub("bar", null).send(null, "bar4", "dummy")).isEqualTo("bar:null:null:bar4:X-My-Header/dummy"); } + @Test + void testHeadersWithCollections() { + String expected = "a, b, c, d"; + Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class); + assertThat(client.headersList(List.of("a", "b"), List.of("c", "d"))).isEqualTo(expected); + assertThat(client.headersSet(Set.of("a", "b"), Set.of("c", "d"))).isEqualTo(expected); + assertThat(client.headersSet(new TreeSet(List.of("a", "b")), new TreeSet(List.of("c", "d")))).isEqualTo(expected); + } + @Path("/") @ApplicationScoped public static class Resource { @@ -51,12 +67,50 @@ public String returnHeaders(@HeaderParam("foo") String header, @HeaderParam("foo return header + ":" + header2 + ":" + header3 + ":" + header4 + ":" + myHeaderName + "/" + headers.getHeaderString("X-My-Header"); } + + @GET + @Path("/headers-list") + public String headersList(@HeaderParam("foo") List foo, @RestHeader List header) { + return joiningCollections(foo, header); + } + + @GET + @Path("/headers-set") + public String headersSet(@HeaderParam("foo") Set foo, @RestHeader Set header) { + return joiningCollections(foo, header); + } + + @GET + @Path("/headers-sorted-set") + public String headersSortedSet(@HeaderParam("foo") SortedSet foo, @RestHeader SortedSet header) { + return joiningCollections(foo, header); + } + + private String joiningCollections(Collection... collections) { + List allHeaders = new ArrayList<>(); + for (Collection collection : collections) { + collection.forEach(v -> allHeaders.add((String) v)); + } + return allHeaders.stream().collect(Collectors.joining(", ")); + } } public interface Client { @Path("/") SubClient cookieSub(@HeaderParam("foo") String cookie, @HeaderParam("foo2") String cookie2); + + @GET + @Path("/headers-list") + String headersList(@HeaderParam("foo") List foo, @RestHeader List header); + + @GET + @Path("/headers-set") + String headersSet(@HeaderParam("foo") Set foo, @RestHeader Set header); + + @GET + @Path("/headers-sorted-set") + String headersSortedSet(@HeaderParam("foo") SortedSet foo, @RestHeader SortedSet header); } public interface SubClient { diff --git a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/MicroProfileRestClientRequestFilter.java b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/MicroProfileRestClientRequestFilter.java index 89982a4c8caaa..7506bccc7cfc7 100644 --- a/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/MicroProfileRestClientRequestFilter.java +++ b/extensions/resteasy-reactive/rest-client-reactive/runtime/src/main/java/io/quarkus/rest/client/reactive/runtime/MicroProfileRestClientRequestFilter.java @@ -1,6 +1,7 @@ package io.quarkus.rest.client.reactive.runtime; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -81,11 +82,13 @@ public void filter(ResteasyReactiveClientRequestContext requestContext) { } } - private static List castToListOfStrings(List values) { + private static List castToListOfStrings(Collection values) { List result = new ArrayList<>(); for (Object value : values) { if (value instanceof String) { result.add((String) value); + } else if (value instanceof Collection) { + result.addAll(castToListOfStrings((Collection) value)); } else { result.add(String.valueOf(value)); } diff --git a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/ScheduledBusinessMethodItem.java b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/ScheduledBusinessMethodItem.java index acce3bce521f4..b303fc18369e0 100644 --- a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/ScheduledBusinessMethodItem.java +++ b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/ScheduledBusinessMethodItem.java @@ -48,4 +48,8 @@ public boolean isNonBlocking() { return nonBlocking; } + public String getMethodDescription() { + return method.declaringClass().name() + "#" + method.name() + "()"; + } + } diff --git a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java index a5b314107ad2b..5751a086d5c46 100644 --- a/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java +++ b/extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java @@ -11,9 +11,11 @@ import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.Function; @@ -191,17 +193,23 @@ void validateScheduledBusinessMethods(SchedulerConfig config, List validationErrors) { List errors = new ArrayList<>(); Map encounteredIdentities = new HashMap<>(); + Set methodDescriptions = new HashSet<>(); for (ScheduledBusinessMethodItem scheduledMethod : scheduledMethods) { + if (!methodDescriptions.add(scheduledMethod.getMethodDescription())) { + errors.add(new IllegalStateException("Multiple @Scheduled methods of the same name declared on the same class: " + + scheduledMethod.getMethodDescription())); + continue; + } MethodInfo method = scheduledMethod.getMethod(); if (Modifier.isAbstract(method.flags())) { errors.add(new IllegalStateException("@Scheduled method must not be abstract: " - + method.declaringClass().name() + "#" + method.name() + "()")); + + scheduledMethod.getMethodDescription())); continue; } if (Modifier.isPrivate(method.flags())) { errors.add(new IllegalStateException("@Scheduled method must not be private: " - + method.declaringClass().name() + "#" + method.name() + "()")); + + scheduledMethod.getMethodDescription())); continue; } diff --git a/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/MultipleScheduledMethodsWithTheSameNameTest.java b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/MultipleScheduledMethodsWithTheSameNameTest.java new file mode 100644 index 0000000000000..2edadd011e600 --- /dev/null +++ b/extensions/scheduler/deployment/src/test/java/io/quarkus/scheduler/test/MultipleScheduledMethodsWithTheSameNameTest.java @@ -0,0 +1,36 @@ +package io.quarkus.scheduler.test; + +import javax.enterprise.inject.spi.DeploymentException; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.scheduler.Scheduled; +import io.quarkus.scheduler.ScheduledExecution; +import io.quarkus.test.QuarkusUnitTest; + +public class MultipleScheduledMethodsWithTheSameNameTest { + + @RegisterExtension + static final QuarkusUnitTest test = new QuarkusUnitTest() + .setExpectedException(DeploymentException.class) + .withApplicationRoot((jar) -> jar + .addClasses(BeanWithInvalidScheduledMethods.class)); + + @Test + public void test() throws InterruptedException { + } + + static class BeanWithInvalidScheduledMethods { + + @Scheduled(cron = "0/1 * * * * ?") + void foo() { + } + + @Scheduled(every = "10s") + void foo(ScheduledExecution execution) { + } + + } + +} diff --git a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java index 1e5caf7772d78..cbcb2cedfd245 100644 --- a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java +++ b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java @@ -223,6 +223,8 @@ private static void prepareBouncyCastleProvider(BuildProducer jar + .addClasses(BeanRegisteringRoute.class) + .addAsResource("conf/cors-same-origin-only.properties", "application.properties")); + + @Test + void corsSameOriginRequest() { + String origin = "http://localhost:8081"; + given().header("Origin", origin) + .get("/test").then() + .statusCode(200) + .header("Access-Control-Allow-Origin", origin); + } + + @Test + void corsInvalidSameOriginRequest() { + String origin = "http://externalhost:8081"; + given().header("Origin", origin) + .get("/test").then() + .statusCode(403) + .header("Access-Control-Allow-Origin", nullValue()); + } +} diff --git a/extensions/vertx-http/deployment/src/test/resources/conf/cors-same-origin-only.properties b/extensions/vertx-http/deployment/src/test/resources/conf/cors-same-origin-only.properties new file mode 100644 index 0000000000000..228ebaf416aed --- /dev/null +++ b/extensions/vertx-http/deployment/src/test/resources/conf/cors-same-origin-only.properties @@ -0,0 +1 @@ +quarkus.http.cors=true diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java index 30d1ad80ec87e..9722e703417e2 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java @@ -187,10 +187,13 @@ public void handle(RoutingContext event) { boolean allowsOrigin = wildcardOrigin; if (!allowsOrigin) { - allowsOrigin = !corsConfig.origins.isEmpty() - && (corsConfig.origins.get().contains(origin) - || isOriginAllowedByRegex(allowedOriginsRegex, origin) - || isSameOrigin(request, origin)); + if (!corsConfig.origins.isEmpty()) { + allowsOrigin = corsConfig.origins.get().contains(origin) + || isOriginAllowedByRegex(allowedOriginsRegex, origin) + || isSameOrigin(request, origin); + } else { + allowsOrigin = isSameOrigin(request, origin); + } } if (allowsOrigin) { diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSetResponseEntityRestHandler.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSetResponseEntityRestHandler.java index 0e8c53a0c25c6..67202ff3da724 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSetResponseEntityRestHandler.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSetResponseEntityRestHandler.java @@ -5,7 +5,6 @@ import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.StatusType; @@ -17,6 +16,7 @@ import org.jboss.resteasy.reactive.client.spi.ClientRestHandler; import org.jboss.resteasy.reactive.common.core.Serialisers; import org.jboss.resteasy.reactive.common.jaxrs.StatusTypeImpl; +import org.jboss.resteasy.reactive.common.util.QuarkusMultivaluedHashMap; import io.vertx.core.buffer.Buffer; @@ -88,7 +88,7 @@ private ByteArrayInputStream entityStreamOfAbortedResponseOf(RestClientRequestCo entity = Entity.entity(untypedEntity, mediaType); } // FIXME: pass headers? - Buffer buffer = context.writeEntity(entity, (MultivaluedMap) Serialisers.EMPTY_MULTI_MAP, + Buffer buffer = context.writeEntity(entity, new QuarkusMultivaluedHashMap<>(), Serialisers.NO_WRITER_INTERCEPTOR); return new ByteArrayInputStream(buffer.getBytes()); } diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientBuilderImpl.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientBuilderImpl.java index 9d323b012a410..062c9ecd26185 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientBuilderImpl.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientBuilderImpl.java @@ -173,9 +173,6 @@ public ClientBuilder clientLogger(ClientLogger clientLogger) { @Override public ClientImpl build() { - Buffer keyStore = asBuffer(this.keyStore, keystorePassword); - Buffer trustStore = asBuffer(this.trustStore, this.trustStorePassword); - HttpClientOptions options = Optional.ofNullable(configuration.getFromContext(HttpClientOptions.class)) .orElseGet(HttpClientOptions::new); @@ -185,6 +182,9 @@ public ClientImpl build() { options.setVerifyHost(false); } + char[] effectiveTrustStorePassword = trustStorePassword == null ? EMPTY_CHAR_ARARAY : trustStorePassword; + Buffer keyStore = asBuffer(this.keyStore, keystorePassword); + Buffer trustStore = asBuffer(this.trustStore, effectiveTrustStorePassword); if (keyStore != null || trustStore != null) { options = options.setSsl(true); if (keyStore != null) { @@ -196,7 +196,7 @@ public ClientImpl build() { if (trustStore != null) { JksOptions jks = new JksOptions(); jks.setValue(trustStore); - jks.setPassword(trustStorePassword == null ? "" : new String(trustStorePassword)); + jks.setPassword(new String(effectiveTrustStorePassword)); options.setTrustStoreOptions(jks); } } diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/InboundSseEventImpl.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/InboundSseEventImpl.java index 947097eed0841..015834e102d4f 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/InboundSseEventImpl.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/InboundSseEventImpl.java @@ -14,6 +14,7 @@ import org.jboss.resteasy.reactive.common.core.Serialisers; import org.jboss.resteasy.reactive.common.jaxrs.ConfigurationImpl; +import org.jboss.resteasy.reactive.common.util.QuarkusMultivaluedHashMap; public class InboundSseEventImpl implements InboundSseEvent { @@ -120,7 +121,7 @@ public T readData(GenericType type, MediaType mediaType) { InputStream in = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); try { return (T) ClientSerialisers.invokeClientReader(null, type.getRawType(), type.getType(), - mediaType, null, null, Serialisers.EMPTY_MULTI_MAP, + mediaType, null, null, new QuarkusMultivaluedHashMap<>(), serialisers, in, Serialisers.NO_READER_INTERCEPTOR, configuration); } catch (IOException e) { throw new UncheckedIOException(e); diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/logging/DefaultClientLogger.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/logging/DefaultClientLogger.java index 2f5b9c632e98e..a7884ecb1e561 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/logging/DefaultClientLogger.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/logging/DefaultClientLogger.java @@ -57,6 +57,8 @@ public void logRequest(HttpClientRequest request, Buffer body, boolean omitBody) private String bodyToString(Buffer body) { if (body == null) { return ""; + } else if (bodySize <= 0) { + return body.toString(); } else { String bodyAsString = body.toString(); return bodyAsString.substring(0, Math.min(bodySize, bodyAsString.length())); diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java index b279df0c8784b..cb56e0d49c651 100644 --- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java +++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java @@ -1362,13 +1362,28 @@ && isParameterContainerType(paramType.asClassType())) { elementType = paramType.name().toString(); handleTemporalParam(builder, paramType.name(), anns, currentMethodInfo); typeHandled = true; - } else if (paramType.name().equals(LIST) && (type == ParameterType.QUERY)) { // RESTEasy Classic handles the non-generic List type + } else if (paramType.name().equals(LIST) && (type == ParameterType.QUERY + || type == ParameterType.HEADER)) { // RESTEasy Classic handles the non-generic List type elementType = String.class.getName(); typeHandled = true; builder.setSingle(false); if (convertible) { handleListParam(existingConverters, errorLocation, hasRuntimeConverters, builder, elementType); } + } else if (paramType.name().equals(SET) && type == ParameterType.HEADER) { // RESTEasy Classic handles the non-generic Set type + elementType = String.class.getName(); + typeHandled = true; + builder.setSingle(false); + if (convertible) { + handleSetParam(existingConverters, errorLocation, hasRuntimeConverters, builder, elementType); + } + } else if (paramType.name().equals(SORTED_SET) && type == ParameterType.HEADER) { // RESTEasy Classic handles the non-generic SortedSet type + elementType = String.class.getName(); + typeHandled = true; + builder.setSingle(false); + if (convertible) { + handleSortedSetParam(existingConverters, errorLocation, hasRuntimeConverters, builder, elementType); + } } else if (paramType.kind() == Kind.ARRAY) { ArrayType at = paramType.asArrayType(); typeHandled = true; diff --git a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/Serialisers.java b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/Serialisers.java index 1f5020bae6a4b..e50003b531963 100644 --- a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/Serialisers.java +++ b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/Serialisers.java @@ -14,7 +14,6 @@ import javax.ws.rs.RuntimeType; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; @@ -31,7 +30,6 @@ public abstract class Serialisers { public static final Annotation[] NO_ANNOTATION = new Annotation[0]; public static final ReaderInterceptor[] NO_READER_INTERCEPTOR = new ReaderInterceptor[0]; - public static final MultivaluedMap EMPTY_MULTI_MAP = new QuarkusMultivaluedHashMap<>(); public static final WriterInterceptor[] NO_WRITER_INTERCEPTOR = new WriterInterceptor[0]; protected static final Map, Class> primitivesToWrappers = new HashMap<>(); // FIXME: spec says we should use generic type, but not sure how to pass that type from Jandex to reflection diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java index 2a2377cc3e021..705d96fcef9d7 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java @@ -198,16 +198,19 @@ public static boolean invokeWriter(ResteasyReactiveRequestContext context, Objec WriterInterceptor[] writerInterceptors = context.getWriterInterceptors(); boolean outputStreamSet = context.getOutputStream() != null; context.serverResponse().setPreCommitListener(HEADER_FUNCTION); + + RuntimeResource target = context.getTarget(); + Type genericType; + if (context.hasGenericReturnType()) { // make sure that when a Response with a GenericEntity was returned, we use it + genericType = context.getGenericReturnType(); + } else { + genericType = target == null ? null : target.getReturnType(); + } + try { if (writer instanceof ServerMessageBodyWriter && writerInterceptors == null && !outputStreamSet) { ServerMessageBodyWriter quarkusRestWriter = (ServerMessageBodyWriter) writer; - RuntimeResource target = context.getTarget(); - Type genericType; - if (context.hasGenericReturnType()) { // make sure that when a Response with a GenericEntity was returned, we use it - genericType = context.getGenericReturnType(); - } else { - genericType = target == null ? null : target.getReturnType(); - } + Class entityClass = entity.getClass(); if (quarkusRestWriter.isWriteable( entityClass, @@ -230,7 +233,7 @@ public static boolean invokeWriter(ResteasyReactiveRequestContext context, Objec context.setResponseContentType(mediaType); } if (writerInterceptors == null) { - writer.writeTo(entity, entity.getClass(), context.getGenericReturnType(), + writer.writeTo(entity, entity.getClass(), genericType, context.getAllAnnotations(), context.getResponseMediaType(), response.getHeaders(), context.getOrCreateOutputStream()); context.getOrCreateOutputStream().close(); diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java index 24de690d468c9..510bf092abbc5 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/SseUtil.java @@ -18,6 +18,7 @@ import org.jboss.resteasy.reactive.common.core.Serialisers; import org.jboss.resteasy.reactive.common.util.CommonSseUtil; +import org.jboss.resteasy.reactive.common.util.QuarkusMultivaluedHashMap; import org.jboss.resteasy.reactive.server.handlers.PublisherResponseHandler; import org.jboss.resteasy.reactive.server.jaxrs.OutboundSseEventImpl; import org.jboss.resteasy.reactive.server.spi.ServerHttpResponse; @@ -137,7 +138,7 @@ private static String serialiseDataToString(ResteasyReactiveRequestContext conte if (writer.isWriteable(entityClass, entityType, Serialisers.NO_ANNOTATION, mediaType)) { // FIXME: spec doesn't really say what headers we should use here writer.writeTo(entity, entityClass, entityType, Serialisers.NO_ANNOTATION, mediaType, - Serialisers.EMPTY_MULTI_MAP, baos); + new QuarkusMultivaluedHashMap<>(), baos); wrote = true; break; } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/StreamingUtil.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/StreamingUtil.java index 8f31bd6bbbe4e..c91e8938e2512 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/StreamingUtil.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/StreamingUtil.java @@ -14,6 +14,7 @@ import javax.ws.rs.ext.MessageBodyWriter; import org.jboss.resteasy.reactive.common.core.Serialisers; +import org.jboss.resteasy.reactive.common.util.QuarkusMultivaluedHashMap; import org.jboss.resteasy.reactive.server.StreamingOutputStream; import org.jboss.resteasy.reactive.server.handlers.PublisherResponseHandler; import org.jboss.resteasy.reactive.server.spi.ServerHttpResponse; @@ -65,7 +66,7 @@ private static byte[] serialiseEntity(ResteasyReactiveRequestContext context, Ob if (writer.isWriteable(entityClass, entityType, Serialisers.NO_ANNOTATION, mediaType)) { // FIXME: spec doesn't really say what headers we should use here writer.writeTo(entity, entityClass, entityType, Serialisers.NO_ANNOTATION, mediaType, - Serialisers.EMPTY_MULTI_MAP, baos); + new QuarkusMultivaluedHashMap<>(), baos); wrote = true; break; } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartMessageBodyWriter.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartMessageBodyWriter.java index f1bfb0484a99e..29907911d6339 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartMessageBodyWriter.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartMessageBodyWriter.java @@ -24,6 +24,7 @@ import org.jboss.resteasy.reactive.common.core.Serialisers; import org.jboss.resteasy.reactive.common.reflection.ReflectionBeanFactoryCreator; +import org.jboss.resteasy.reactive.common.util.QuarkusMultivaluedHashMap; import org.jboss.resteasy.reactive.multipart.FileDownload; import org.jboss.resteasy.reactive.server.NoopCloseAndFlushOutputStream; import org.jboss.resteasy.reactive.server.core.CurrentRequestManager; @@ -189,7 +190,7 @@ private void writeEntity(OutputStream os, Object entity, MediaType mediaType, Re try (NoopCloseAndFlushOutputStream writerOutput = new NoopCloseAndFlushOutputStream(os)) { // FIXME: spec doesn't really say what headers we should use here writer.writeTo(entity, entityClass, entityType, Serialisers.NO_ANNOTATION, mediaType, - Serialisers.EMPTY_MULTI_MAP, writerOutput); + new QuarkusMultivaluedHashMap<>(), writerOutput); wrote = true; } diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RequestDeserializeHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RequestDeserializeHandler.java index 701946a95ca5c..2bfc2b7e1dbf5 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RequestDeserializeHandler.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RequestDeserializeHandler.java @@ -47,12 +47,14 @@ public RequestDeserializeHandler(Class type, Type genericType, List> readers = serialisers.findReaders(null, type, effectiveRequestType, RuntimeType.SERVER); if (readers.isEmpty()) { + log.debugv("No matching MessageBodyReader found for type {0} and media type {1}", type, effectiveRequestType); throw new NotSupportedException(); } for (MessageBodyReader reader : readers) { @@ -101,6 +104,7 @@ public void handle(ResteasyReactiveRequestContext requestContext) throws Excepti return; } } + log.debugv("No matching MessageBodyReader found for type {0} and media type {1}", type, effectiveRequestType); throw new NotSupportedException("No supported MessageBodyReader found"); } diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestResource.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestResource.java index 5570f23f853ee..86104b92e38aa 100644 --- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestResource.java +++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestResource.java @@ -233,6 +233,12 @@ public TestClass writer() { return new TestClass(); } + @GET + @Path("uni-writer") + public Uni uniWriter() { + return Uni.createFrom().item(new TestClass()); + } + @GET @Path("fast-writer") @Produces("text/plain") diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestTestCase.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestTestCase.java index 1324e5ca35a5a..1a3c0266a27ae 100644 --- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestTestCase.java +++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestTestCase.java @@ -206,6 +206,8 @@ public void testWriter() { .then().body(Matchers.equalTo("OK")); RestAssured.get("/simple/writer") .then().body(Matchers.equalTo("WRITER")); + RestAssured.get("/simple/uni-writer") + .then().body(Matchers.equalTo("WRITER")); RestAssured.get("/simple/fast-writer") .then().body(Matchers.equalTo("OK")); diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/TestWriter.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/TestWriter.java index 18f8a2194846f..673f8dcdefd92 100644 --- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/TestWriter.java +++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/TestWriter.java @@ -26,7 +26,11 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotat public void writeTo(TestClass t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { - entityStream.write("WRITER".getBytes(StandardCharsets.UTF_8)); + if (genericType.getTypeName().equals(TestClass.class.getName())) { + entityStream.write("WRITER".getBytes(StandardCharsets.UTF_8)); + } else { + entityStream.write("INCORRECT GENERIC TYPE".getBytes(StandardCharsets.UTF_8)); + } } } diff --git a/integration-tests/liquibase/pom.xml b/integration-tests/liquibase/pom.xml index b799d8b7f1078..16f35371b55b6 100644 --- a/integration-tests/liquibase/pom.xml +++ b/integration-tests/liquibase/pom.xml @@ -12,6 +12,12 @@ quarkus-integration-test-liquibase Quarkus - Integration Tests - Liquibase Module that contains Liquibase related tests + + + false + ${skipTests} + + io.quarkus @@ -35,6 +41,11 @@ quarkus-junit5 test + + io.quarkus + quarkus-junit5-internal + test + io.quarkus quarkus-test-h2 @@ -126,6 +137,27 @@ + + maven-surefire-plugin + + + + prod-mode + test + + test + + + **/*PMT.java + ${skipPMTests} + + + + diff --git a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityPMT.java b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityPMT.java new file mode 100644 index 0000000000000..1bcb6cb604d16 --- /dev/null +++ b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityPMT.java @@ -0,0 +1,38 @@ +package io.quarkus.it.liquibase; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.LogFile; +import io.quarkus.test.QuarkusProdModeTest; + +public class LiquibaseFunctionalityPMT { + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .withApplicationRoot(jar -> jar + .addClasses(LiquibaseApp.class, LiquibaseFunctionalityResource.class) + .addAsResource("db") + .addAsResource("application.properties")) + .setApplicationName("liquibase-prodmode-test") + .setLogFileName("liquibase-prodmode-test.log") + .setRun(true); + + @LogFile + private Path logfile; + + @Test + public void test() { + LiquibaseFunctionalityTest.doTestLiquibaseQuarkusFunctionality(true); + } + + @AfterEach + void dumpLog() throws IOException { + System.out.println(Files.readString(logfile)); + } +} diff --git a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityTest.java b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityTest.java index a5079d99a5cec..52246e1254d69 100644 --- a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityTest.java +++ b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityTest.java @@ -15,12 +15,16 @@ public class LiquibaseFunctionalityTest { @Test @DisplayName("Migrates a schema correctly using integrated instance") public void testLiquibaseQuarkusFunctionality() { + doTestLiquibaseQuarkusFunctionality(isIncludeAllExpectedToWork()); + } + + static void doTestLiquibaseQuarkusFunctionality(boolean isIncludeAllExpectedToWork) { when() .get("/liquibase/update") .then() .body(is( "create-tables-1,test-1,create-view-inline,create-view-file-abs,create-view-file-rel," - + (isIncludeAllExpectedToWork() ? "includeAll-1,includeAll-2," : "") + + (isIncludeAllExpectedToWork ? "includeAll-1,includeAll-2," : "") + "json-create-tables-1,json-test-1," + "sql-create-tables-1,sql-test-1," + "yaml-create-tables-1,yaml-test-1," diff --git a/integration-tests/narayana-lra/src/test/java/org/acme/quickstart/lra/LRAParticipantTestResourceLifecycle.java b/integration-tests/narayana-lra/src/test/java/org/acme/quickstart/lra/LRAParticipantTestResourceLifecycle.java index afa58143853d8..c0fc6107985c7 100644 --- a/integration-tests/narayana-lra/src/test/java/org/acme/quickstart/lra/LRAParticipantTestResourceLifecycle.java +++ b/integration-tests/narayana-lra/src/test/java/org/acme/quickstart/lra/LRAParticipantTestResourceLifecycle.java @@ -22,7 +22,7 @@ public static String getCoordinatorEndpoint() { @Override public Map start() { - registry = new GenericContainer<>("jbosstm/lra-coordinator:5.12.0.Final") + registry = new GenericContainer<>("quay.io/jbosstm/lra-coordinator:latest") .withExposedPorts(8080) .withEnv("QUARKUS_PROFILE", "prod"); registry.start(); diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/TestMappingBuildTime.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/TestMappingBuildTime.java index 2701764b02835..a256fb4843b74 100644 --- a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/TestMappingBuildTime.java +++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/TestMappingBuildTime.java @@ -46,4 +46,8 @@ interface Group { */ String value(); } + + default void mustNotRequireDocs() { + + } } diff --git a/tcks/microprofile-lra/src/main/java/io/quarkus/tck/lra/LRACoordinatorManager.java b/tcks/microprofile-lra/src/main/java/io/quarkus/tck/lra/LRACoordinatorManager.java index 8721d08e41755..03d62f97fdd9b 100644 --- a/tcks/microprofile-lra/src/main/java/io/quarkus/tck/lra/LRACoordinatorManager.java +++ b/tcks/microprofile-lra/src/main/java/io/quarkus/tck/lra/LRACoordinatorManager.java @@ -19,7 +19,7 @@ public class LRACoordinatorManager { public void beforeClass( @Observes(precedence = DEFAULT_PRECEDENCE) org.jboss.arquillian.test.spi.event.suite.BeforeSuite event) { LOGGER.debug("Starting LRA coordinator on port " + coordinatorPort); - coordinatorContainer = new GenericContainer<>(DockerImageName.parse("jbosstm/lra-coordinator:latest")) + coordinatorContainer = new GenericContainer<>(DockerImageName.parse("quay.io/jbosstm/lra-coordinator:latest")) // lra-coordinator is a Quarkus service .withEnv("QUARKUS_HTTP_PORT", String.valueOf(coordinatorPort)) // need to run with host network because coordinator calls the TCK services from the container diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java index f3aa07dc40270..50b565e3b9f34 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java @@ -433,9 +433,10 @@ static Properties readQuarkusArtifactProperties(ExtensionContext context) { } throw new IllegalStateException(errorMessage); } - try { - Properties properties = new Properties(); - properties.load(new FileInputStream(artifactProperties.toFile())); + + Properties properties = new Properties(); + try (var fis = new FileInputStream(artifactProperties.toFile())) { + properties.load(fis); return properties; } catch (IOException e) { throw new UncheckedIOException(