diff --git a/core/deployment/src/main/java/io/quarkus/deployment/configuration/ClassLoadingConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/configuration/ClassLoadingConfig.java
index 3eb7b693f46ec..ae14536df79d6 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/configuration/ClassLoadingConfig.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/configuration/ClassLoadingConfig.java
@@ -6,9 +6,9 @@
import java.util.Set;
import io.quarkus.runtime.annotations.ConfigDocMapKey;
-import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
+import io.smallrye.config.ConfigMapping;
/**
* Class loading
@@ -18,7 +18,8 @@
* This is because it is needed before any of the config infrastructure is set up.
*/
@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
-public class ClassLoadingConfig {
+@ConfigMapping(prefix = "quarkus.class-loading")
+public interface ClassLoadingConfig {
/**
* Artifacts that are loaded in a parent first manner. This can be used to work around issues where a given
@@ -30,8 +31,7 @@ public class ClassLoadingConfig {
*
* WARNING: This config property can only be set in application.properties
*/
- @ConfigItem(defaultValue = "")
- public Optional> parentFirstArtifacts;
+ Optional> parentFirstArtifacts();
/**
* Artifacts that are loaded in the runtime ClassLoader in dev mode, so they will be dropped
@@ -48,15 +48,13 @@ public class ClassLoadingConfig {
*
* WARNING: This config property can only be set in application.properties
*/
- @ConfigItem(defaultValue = "")
- public Optional reloadableArtifacts;
+ Optional reloadableArtifacts();
/**
* Artifacts that will never be loaded by the class loader, and will not be packed into the final application. This allows
* you to explicitly remove artifacts from your application even though they may be present on the class path.
*/
- @ConfigItem(defaultValue = "")
- public Optional> removedArtifacts;
+ Optional> removedArtifacts();
/**
* Resources that should be removed/hidden from dependencies.
@@ -73,8 +71,7 @@ public class ClassLoadingConfig {
*
* Note that for technical reasons this is not supported when running with JBang.
*/
- @ConfigItem
@ConfigDocMapKey("group-id:artifact-id")
- public Map> removedResources;
+ Map> removedResources();
}
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java
index 4efa94db2d4ca..0eb9f56003939 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/index/ApplicationArchiveBuildStep.java
@@ -117,7 +117,7 @@ ApplicationArchivesBuildItem build(
}
Map> removedResources = new HashMap<>();
- for (Map.Entry> entry : classLoadingConfig.removedResources.entrySet()) {
+ for (Map.Entry> entry : classLoadingConfig.removedResources().entrySet()) {
removedResources.put(new GACT(entry.getKey().split(":")), entry.getValue());
}
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java
index bd36f8ba78ae9..b9d5b25fb68ae 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java
@@ -1,7 +1,6 @@
package io.quarkus.deployment.pkg.steps;
import static io.quarkus.commons.classloading.ClassLoaderHelper.fromClassNameToResourceName;
-import static io.quarkus.deployment.pkg.PackageConfig.JarConfig.JarType.LEGACY_JAR;
import static io.quarkus.deployment.pkg.PackageConfig.JarConfig.JarType.MUTABLE_JAR;
import static io.quarkus.deployment.pkg.PackageConfig.JarConfig.JarType.UBER_JAR;
@@ -358,7 +357,7 @@ private void buildUberJar0(CurateOutcomeBuildItem curateOutcomeBuildItem,
final Set mergeResourcePaths = mergedResources.stream()
.map(UberJarMergedResourceBuildItem::getPath)
.collect(Collectors.toSet());
- final Set removed = getRemovedKeys(classLoadingConfig);
+ final Set removed = getRemovedArtifactKeys(classLoadingConfig);
Set ignoredEntries = new HashSet<>();
packageConfig.jar().userConfiguredIgnoredEntries().ifPresent(ignoredEntries::addAll);
@@ -554,7 +553,7 @@ private JarBuildItem buildLegacyThinJar(CurateOutcomeBuildItem curateOutcomeBuil
doLegacyThinJarGeneration(curateOutcomeBuildItem, outputTargetBuildItem, transformedClasses,
applicationArchivesBuildItem, applicationInfo,
packageConfig, generatedResources, libDir, generatedClasses, runnerZipFs, mainClassBuildItem,
- classLoadingConfig);
+ getRemovedArtifactKeys(classLoadingConfig));
}
runnerJar.toFile().setReadable(true, false);
@@ -707,7 +706,7 @@ private JarBuildItem buildThinJar(CurateOutcomeBuildItem curateOutcomeBuildItem,
}
final Set parentFirstKeys = getParentFirstKeys(curateOutcomeBuildItem, classLoadingConfig);
final StringBuilder classPath = new StringBuilder();
- final Set removed = getRemovedKeys(classLoadingConfig);
+ final Set removed = getRemovedArtifactKeys(classLoadingConfig);
final Map> copiedArtifacts = new HashMap<>();
for (ResolvedDependency appDep : curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies()) {
if (!rebuild) {
@@ -882,7 +881,7 @@ private Set getParentFirstKeys(CurateOutcomeBuildItem curateOutcome
parentFirstKeys.add(d.getKey());
}
});
- classLoadingConfig.parentFirstArtifacts.ifPresent(
+ classLoadingConfig.parentFirstArtifacts().ifPresent(
parentFirstArtifacts -> {
for (String artifact : parentFirstArtifacts) {
parentFirstKeys.add(new GACT(artifact.split(":")));
@@ -891,18 +890,16 @@ private Set getParentFirstKeys(CurateOutcomeBuildItem curateOutcome
return parentFirstKeys;
}
- /**
- * @return a {@code Set} containing the key of the artifacts to load from the parent ClassLoader first.
- */
- private Set getRemovedKeys(ClassLoadingConfig classLoadingConfig) {
- final Set removed = new HashSet<>();
- classLoadingConfig.removedArtifacts.ifPresent(
- removedArtifacts -> {
- for (String artifact : removedArtifacts) {
- removed.add(new GACT(artifact.split(":")));
- }
- });
- return removed;
+ private Set getRemovedArtifactKeys(ClassLoadingConfig classLoadingConfig) {
+ if (classLoadingConfig.removedArtifacts().isEmpty()) {
+ return Set.of();
+ }
+
+ Set removedArtifacts = new HashSet<>();
+ for (String artifact : classLoadingConfig.removedArtifacts().get()) {
+ removedArtifacts.add(GACT.fromString(artifact));
+ }
+ return Collections.unmodifiableSet(removedArtifacts);
}
private void copyDependency(Set parentFirstArtifacts, OutputTargetBuildItem outputTargetBuildItem,
@@ -1044,16 +1041,13 @@ private NativeImageSourceJarBuildItem buildNativeImageThinJar(CurateOutcomeBuild
log.info("Building native image source jar: " + runnerJar);
+ final Set removedArtifacts = new HashSet<>(getRemovedArtifactKeys(classLoadingConfig));
// Remove svm and graal-sdk artifacts as they are provided by GraalVM itself
- if (classLoadingConfig.removedArtifacts.isEmpty()) {
- classLoadingConfig.removedArtifacts = Optional.of(new ArrayList<>(6));
- }
- List removedArtifacts = classLoadingConfig.removedArtifacts.get();
- removedArtifacts.add("org.graalvm.nativeimage:svm");
- removedArtifacts.add("org.graalvm.sdk:graal-sdk");
- removedArtifacts.add("org.graalvm.sdk:nativeimage");
- removedArtifacts.add("org.graalvm.sdk:word");
- removedArtifacts.add("org.graalvm.sdk:collections");
+ removedArtifacts.add(GACT.fromString("org.graalvm.nativeimage:svm"));
+ removedArtifacts.add(GACT.fromString("org.graalvm.sdk:graal-sdk"));
+ removedArtifacts.add(GACT.fromString("org.graalvm.sdk:nativeimage"));
+ removedArtifacts.add(GACT.fromString("org.graalvm.sdk:word"));
+ removedArtifacts.add(GACT.fromString("org.graalvm.sdk:collections"));
// complain if graal-sdk is present as a dependency as nativeimage should be preferred
if (curateOutcomeBuildItem.getApplicationModel().getDependencies().stream()
@@ -1065,7 +1059,7 @@ private NativeImageSourceJarBuildItem buildNativeImageThinJar(CurateOutcomeBuild
doLegacyThinJarGeneration(curateOutcomeBuildItem, outputTargetBuildItem, transformedClasses,
applicationArchivesBuildItem, applicationInfo, packageConfig, generatedResources, libDir, allClasses,
- runnerZipFs, mainClassBuildItem, classLoadingConfig);
+ runnerZipFs, mainClassBuildItem, removedArtifacts);
}
runnerJar.toFile().setReadable(true, false);
return new NativeImageSourceJarBuildItem(runnerJar, libDir);
@@ -1109,7 +1103,7 @@ private void doLegacyThinJarGeneration(CurateOutcomeBuildItem curateOutcomeBuild
List allClasses,
FileSystem runnerZipFs,
MainClassBuildItem mainClassBuildItem,
- ClassLoadingConfig classLoadingConfig)
+ Set removedArtifacts)
throws IOException {
final Map seen = new HashMap<>();
final StringBuilder classPath = new StringBuilder();
@@ -1120,9 +1114,8 @@ private void doLegacyThinJarGeneration(CurateOutcomeBuildItem curateOutcomeBuild
Predicate ignoredEntriesPredicate = getThinJarIgnoredEntriesPredicate(packageConfig);
- final Set removed = getRemovedKeys(classLoadingConfig);
copyLibraryJars(runnerZipFs, outputTargetBuildItem, transformedClasses, libDir, classPath, appDeps, services,
- ignoredEntriesPredicate, removed);
+ ignoredEntriesPredicate, removedArtifacts);
ResolvedDependency appArtifact = curateOutcomeBuildItem.getApplicationModel().getAppArtifact();
// the manifest needs to be the first entry in the jar, otherwise JarInputStream does not work properly
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ApplicationIndexBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ApplicationIndexBuildStep.java
index b90e9592f69e4..bff7b73344d81 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/steps/ApplicationIndexBuildStep.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ApplicationIndexBuildStep.java
@@ -84,7 +84,7 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx
private Set removedApplicationClasses(CurateOutcomeBuildItem curation, ClassLoadingConfig classLoadingConfig) {
ResolvedDependency appArtifact = curation.getApplicationModel().getAppArtifact();
- Set entry = classLoadingConfig.removedResources
+ Set entry = classLoadingConfig.removedResources()
.get(appArtifact.getGroupId() + ":" + appArtifact.getArtifactId());
return entry != null ? entry : Collections.emptySet();
}
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassTransformingBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassTransformingBuildStep.java
index 921cb5fc8993e..fe0ed1f052263 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassTransformingBuildStep.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ClassTransformingBuildStep.java
@@ -88,7 +88,7 @@ TransformedClassesBuildItem handleClassTransformation(List removedResourceBuildItems) {
//a little bit of a hack, but we use an empty transformed class to represent removed resources, as transforming a class removes it from the original archive
Map> removed = new HashMap<>();
- for (Map.Entry> entry : classLoadingConfig.removedResources.entrySet()) {
+ for (Map.Entry> entry : classLoadingConfig.removedResources().entrySet()) {
removed.put(new GACT(entry.getKey().split(":")), entry.getValue());
}
for (RemovedResourceBuildItem i : removedResourceBuildItems) {