Reputation: 8487
I used spring boot + jsp, and from this post I know if put jsp files in src/main/resources/META-INF/resources/
also could package as a executable jar.
Unfortunately when I modify spring boot version from 1.4.2
to 1.5.3
, it cannot support and return 404. After hours tracing their source codes and compare I know why 1.5.3
cannot support it.
Spring boot 1.4.2
//org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.StoreMergedWebXmlListener#onStart
private void onStart(Context context) {
ServletContext servletContext = context.getServletContext();
if(servletContext.getAttribute("org.apache.tomcat.util.scan.MergedWebXml") == null) {
servletContext.setAttribute("org.apache.tomcat.util.scan.MergedWebXml", this.getEmptyWebXml());
}
// only 1.4.2 has this line and with this code could recognise jsp files in /META-INF/resources/
TomcatResources.get(context).addClasspathResources();
}
Spring boot 1.5.3
private void onStart(Context context) {
ServletContext servletContext = context.getServletContext();
if (servletContext.getAttribute(MERGED_WEB_XML) == null) {
servletContext.setAttribute(MERGED_WEB_XML, getEmptyWebXml());
}
}
So I want to know why after 1.4.2 have to remove this code?
TomcatResources.get(context).addClasspathResources();
And because I still want to use 1.5.3 so I have to manually add this code by below way
1.copy source code of TomcatEmbeddedServletContainerFactory
to current classpath
2.do below modify
private void onStart(Context context) {
ServletContext servletContext = context.getServletContext();
if (servletContext.getAttribute(MERGED_WEB_XML) == null) {
servletContext.setAttribute(MERGED_WEB_XML, getEmptyWebXml());
}
// Add below code
ClassLoader loader = getClass().getClassLoader();
URL[] urLs = ((URLClassLoader) loader).getURLs();
List<URL> list = new ArrayList<>();
//String file = "file:/Users/zhugw/workspace/boot-jar-serving-jsp/boot-jar-serving-jsp-1.0-SNAPSHOT.jar!/";
String file = urLs[0].getFile().replaceFirst("BOOT-INF/classes!/", "");
URL jar = new URL("jar", "", file);
list.add(0,jar);
TomcatResources.get(context).addResourceJars(list);
}
and it does works. And I want to know if could do this so?
Upvotes: 1
Views: 199
Reputation: 449
We have the same pb here.
...
Caused by: java.lang.IllegalAccessError: tried to access class org.springframework.boot.context.embedded.tomcat.TldSkipPatterns from class org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.(TomcatEmbeddedServletContainerFactory.java:130)
...
Now in SpringBoot 1.5.8.RELEASE, you have the following lines in TomcatEmbeddedServletContainerFactory.prepareContext():
context.addLifecycleListener(new LifecycleListener() {
@Override
public void lifecycleEvent(LifecycleEvent event) {
if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
TomcatResources.get(context)
.addResourceJars(getUrlsOfJarsWithMetaInfResources());
}
}
});
Solution: We've simply removed this override. Jar files areback in the classloader and consequently jsp files stored in those jar files are now correctly recognized by the app.
Upvotes: 1