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附件!