diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java index 6a63a6f9417ec..3ed6dfc61d8b1 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/PackageConfig.java @@ -160,6 +160,23 @@ interface JarConfig { @WithDefault("true") boolean addRunnerSuffix(); + /** + * Indicates a list of dependency for which the jar will use artifactId.type filename scheme + * Each dependency needs to be expressed in the following format: + *

+ * {@code groupId:artifactId[:[classifier][:[type]]]} + *

+ * With the classifier and type being optional (note that the brackets ({@code []}) denote optionality and are + * not a part of the syntax specification). + * The group ID and artifact ID must be present and non-empty. + *

+ * If the type is missing, the artifact is assumed to be of type {@code jar}. + *

+ * This parameter is optional; if absent, jar names will use groupId.artifactId[-version][-classifier].type scheme + */ + @WithDefault("com.sap.conn.jco:sapjco3::jar,com.sap.conn.idoc:sapidoc3::jar") + Optional> forceUseArtifactIdOnlyAsName(); + /** * AppCDS archive sub-configuration. * This configuration only applies to certain JAR types. diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/jar/FastJarBuilder.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/jar/FastJarBuilder.java index e25888afb2be4..c7a2ad7a07198 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/jar/FastJarBuilder.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/jar/FastJarBuilder.java @@ -56,6 +56,7 @@ import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; import io.quarkus.deployment.util.FileUtil; import io.quarkus.maven.dependency.ArtifactKey; +import io.quarkus.maven.dependency.GACT; import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.sbom.ApplicationComponent; import io.quarkus.sbom.ApplicationManifestConfig; @@ -409,8 +410,20 @@ private static void copyDependency(Set parentFirstArtifacts, Output if (runtimeArtifacts.containsKey(appDep.getKey())) { return; } + Set forceUseArtifactIdOnlyAsNameSet = packageConfig.jar().forceUseArtifactIdOnlyAsName() + .orElse(Collections.emptySet()); + boolean forceUseArtifactIdOnlyAsName = forceUseArtifactIdOnlyAsNameSet.stream() + .anyMatch(gact -> gact.getGroupId().equals(appDep.getGroupId()) + && gact.getArtifactId().equals(appDep.getArtifactId()) + && gact.getType().equals(appDep.getType()) + && gact.getClassifier().equals(appDep.getClassifier())); for (Path resolvedDep : appDep.getResolvedPaths()) { - final String fileName = FastJarFormat.getJarFileName(appDep, resolvedDep); + String fileName; + if (forceUseArtifactIdOnlyAsName) { + fileName = appDep.getArtifactId() + "." + appDep.getType(); + } else { + fileName = FastJarFormat.getJarFileName(appDep, resolvedDep); + } final Path targetPath; if (allowParentFirst && parentFirstArtifacts.contains(appDep.getKey())) { diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/it/FastJarQuarkusIntegrationTestIT.java b/integration-tests/maven/src/test/java/io/quarkus/maven/it/FastJarQuarkusIntegrationTestIT.java index 2707eca2ba93a..c7ef6a29a3659 100644 --- a/integration-tests/maven/src/test/java/io/quarkus/maven/it/FastJarQuarkusIntegrationTestIT.java +++ b/integration-tests/maven/src/test/java/io/quarkus/maven/it/FastJarQuarkusIntegrationTestIT.java @@ -1,15 +1,27 @@ package io.quarkus.maven.it; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; import java.io.IOException; import org.apache.maven.shared.invoker.MavenInvocationException; import org.junit.jupiter.api.Test; @DisableForNative -public class FastJarQuarkusIntegrationTestIT extends QuarkusITBase { +class FastJarQuarkusIntegrationTestIT extends QuarkusITBase { @Test - public void testFastJar() throws MavenInvocationException, IOException { + void testFastJar() throws MavenInvocationException, IOException { doTest("qit-fast-jar", "fastjar"); } + + @Test + void testFastJarWithForceUseArtifactIdOnlyAsName() throws MavenInvocationException, IOException { + File testDir = doTest("qit-fast-jar-forceUseArtifactId", "fastjar", + "-Dquarkus.package.jar.force-use-artifact-id-only-as-name=io.quarkus:quarkus-reactive-routes"); + System.out.println(testDir); + File forceNamedFile = new File(testDir, "target/quarkus-app/lib/main/quarkus-reactive-routes.jar"); + assertThat(forceNamedFile).exists(); + } } diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/it/QuarkusITBase.java b/integration-tests/maven/src/test/java/io/quarkus/maven/it/QuarkusITBase.java index 08c98d3e4e16e..900c3ccecb8a2 100644 --- a/integration-tests/maven/src/test/java/io/quarkus/maven/it/QuarkusITBase.java +++ b/integration-tests/maven/src/test/java/io/quarkus/maven/it/QuarkusITBase.java @@ -17,13 +17,14 @@ // meant to test that @QuarkusIntegrationTest can properly launch jars abstract class QuarkusITBase extends MojoTestBase { - void doTest(String projectName, String profile) throws MavenInvocationException, IOException { + File doTest(String projectName, String profile, String additionalBuildParameter) + throws MavenInvocationException, IOException { File testDir = initProject("projects/reactive-routes", "projects/" + projectName); RunningInvoker packageInvocation = new RunningInvoker(testDir, false); MavenProcessInvocationResult packageInvocationResult = packageInvocation .execute(Arrays.asList("package", "-B", - "-D" + profile), Collections.emptyMap()); + "-D" + profile, additionalBuildParameter), Collections.emptyMap()); await().atMost(3, TimeUnit.MINUTES) .until(() -> packageInvocationResult.getProcess() != null && !packageInvocationResult.getProcess().isAlive()); @@ -39,5 +40,10 @@ void doTest(String projectName, String profile) throws MavenInvocationException, .until(() -> integrationTestsInvocationResult.getProcess() != null && !integrationTestsInvocationResult.getProcess().isAlive()); assertThat(integrationTestsInvocation.log()).containsIgnoringCase("BUILD SUCCESS"); + return testDir; + } + + File doTest(String projectName, String profile) throws MavenInvocationException, IOException { + return doTest(projectName, profile, ""); } }