Hi, I am currently working on implementing an OSGi Http service based on the full-fledged Tomcat running inside the OSGi environment as an OSGi bundle. To implement Http service, the major functionality I require from Tomcat is that it should allow for dynamic adding/removing servlet and servlet-mapping without having to restart context for many reasons such as performace consideration, etc.
After having worked with Tomcat for some time, I found the goal is hard to achieve without modification to the current code of Tomcat (I am using 5.5.17), the following is my understanding of the reason why: The mapping info are mostly maintained at two places: StandardContext and Connector, each StandardContext only contains servlet-mappings pertaining to itself, but a Connector includes not only all servlet-mappings from all StandardContext instances but also the virtual host, context mappings for the servlet container. The mapping info at these places must be consistent, otherwise, Http request dispatch may run into prolems. The current mechanism used to synchronize them is through JMX Mbean registration/unregistration events: StandardContext creates/destroys servlet wrapper mbeans for the servlets being added/removed to/from the context, and the Connector (actually a MapperListener owned by it) listens to the events and updates its mapping info accordingly. But I found only registerWrapper is provided in MapperListener.java at the moment, no associated unregisterWrapper is there. This prevents previously registered servlet mapping info from being able to be removed from the Connector even if the servlet and its mapping info has been removed from its containing context, and subsequently prevents other servlet from being registered under the same servlet path with Connector. For instance, I first add a servlet X to the root context at path "/test-servlet" and then remove the servlet and its mapping info from the context by invoking removeServletMapping and removeChild on the context, but due to the reason aforementioned, the mapping "/test-servlet" to the servlet will still be kept in Connector. So later, when I try to add a servlet Y to the root context at the same path "/test-servlet" again, the old mapping at path "/test-servlet" kept in Connector will prevent the mapping info from being updated due to the rule that only distinct servlet path is allowed to be registered. This makes the Http requests to the servlet Y mistakenly dispatched by Connector to servlet X and eventually leads to failures. The fix I have tried is that we can add the unregisterWrapper method and corresponding mbean unregistration event handling to the MapperListener.java so that the MapperListener can always keep the mapping info maintained in StandardContext and Connector consistent. Any thoughts? Thanks, Eric --------------------------------- 抢注雅虎免费邮箱-3.5G容量,20M附件!