-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
As of Servlet 3.0, there is no way to create code guaranteed to run first before anything else #79
Comments
@glassfishrobot Commented |
@glassfishrobot Commented I suggest the following approach. 1. Container provided SCIs are always executed first in a container determined order. |
@glassfishrobot Commented |
@glassfishrobot Commented
The aim is that all container specified SCIs are loaded first even if the implementations of some of them are provided by the application because the application ships with an alternative implementation. |
@glassfishrobot Commented |
@arjantijms Commented |
|
In Servlet 2.5 and earlier, if you needed code that you could guarantee would always run first, you implemented ServletContextListener, put your important code in the initialization method, and defined it as the very first listener in your deployment descriptor web.xml. This was critically important for many tasks, such as logging initialization. Logging initialization typically must happen before anything else, or else it could be initialized incorrectly.
Servlet 3.0 added the awesome and useful concept of the ServletContainerInitializer, but this introduced a critical problem. There is no longer any way to create code guaranteed to run before anything else. First, a ServletContainerInitializer will always run before any ServletContextListener is initialized, so you can't rely on a ServletContextListener to run your critical startup code. I thought that a ServletContainerInitializer would run in the order of its web-fragment (either in web-fragment.xml or in web.xml), but I was wrong. The spec makes no such guarantee. Initializers are guaranteed nothing more than a random execution order. Because of this, it is impossible to guarantee that critical startup code will always run first.
Some containers appear to abide by the web-fragment order any. For example, Tomcat, TomEE, and JBoss definitely order initializers according to their web-fragment order (this is confirmed in code), while WebLogic and WebSphere appear to order them the same way (they are closed source, so this can't be completely confirmed, but the behavior is consistent). However, GlassFish, Jetty, and Resin order initializers in the order they are returned from the ClassLoader.
The execution of an ServletContainerInitializer should be ordered according to its web-fragment order. Alternatively a separate ordering mechanism could be specified, but this would seem to be unnecessary and burdensome. Furthermore, I think the committee should encourage (though obviously it cannot require) existing 3.0 and 3.1 implementations to apply this change retroactively, since it doesn't change the API.
Failing to require a predictable and controllable order for initializers is a serious oversight in the spec and represents a regression from 2.5, where it was possible to write code guaranteed to always run first.
The text was updated successfully, but these errors were encountered: