jakartaee / jakartaee/servlet

As of Servlet 3.0, there is no way to create code guaranteed to run first before anything else

Open
#79 7 comments 0 reactions 1 assignee Claimed by @glassfishrobot View on GitHub
Dominant language
Java
Stars
325
Forks
112
PR merge metrics
No merged PRs in 30d

Description

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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.