Hey Folks, Tomcat version: 10.1.26 JDK: "21.0.3" 2024-04-16 LTS OS: Macos Sonoma 14.5
I'm looking for clarification on what annotations will be supported when calling ServletContext.createServlet() after the context has been initialized. Some background; I have a tool that inspects a web application where for each discovered Servlet (either declared in the {web,web-fragment}.xml or via annotations) will wrap that Servlet which performs additional logic during init and service before calling through to the actual delegate that we wrapped. When this wrapper's init() is first called by the container, we will instantiate the delegate using ServletContext.createServlet(). The Servlet 6.0 specification states the following: ----------------------------------------------------- 4.4.1.5. <T extends Servlet> T createServlet(Class<T> clazz) This method instantiates the given Servlet class. The method must support all the annotations applicable to servlets except @WebServlet. The returned Servlet instance may be further customized before it is registered with the ServletContext via a call to addServlet(String, Servlet) as defined above. The given Servlet class must define a zero argument constructor, which is used to instantiate it. ----------------------------------------------------- This works fine for cases such as @Inject or @Resource, however, I've found the behavior in the case of @ServletSecurity to differ between containers. For example, Tomcat, Jetty, and Wildlfy appear to ignore @ServletSecurity when calling createServlet() from the wrappers init() method. However, section 13.4.1 has the following constraint on @ServletSecurity: ----------------------------------------------------- When metadata-complete=true is defined for a portable deployment descriptor, the @ServletSecurity annotation does not apply to any of the url-patterns mapped to (any servlet mapped to) the annotated class in the deployment descriptor. ----------------------------------------------------- In my test case, the descriptor containing the original Servlet has the metadata-complete attribute set to true. If I set it to false, I find that the security constraints are applied, but only when running with Jetty; Tomcat and Wildfly continue to ignore the desired constraints. Going back to section 4.4 for a moment which states: ----------------------------------------------------- The following methods are provided on the ServletContext interface to enable programmatic definition of servlets, filters and the url pattern(s) that they map to. These methods can only be called during the initialization of the application either from the contexInitialized method of a ServletContextListener implementation or from the onStartup method of a ServletContainerInitializer implementation. ------------------------------------------------------ The javadocs for ServletContext.createServlet() don't impose any restrictions on when it may be called unlike the javadocs for the various dynamic registration methods. I'm curious to see what the devs lurking here think. What should the behavior be? It seems like the spec could use some tightening here either way. Thanks for your time.