Bug 51376

Summary: Dynamically added Servlet instances ignore setLoadOnStartup(), @ServletSecurity, etc
Product: Tomcat 7 Reporter: Artem Troitskiy <axtavt>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Severity: normal    
Priority: P2    
Version: 7.0.14   
Target Milestone: ---   
Hardware: PC   
OS: All   

Description Artem Troitskiy 2011-06-15 10:14:25 UTC
When a pre-existing instance of Servlet class is added dynamically by calling ServletContext.addServlet(String, Servlet) in ServletContainerInitializer, multiple problems arise:

 * setLoadOnStartup() is ignored
 * @ServletSecurity is ignored
 * destroy() can be called on non-initialized servlet

Adding a servlet class (addServlet(String, String), addServlet(String, Class)) doesn't have this problems.

It happens because methods of org.apache.catalina.core.StandardWrapper treat presence of servlet instance as an indicator of the fact that servlet have been initialized, that is not true when addServlet(String, Servlet) is used.
Comment 1 Mark Thomas 2011-06-15 12:04:43 UTC
(In reply to comment #0)
>  * @ServletSecurity is ignored

This is as required by the Servlet spec (section 13.4.1) so this aspect of the bug report is INVALID. This is also made clear in the Servlet 3.0 Javadoc.

I'm still researching the other issues. The specification is ambiguous on what to do here. I'm leaning towards making a change but I need to check that any such change doesn't trigger any TCK failures.
Comment 2 Mark Thomas 2011-06-15 12:48:20 UTC
The Servlet TCK still passes with my change in place so I am going to go ahead and commit it to fix this issue. I'll be a little while as I need to write a test case first.
Comment 3 Mark Thomas 2011-06-15 13:21:19 UTC
Fixed in 7.0.x and will be included in 7.0.17 onwards.
Comment 4 Artem Troitskiy 2011-06-15 14:50:26 UTC
(In reply to comment #3)
> Fixed in 7.0.x and will be included in 7.0.17 onwards.

This one is still unresolved:

 * destroy() can be called on non-initialized servlet

If servlet added via addServlet(String, Servlet) without setLoadOnStartup() was never accessed, its destroy() method is called during shutdown despite the fact that init() was never called.
Comment 5 Mark Thomas 2011-06-15 20:32:36 UTC
Thanks for the catch. Fixed in 7.0.x and will be in 7.0.17 onwards.