You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A number of static resources to be served by Tomcat are included in the META-INF/resources folder.
I find that the static resources are not added to the Tomcat servlet context, and cannot be found when run in "fat jar" mode. When not run as a "fat jar", it works.
Cause:
The reason for this is the way AbstractEmbeddedServletContainerFactory.getUrlsOfJarsWithMetaInfResources() works:
ClassLoaderclassLoader = getClass().getClassLoader();
List<URL> staticResourceUrls = newArrayList<URL>();
if (classLoaderinstanceofURLClassLoader) {
for (URLurl : ((URLClassLoader) classLoader).getURLs()) {
[...]
The classloader hierarchy (with the results returned by getURLs()) is as follows when the application in run as a "fat jar":
sun.misc.Launcher$ExtClassLoader:
[...] misc system jars
sun.misc.Launcher$AppClassLoader:
**URL:file:/path/to/fatjar.jar**
org.springframework.boot.loader.LaunchedURLClassLoader:
URL:jar:file:/path/to/fatjar.jar!/BOOT-INF/classes!/
URL:jar:file:/path/to/fatjar.jar!/BOOT-INF/lib!/comp1.jar!/
getClass() returns the LaunchedURLClassLoader, which only includes its embedded jars in getURLs(). Therefore, none of the resources in the main jar are found - only those embedded in the "fat jar". It works when not run as a fat jar, since the AppClassLoader returns all the URLs and paths to resources.
Suggested solution:
A solution that I have tested OK is to traverse the parent ClassLoaders too, scanning those for jars containing a META-INF/resources folder:
privateURL[] getURLs(URLClassLoaderclassLoader) {
Set<URL> urlSet = newLinkedHashSet<>();
ClassLoaderc = classLoader;
while (c != null) {
if (cinstanceofURLClassLoader) {
Collections.addAll(urlSet, ((URLClassLoader) c).getURLs());
}
c = c.getParent();
}
returnurlSet.toArray(newURL[urlSet.size()]);
}
ClassLoaderclassLoader = getClass().getClassLoader();
List<URL> staticResourceUrls = newArrayList<>();
if (classLoaderinstanceofURLClassLoader) {
-> for (URLurl : getURLs((URLClassLoader) classLoader)) {
The text was updated successfully, but these errors were encountered:
Uh oh!
There was an error while loading. Please reload this page.
Spring Boot 1.5.4
Scenario:
A Spring Boot application is packaged as a "fat jar". The jar then has the following structure:
A number of static resources to be served by Tomcat are included in the META-INF/resources folder.
I find that the static resources are not added to the Tomcat servlet context, and cannot be found when run in "fat jar" mode. When not run as a "fat jar", it works.
Cause:
The reason for this is the way AbstractEmbeddedServletContainerFactory.getUrlsOfJarsWithMetaInfResources() works:
The classloader hierarchy (with the results returned by getURLs()) is as follows when the application in run as a "fat jar":
getClass() returns the LaunchedURLClassLoader, which only includes its embedded jars in getURLs(). Therefore, none of the resources in the main jar are found - only those embedded in the "fat jar". It works when not run as a fat jar, since the AppClassLoader returns all the URLs and paths to resources.
Suggested solution:
A solution that I have tested OK is to traverse the parent ClassLoaders too, scanning those for jars containing a META-INF/resources folder:
The text was updated successfully, but these errors were encountered: