Skip to content

Commit b7aa7fa

Browse files
Allow WebJar branding overrides from application dependencies
Previously, META-INF/branding/ resources (style.css, logo.png, favicon.ico) were only resolved from the application's own resources. When placed in a dependency JAR (e.g. a shared branding library), style.css was ignored because the Quarkus default branding took precedence via the classloader fallback. This change extends getCustomOverride() to also scan application dependencies for branding resources, with the following priority: 1. Application's own resources (highest) 2. Application dependency JARs 3. Quarkus default branding (lowest) Fixes #53237 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4bb7f1d commit b7aa7fa

File tree

1 file changed

+29
-9
lines changed
  • extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/webjar

1 file changed

+29
-9
lines changed

extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/webjar/WebJarUtil.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.nio.file.attribute.BasicFileAttributes;
1212
import java.util.ArrayList;
1313
import java.util.Arrays;
14+
import java.util.Collection;
1415
import java.util.List;
1516
import java.util.Map;
1617
import java.util.function.Consumer;
@@ -65,6 +66,7 @@ private static void copyResources(CurateOutcomeBuildItem curateOutcomeBuildItem,
6566
WebJarBuildItem webJar,
6667
ResolvedDependency resourcesArtifact, WebJarResourcesTargetVisitor visitor) {
6768
final ResolvedDependency userApplication = curateOutcomeBuildItem.getApplicationModel().getAppArtifact();
69+
final Collection<ResolvedDependency> dependencies = curateOutcomeBuildItem.getApplicationModel().getDependencies();
6870

6971
ClassLoader classLoader = WebJarUtil.class.getClassLoader();
7072

@@ -84,7 +86,8 @@ public void accept(PathVisit pathVisit) {
8486
try {
8587
Files.walkFileTree(pathVisit.getPath(),
8688
new ResourcesFileVisitor(visitor, pathVisit.getPath(), resourcesArtifact,
87-
userApplication, new CombinedWebJarResourcesFilter(filters), classLoader, webJar));
89+
userApplication, dependencies, new CombinedWebJarResourcesFilter(filters),
90+
classLoader, webJar));
8891
} catch (IOException e) {
8992
throw new UncheckedIOException(e);
9093
}
@@ -107,21 +110,22 @@ private static String getModuleOverrideName(ResolvedDependency artifact, String
107110
return artifact.getArtifactId() + type;
108111
}
109112

110-
private static InputStream getOverride(ResolvedDependency userApplication, ClassLoader classLoader, String filename,
111-
String moduleName,
113+
private static InputStream getOverride(ResolvedDependency userApplication, Collection<ResolvedDependency> dependencies,
114+
ClassLoader classLoader, String filename, String moduleName,
112115
boolean useDefaultQuarkusBranding) {
113116

114-
// First check if the developer supplied the files
115-
InputStream overrideStream = getCustomOverride(userApplication, filename, moduleName);
117+
// First check if the developer supplied the files (application resources, then dependencies)
118+
InputStream overrideStream = getCustomOverride(userApplication, dependencies, filename, moduleName);
116119
if (overrideStream == null && useDefaultQuarkusBranding) {
117120
// Else check if Quarkus has a default branding
118121
overrideStream = getQuarkusOverride(classLoader, filename, moduleName);
119122
}
120123
return overrideStream;
121124
}
122125

123-
private static InputStream getCustomOverride(ResolvedDependency userApplication, String filename, String moduleName) {
124-
// Check if the developer supplied the files
126+
private static InputStream getCustomOverride(ResolvedDependency userApplication,
127+
Collection<ResolvedDependency> dependencies, String filename, String moduleName) {
128+
// First check if the developer supplied the files in the application itself
125129
byte[] content = readFromPathTree(userApplication.getContentTree(), CUSTOM_MEDIA_FOLDER + moduleName);
126130
if (content != null) {
127131
return new ByteArrayInputStream(content);
@@ -132,6 +136,19 @@ private static InputStream getCustomOverride(ResolvedDependency userApplication,
132136
return new ByteArrayInputStream(content);
133137
}
134138

139+
// Then check application dependencies
140+
for (ResolvedDependency dep : dependencies) {
141+
content = readFromPathTree(dep.getContentTree(), CUSTOM_MEDIA_FOLDER + moduleName);
142+
if (content != null) {
143+
return new ByteArrayInputStream(content);
144+
}
145+
146+
content = readFromPathTree(dep.getContentTree(), CUSTOM_MEDIA_FOLDER + filename);
147+
if (content != null) {
148+
return new ByteArrayInputStream(content);
149+
}
150+
}
151+
135152
return null;
136153
}
137154

@@ -165,17 +182,20 @@ private static class ResourcesFileVisitor extends SimpleFileVisitor<Path> {
165182
private final Path rootFolderToCopy;
166183
private final ResolvedDependency resourcesArtifact;
167184
private final ResolvedDependency userApplication;
185+
private final Collection<ResolvedDependency> dependencies;
168186
private final WebJarResourcesFilter filter;
169187
private final ClassLoader classLoader;
170188
private final WebJarBuildItem webJar;
171189

172190
public ResourcesFileVisitor(WebJarResourcesTargetVisitor visitor, Path rootFolderToCopy,
173-
ResolvedDependency resourcesArtifact, ResolvedDependency userApplication, WebJarResourcesFilter filter,
191+
ResolvedDependency resourcesArtifact, ResolvedDependency userApplication,
192+
Collection<ResolvedDependency> dependencies, WebJarResourcesFilter filter,
174193
ClassLoader classLoader, WebJarBuildItem webJar) {
175194
this.visitor = visitor;
176195
this.rootFolderToCopy = rootFolderToCopy;
177196
this.resourcesArtifact = resourcesArtifact;
178197
this.userApplication = userApplication;
198+
this.dependencies = dependencies;
179199
this.filter = filter;
180200
this.classLoader = classLoader;
181201
this.webJar = webJar;
@@ -197,7 +217,7 @@ public FileVisitResult visitFile(final Path file,
197217
boolean overrideFileCreated = false;
198218
if (OVERRIDABLE_RESOURCES.contains(fileName)) {
199219
try (WebJarResourcesFilter.FilterResult filterResult = filter.apply(fileName,
200-
getOverride(userApplication, classLoader,
220+
getOverride(userApplication, dependencies, classLoader,
201221
fileName, moduleName, webJar.getUseDefaultQuarkusBranding()))) {
202222
if (filterResult.hasStream()) {
203223
overrideFileCreated = true;

0 commit comments

Comments
 (0)