diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/RemovedResourceBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/RemovedResourceBuildItem.java index 23b7ed6c8d2d4..da23a468a4b1d 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/RemovedResourceBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/RemovedResourceBuildItem.java @@ -6,17 +6,25 @@ import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.maven.dependency.GACT; +/** + * Represents resources to be removed from a dependency when packaging the application. + */ public final class RemovedResourceBuildItem extends MultiBuildItem { - private final GACT artifact; + private final ArtifactKey artifact; private final Set resources; - @Deprecated public RemovedResourceBuildItem(ArtifactKey artifact, Set resources) { - this.artifact = new GACT(artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(), artifact.getType()); + this.artifact = artifact; this.resources = resources; } + /** + * @deprecated In favor of {@link #RemovedResourceBuildItem(ArtifactKey, Set)} + * @param artifact artifact key + * @param resources resources to be removed from the application + */ + @Deprecated(forRemoval = true) public RemovedResourceBuildItem(GACT artifact, Set resources) { this.artifact = artifact; this.resources = resources; diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/CurateOutcomeBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/CurateOutcomeBuildStep.java index efdaf75ffdcf7..fc0487044bfef 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/CurateOutcomeBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/CurateOutcomeBuildStep.java @@ -1,9 +1,15 @@ package io.quarkus.deployment.steps; +import java.util.Map; +import java.util.Set; + import io.quarkus.deployment.BootstrapConfig; +import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.AppModelProviderBuildItem; +import io.quarkus.deployment.builditem.RemovedResourceBuildItem; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; +import io.quarkus.maven.dependency.ArtifactKey; public class CurateOutcomeBuildStep { @@ -13,4 +19,15 @@ public class CurateOutcomeBuildStep { CurateOutcomeBuildItem curateOutcome(AppModelProviderBuildItem appModelProvider) { return new CurateOutcomeBuildItem(appModelProvider.validateAndGet(config)); } + + @BuildStep + void removeResources(CurateOutcomeBuildItem curateOutcome, + BuildProducer removedResourceProducer) { + final Map> excludedResources = curateOutcome.getApplicationModel().getRemovedResources(); + if (!excludedResources.isEmpty()) { + for (Map.Entry> removed : excludedResources.entrySet()) { + removedResourceProducer.produce(new RemovedResourceBuildItem(removed.getKey(), removed.getValue())); + } + } + } } 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 cde6d75ae47cd..1ca65afd34c76 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,7 +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.maven.dependency.GACT; +import io.quarkus.maven.dependency.ArtifactKey; /** * The Oracle JDBC driver includes a {@literal META-INF/native-image} which enables a set @@ -118,13 +118,13 @@ NativeImageAllowIncompleteClasspathBuildItem naughtyDriver() { @BuildStep RemovedResourceBuildItem overrideSubstitutions() { - return new RemovedResourceBuildItem(GACT.fromString("com.oracle.database.jdbc:ojdbc11"), + return new RemovedResourceBuildItem(ArtifactKey.fromString("com.oracle.database.jdbc:ojdbc11"), Collections.singleton("oracle/nativeimage/Target_java_io_ObjectStreamClass.class")); } @BuildStep RemovedResourceBuildItem enhancedCharsetSubstitutions() { - return new RemovedResourceBuildItem(GACT.fromString("com.oracle.database.jdbc:ojdbc11"), + return new RemovedResourceBuildItem(ArtifactKey.fromString("com.oracle.database.jdbc:ojdbc11"), Collections.singleton("oracle/nativeimage/CharacterSetFeature.class")); } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppModel.java index 9491e56021a17..ea3a4a444b92c 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppModel.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/AppModel.java @@ -360,4 +360,10 @@ public Set getLowerPriorityArtifacts() { public Set getReloadableWorkspaceDependencies() { return new HashSet<>(localProjectArtifacts); } + + @Override + public Map> getRemovedResources() { + // not supported + return Map.of(); + } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModel.java index 3bd5831222067..e3c8ee185fe0e 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModel.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModel.java @@ -44,6 +44,13 @@ default Map getPlatformProperties() { Set getReloadableWorkspaceDependencies(); + /** + * Resources that should be removed from the classpath. + * + * @return resources that should be removed from the classpath + */ + Map> getRemovedResources(); + default WorkspaceModule getApplicationModule() { return getAppArtifact().getWorkspaceModule(); } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModelBuilder.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModelBuilder.java index 50a664ab81339..42cb9de86ca56 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModelBuilder.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/ApplicationModelBuilder.java @@ -25,6 +25,7 @@ public class ApplicationModelBuilder { public static final String PARENT_FIRST_ARTIFACTS = "parent-first-artifacts"; public static final String RUNNER_PARENT_FIRST_ARTIFACTS = "runner-parent-first-artifacts"; public static final String EXCLUDED_ARTIFACTS = "excluded-artifacts"; + public static final String REMOVED_RESOURCES_DOT = "removed-resources."; public static final String LESSER_PRIORITY_ARTIFACTS = "lesser-priority-artifacts"; private static final Logger log = Logger.getLogger(ApplicationModelBuilder.class); @@ -35,6 +36,7 @@ public class ApplicationModelBuilder { final Set parentFirstArtifacts = new HashSet<>(); final Set runnerParentFirstArtifacts = new HashSet<>(); final Set excludedArtifacts = new HashSet<>(); + final Map> excludedResources = new HashMap<>(0); final Set lesserPriorityArtifacts = new HashSet<>(); final Set reloadableWorkspaceModules = new HashSet<>(); final List extensionCapabilities = new ArrayList<>(); @@ -102,6 +104,11 @@ public ApplicationModelBuilder addExcludedArtifacts(List deps) { return this; } + public ApplicationModelBuilder addRemovedResources(ArtifactKey key, Set resources) { + this.excludedResources.computeIfAbsent(key, k -> new HashSet<>(resources.size())).addAll(resources); + return this; + } + public ApplicationModelBuilder addLesserPriorityArtifact(ArtifactKey deps) { this.lesserPriorityArtifacts.add(deps); return this; @@ -134,34 +141,69 @@ public WorkspaceModule.Mutable getOrCreateProjectModule(WorkspaceModuleId id, Fi * @param props The quarkus-extension.properties file */ public void handleExtensionProperties(Properties props, String extension) { - String parentFirst = props.getProperty(PARENT_FIRST_ARTIFACTS); - if (parentFirst != null) { - String[] artifacts = parentFirst.split(","); - for (String artifact : artifacts) { - parentFirstArtifacts.add(new GACT(artifact.split(":"))); + for (Map.Entry prop : props.entrySet()) { + if (prop.getValue() == null) { + continue; } - } - String runnerParentFirst = props.getProperty(RUNNER_PARENT_FIRST_ARTIFACTS); - if (runnerParentFirst != null) { - String[] artifacts = runnerParentFirst.split(","); - for (String artifact : artifacts) { - runnerParentFirstArtifacts.add(new GACT(artifact.split(":"))); + final String value = prop.getValue().toString(); + if (value.isBlank()) { + continue; } - } - String excluded = props.getProperty(EXCLUDED_ARTIFACTS); - if (excluded != null) { - String[] artifacts = excluded.split(","); - for (String artifact : artifacts) { - excludedArtifacts.add(new GACT(artifact.split(":"))); - log.debugf("Extension %s is excluding %s", extension, artifact); - } - } - String lesserPriority = props.getProperty(LESSER_PRIORITY_ARTIFACTS); - if (lesserPriority != null) { - String[] artifacts = lesserPriority.split(","); - for (String artifact : artifacts) { - lesserPriorityArtifacts.add(new GACT(artifact.split(":"))); - log.debugf("Extension %s is making %s a lesser priority artifact", extension, artifact); + final String name = prop.getKey().toString(); + switch (name) { + case PARENT_FIRST_ARTIFACTS: + for (String artifact : value.split(",")) { + parentFirstArtifacts.add(new GACT(artifact.split(":"))); + } + break; + case RUNNER_PARENT_FIRST_ARTIFACTS: + for (String artifact : value.split(",")) { + runnerParentFirstArtifacts.add(new GACT(artifact.split(":"))); + } + break; + case EXCLUDED_ARTIFACTS: + for (String artifact : value.split(",")) { + excludedArtifacts.add(new GACT(artifact.split(":"))); + log.debugf("Extension %s is excluding %s", extension, artifact); + } + break; + case LESSER_PRIORITY_ARTIFACTS: + String[] artifacts = value.split(","); + for (String artifact : artifacts) { + lesserPriorityArtifacts.add(new GACT(artifact.split(":"))); + log.debugf("Extension %s is making %s a lesser priority artifact", extension, artifact); + } + break; + default: + if (name.startsWith(REMOVED_RESOURCES_DOT)) { + final String keyStr = name.substring(REMOVED_RESOURCES_DOT.length()); + if (!keyStr.isBlank()) { + ArtifactKey key = null; + try { + key = ArtifactKey.fromString(keyStr); + } catch (IllegalArgumentException e) { + log.warnf("Failed to parse artifact key %s in %s from descriptor of extension %s", keyStr, name, + extension); + } + if (key != null) { + final Set resources; + Collection existingResources = excludedResources.get(key); + if (existingResources == null || existingResources.isEmpty()) { + resources = Set.of(value.split(",")); + } else { + final String[] split = value.split(","); + resources = new HashSet<>(existingResources.size() + split.length); + resources.addAll(existingResources); + for (String s : split) { + resources.add(s); + } + } + log.debugf("Extension %s is excluding resources %s from artifact %s", extension, resources, + key); + excludedResources.put(key, resources); + } + } + } } } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/DefaultApplicationModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/DefaultApplicationModel.java index 0e8a981fc97cf..e98630ebd7c7e 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/DefaultApplicationModel.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/DefaultApplicationModel.java @@ -5,6 +5,7 @@ import java.io.Serializable; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Set; public class DefaultApplicationModel implements ApplicationModel, Serializable { @@ -19,6 +20,7 @@ public class DefaultApplicationModel implements ApplicationModel, Serializable { private final Set runnerParentFirstArtifacts; private final Set lesserPriorityArtifacts; private final Set localProjectArtifacts; + private final Map> excludedResources; public DefaultApplicationModel(ApplicationModelBuilder builder) { this.appArtifact = builder.appArtifact; @@ -29,6 +31,7 @@ public DefaultApplicationModel(ApplicationModelBuilder builder) { this.runnerParentFirstArtifacts = builder.runnerParentFirstArtifacts; this.lesserPriorityArtifacts = builder.lesserPriorityArtifacts; this.localProjectArtifacts = builder.reloadableWorkspaceModules; + this.excludedResources = builder.excludedResources; } @Override @@ -70,4 +73,9 @@ public Set getLowerPriorityArtifacts() { public Set getReloadableWorkspaceDependencies() { return localProjectArtifacts; } + + @Override + public Map> getRemovedResources() { + return excludedResources; + } } diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/MutableJarApplicationModel.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/MutableJarApplicationModel.java index 659b0f45dbac4..21177a319a0ad 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/MutableJarApplicationModel.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/bootstrap/model/MutableJarApplicationModel.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -33,6 +34,7 @@ public class MutableJarApplicationModel implements Serializable { private Set runnerParentFirstArtifacts; private Set lesserPriorityArtifacts; private Set localProjectArtifacts; + private Map> excludedResources; private Collection capabilitiesContracts; private PlatformImports platformImports; private String userProvidersDirectory; @@ -51,6 +53,7 @@ public MutableJarApplicationModel(String baseName, Map parentFirstArtifacts = new HashSet<>(appModel.getParentFirst()); runnerParentFirstArtifacts = new HashSet<>(appModel.getRunnerParentFirst()); lesserPriorityArtifacts = new HashSet<>(appModel.getLowerPriorityArtifacts()); + excludedResources = new HashMap<>(appModel.getRemovedResources()); capabilitiesContracts = new ArrayList<>(appModel.getExtensionCapabilities()); this.platformImports = appModel.getPlatforms(); } @@ -77,6 +80,9 @@ public ApplicationModel getAppModel(Path root) { for (ArtifactKey i : localProjectArtifacts) { model.addReloadableWorkspaceModule(i); } + for (Map.Entry> i : excludedResources.entrySet()) { + model.addRemovedResources(i.getKey(), i.getValue()); + } for (ExtensionCapabilities ec : capabilitiesContracts) { model.addExtensionCapabilities(ec); } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/ConfiguredClassLoading.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/ConfiguredClassLoading.java index 86c710ab66d7c..610de0a6e58a3 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/ConfiguredClassLoading.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/ConfiguredClassLoading.java @@ -12,7 +12,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -108,6 +107,17 @@ public ConfiguredClassLoading build() { } } } + + if (!appModel.getRemovedResources().isEmpty()) { + for (Map.Entry> e : appModel.getRemovedResources().entrySet()) { + Collection resources = removedResources.get(e.getKey()); + if (resources == null) { + removedResources.put(e.getKey(), e.getValue()); + } else { + resources.addAll(e.getValue()); + } + } + } } return ConfiguredClassLoading.this; @@ -135,7 +145,11 @@ private void collectRemovedResources(String baseConfigKey, Properties properties if (key.startsWith(baseConfigKey)) { String artifactId = key.substring(baseConfigKey.length()); artifactId = artifactId.replace("\"", ""); - List resources = Arrays.asList(value.split(",")); + final String[] split = value.split(","); + List resources = new ArrayList<>(split.length); + for (String s : split) { + resources.add(s); + } removedResources.put(new GACT(artifactId.split(":")), resources); } } diff --git a/independent-projects/bootstrap/maven-plugin/src/main/java/io/quarkus/maven/ExtensionDescriptorMojo.java b/independent-projects/bootstrap/maven-plugin/src/main/java/io/quarkus/maven/ExtensionDescriptorMojo.java index 179b4671fd03a..41f071180e0a7 100644 --- a/independent-projects/bootstrap/maven-plugin/src/main/java/io/quarkus/maven/ExtensionDescriptorMojo.java +++ b/independent-projects/bootstrap/maven-plugin/src/main/java/io/quarkus/maven/ExtensionDescriptorMojo.java @@ -14,7 +14,7 @@ import io.quarkus.bootstrap.BootstrapConstants; import io.quarkus.bootstrap.model.AppArtifactCoords; import io.quarkus.bootstrap.model.AppArtifactKey; -import io.quarkus.bootstrap.model.ApplicationModel; +import io.quarkus.bootstrap.model.ApplicationModelBuilder; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenContext; import io.quarkus.bootstrap.resolver.maven.BootstrapMavenException; import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver; @@ -25,6 +25,7 @@ import io.quarkus.maven.capabilities.CapabilitiesConfig; import io.quarkus.maven.capabilities.CapabilityConfig; import io.quarkus.maven.dependency.ArtifactCoords; +import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.maven.dependency.GACTV; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -153,6 +154,14 @@ public class ExtensionDescriptorMojo extends AbstractMojo { @Parameter List excludedArtifacts; + /** + * Resources that should excluded from the classloader and the packaged application. + * It is an equivalent of {@code quarkus.class-loading.removed-resources} from {@code application.properties} + * but in the `META-INF/quarkus-extension.properties`. + */ + @Parameter + Map removedResources = Map.of(); + /** * Artifacts that are always loaded parent first when running in dev or test mode. This is an advanced option * and should only be used if you are sure that this is the correct solution for the use case. @@ -285,22 +294,56 @@ public void execute() throws MojoExecutionException { if (parentFirstArtifacts != null && !parentFirstArtifacts.isEmpty()) { String val = String.join(",", parentFirstArtifacts); - props.put(ApplicationModel.PARENT_FIRST_ARTIFACTS, val); + props.put(ApplicationModelBuilder.PARENT_FIRST_ARTIFACTS, val); } if (runnerParentFirstArtifacts != null && !runnerParentFirstArtifacts.isEmpty()) { String val = String.join(",", runnerParentFirstArtifacts); - props.put(ApplicationModel.RUNNER_PARENT_FIRST_ARTIFACTS, val); + props.put(ApplicationModelBuilder.RUNNER_PARENT_FIRST_ARTIFACTS, val); } if (excludedArtifacts != null && !excludedArtifacts.isEmpty()) { String val = String.join(",", excludedArtifacts); - props.put(ApplicationModel.EXCLUDED_ARTIFACTS, val); + props.put(ApplicationModelBuilder.EXCLUDED_ARTIFACTS, val); + } + + if (!removedResources.isEmpty()) { + for (Map.Entry entry : removedResources.entrySet()) { + final ArtifactKey key; + try { + key = ArtifactKey.fromString(entry.getKey()); + } catch (IllegalArgumentException e) { + throw new MojoExecutionException( + "Failed to parse removed resource '" + entry.getKey() + '=' + entry.getValue() + "'", e); + } + if (entry.getValue() == null || entry.getValue().isBlank()) { + continue; + } + final String[] resources = entry.getValue().split(","); + if (resources.length == 0) { + continue; + } + final String value; + if (resources.length == 1) { + value = resources[0]; + } else { + final StringBuilder sb = new StringBuilder(); + sb.append(resources[0]); + for (int i = 1; i < resources.length; ++i) { + final String resource = resources[i]; + if (!resource.isBlank()) { + sb.append(',').append(resource); + } + } + value = sb.toString(); + } + props.setProperty(ApplicationModelBuilder.REMOVED_RESOURCES_DOT + key.toString(), value); + } } if (lesserPriorityArtifacts != null && !lesserPriorityArtifacts.isEmpty()) { String val = String.join(",", lesserPriorityArtifacts); - props.put(ApplicationModel.LESSER_PRIORITY_ARTIFACTS, val); + props.put(ApplicationModelBuilder.LESSER_PRIORITY_ARTIFACTS, val); } final Path output = outputDirectory.toPath().resolve(BootstrapConstants.META_INF); diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/it/PackageIT.java b/integration-tests/maven/src/test/java/io/quarkus/maven/it/PackageIT.java index a4edd93af7f5b..7cef6453ba67c 100644 --- a/integration-tests/maven/src/test/java/io/quarkus/maven/it/PackageIT.java +++ b/integration-tests/maven/src/test/java/io/quarkus/maven/it/PackageIT.java @@ -12,6 +12,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.jar.JarFile; @@ -42,6 +43,14 @@ public void testPluginClasspathConfig() throws Exception { assertThat(result.getProcess().waitFor()).isEqualTo(0); } + @Test + public void testExtensionRemovedResources() throws Exception { + testDir = initProject("projects/extension-removed-resources"); + running = new RunningInvoker(testDir, false); + final MavenProcessInvocationResult result = running.execute(List.of("verify"), Map.of()); + assertThat(result.getProcess().waitFor()).isEqualTo(0); + } + @Test public void testUberJarMavenPluginConfiguration() throws MavenInvocationException, IOException, InterruptedException { diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/deployment/pom.xml b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/deployment/pom.xml new file mode 100644 index 0000000000000..08aba86f28968 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/deployment/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + org.acme + acme-extension-parent + 1.0.0-SNAPSHOT + + acme-extension-deployment + Acme - Extension - Deployment + + + io.quarkus + quarkus-arc-deployment + + + org.acme + acme-extension + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + \${quarkus.platform.version} + + + + + + + diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/deployment/src/main/java/org/acme/deployment/AcmeProcessor.java b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/deployment/src/main/java/org/acme/deployment/AcmeProcessor.java new file mode 100644 index 0000000000000..363713a3935e4 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/deployment/src/main/java/org/acme/deployment/AcmeProcessor.java @@ -0,0 +1,18 @@ +package org.acme.deployment; + +import java.util.Set; + +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.builditem.RemovedResourceBuildItem; +import io.quarkus.maven.dependency.ArtifactKey; + +class AcmeProcessor { + + private static final String FEATURE = "acme"; + + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } +} diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/pom.xml b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/pom.xml new file mode 100644 index 0000000000000..48a1816dc5aa5 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.acme + code-with-quarkus + 1.0.0-SNAPSHOT + + acme-extension-parent + pom + Acme - Extension - Parent + + deployment + runtime + + + + + + io.quarkus + quarkus-maven-plugin + \${quarkus.platform.version} + + + maven-compiler-plugin + \${compiler-plugin.version} + + + -parameters + + + + + + + diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/runtime/pom.xml b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/runtime/pom.xml new file mode 100644 index 0000000000000..1ac8aac1c86eb --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/runtime/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + org.acme + acme-extension-parent + 1.0.0-SNAPSHOT + + acme-extension + Quarkus - Custom - Runtime + + + io.quarkus + quarkus-arc + + + org.acme + acme-resources + + + + + + io.quarkus + quarkus-bootstrap-maven-plugin + \${quarkus.platform.version} + + + compile + + extension-descriptor + + + \${project.groupId}:\${project.artifactId}-deployment:\${project.version} + + META-INF/a + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + \${quarkus.platform.version} + + + + + + + diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/runtime/src/main/resources/META-INF/quarkus-extension.yaml new file mode 100644 index 0000000000000..f4525c057c4db --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/extension/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -0,0 +1 @@ +name: Acme diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/pom.xml b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/pom.xml new file mode 100644 index 0000000000000..856ae04c1a14e --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + pom + org.acme + code-with-quarkus + 1.0.0-SNAPSHOT + + 3.8.1 + false + 11 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus + 999-SNAPSHOT + 3.0.0-M5 + + + + + \${quarkus.platform.group-id} + \${quarkus.platform.artifact-id} + \${quarkus.platform.version} + pom + import + + + org.acme + acme-extension + 1.0.0-SNAPSHOT + + + org.acme + acme-extension-deployment + 1.0.0-SNAPSHOT + + + org.acme + acme-resources + 1.0.0-SNAPSHOT + + + + + resources + extension + runner + + + + + io.quarkus + quarkus-maven-plugin + \${quarkus.platform.version} + + + + diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/pom.xml b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/pom.xml new file mode 100644 index 0000000000000..e6a25f61dc158 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + org.acme + code-with-quarkus + 1.0.0-SNAPSHOT + + acme-resources + + + + maven-compiler-plugin + \${compiler-plugin.version} + + + -parameters + + + + + + diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/src/main/resources/META-INF/a b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/src/main/resources/META-INF/a new file mode 100644 index 0000000000000..2e65efe2a145d --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/src/main/resources/META-INF/a @@ -0,0 +1 @@ +a \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/src/main/resources/META-INF/b b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/src/main/resources/META-INF/b new file mode 100644 index 0000000000000..63d8dbd40c235 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/resources/src/main/resources/META-INF/b @@ -0,0 +1 @@ +b \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/pom.xml b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/pom.xml new file mode 100644 index 0000000000000..c9f08ff9dbdab --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/pom.xml @@ -0,0 +1,86 @@ + + + 4.0.0 + + org.acme + code-with-quarkus + 1.0.0-SNAPSHOT + + acme-app + + + io.quarkus + quarkus-resteasy-reactive + + + org.acme + acme-extension + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + + + + \${quarkus.platform.group-id} + quarkus-maven-plugin + \${quarkus.platform.version} + true + + + + build + + + + + + maven-compiler-plugin + \${compiler-plugin.version} + + + -parameters + + + + + maven-surefire-plugin + \${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + \${maven.home} + + + + + maven-failsafe-plugin + \${surefire-plugin.version} + + + + integration-test + verify + + + + \${project.build.directory}/\${project.build.finalName}-runner + org.jboss.logmanager.LogManager + \${maven.home} + + + + + + + + diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/main/java/org/acme/MetaInfResource.java b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/main/java/org/acme/MetaInfResource.java new file mode 100644 index 0000000000000..c1b17b6427f9f --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/main/java/org/acme/MetaInfResource.java @@ -0,0 +1,33 @@ +package org.acme; + +import java.io.IOException; +import java.io.InputStream; + +import javax.ws.rs.BadRequestException; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +@Path("/meta-inf") +public class MetaInfResource { + + @GET + @Produces(MediaType.TEXT_PLAIN) + @Path("/{name}") + public String hello(@PathParam("name") String name) { + final ClassLoader cl = Thread.currentThread().getContextClassLoader(); + var url = cl.getResource("META-INF/" + name); + if(url == null) { + throw new BadRequestException(Response.status(Status.BAD_REQUEST).build()); + } + try(InputStream is = url.openStream()) { + return new String(is.readAllBytes()); + } catch (IOException e) { + throw new RuntimeException("Failed to read " + url, e); + } + } +} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/test/java/org/acme/MetaInfResourceIT.java b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/test/java/org/acme/MetaInfResourceIT.java new file mode 100644 index 0000000000000..a817006186a42 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/test/java/org/acme/MetaInfResourceIT.java @@ -0,0 +1,9 @@ +package org.acme; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +public class MetaInfResourceIT extends MetaInfResourceTest { + + // Execute the same tests but in native mode. +} diff --git a/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/test/java/org/acme/MetaInfResourceTest.java b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/test/java/org/acme/MetaInfResourceTest.java new file mode 100644 index 0000000000000..97d3a82b48ed9 --- /dev/null +++ b/integration-tests/maven/src/test/resources-filtered/projects/extension-removed-resources/runner/src/test/java/org/acme/MetaInfResourceTest.java @@ -0,0 +1,28 @@ +package org.acme; + +import io.quarkus.test.junit.QuarkusTest; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +@QuarkusTest +public class MetaInfResourceTest { + + @Test + public void testMetaInfB() { + given() + .when().get("/meta-inf/b") + .then() + .statusCode(200) + .body(is("b")); + } + + @Test + public void testMetaInfA() { + given() + .when().get("/meta-inf/a") + .then() + .statusCode(400); + } +} \ No newline at end of file