fix scanning of ServletContainerInitializer by tomcat > 7.0.5x #20
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
ServletContainerInitializer not scanned in goal "run"
I found that since tomcat v7.0.5x , because of a refactor on the scanning of the ServletContainerInitializer, it is broken in the tomcat maven plugin in the run goal.
The bug is introduced by the new method of scanning of the new class "org.apache.catalina.startup.WebappServiceLoader" in tomcat core.
The method "load" looks for lib jar path using servletContext.getResource() with the prefix "WEB-INb/lib", but in "run" goal, we do not have the dependencies in this folder, and because the method do not use the classloader, all lib jars are not scanned.
The problematic code path is used if the "servletContext.getAttribute(ServletContext.ORDERED_LIBS);" return a list.
But if we clear this list, the load method will scan every jar in the classpath.
To fix the problem we have three solutions:
clear the servletContext attribute ServletContext.ORDERED_LIBS,
or get the lib loaded in dependencies accessible by servletContext.getResource("WEB-INb/lib" + jarName),
or put the dependencies in the parent classloader
The first solution can be easily implemented by extending the ContextConfig class to override the processServletContainerInitializers method in the following way.
protected void processServletContainerInitializers(ServletContext servletContext) {
List saveOrderedLib = (List) servletContext.getAttribute(ServletContext.ORDERED_LIBS);
servletContext.setAttribute(ServletContext.ORDERED_LIBS, null);
super.processServletContainerInitializers(servletContext);
servletContext.setAttribute(ServletContext.ORDERED_LIBS, saveOrderedLib);
}
and using this custom ContextConfig class in the ExtendedTomcat class.