Reputation: 1727
I need to programmatically add and remove a servlet on a Jetty 6 server. While it is almost straighforward to add I cannot find an effective way to remove. For my purposes it is important to add and remove a servlet because it is associated to a dynamic compontent architecture. I need to add a new service when I add a component and I need to remove the service when I remove the component.
To add a servlet I used this pattern:
Server server = new Server(8080);
class MyServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
resp.getOutputStream().write("Hello World!".getBytes());
}
}
...
public void addServlet(HttpServlet s, String path)
{
Context root = new Context(server,"/",Context.SESSIONS);
root.addServlet(new ServletHolder(new MyServlet()), "/test/*");
root.getServletHandler().
}
public void removeServlet(HttpServlet s, String path)
{
//What I have to put here ? There is no removeServlet like methods in server/Context/ServletHolder
}
Why removing a servlet is not so obvious? Can you explain me the motivations ?
Upvotes: 2
Views: 3438
Reputation: 1727
This solution seems to be working:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.ContextHandler;
import org.mortbay.jetty.handler.ContextHandlerCollection;
import org.mortbay.jetty.handler.ResourceHandler;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHandler;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.ServletMapping;
public class MyServer extends Server
{
ServletHandler sh = new ServletHandler();
public MyServer()
{
super(9090);
setHandler(sh);
test();
}
class MyServlet extends HttpServlet
{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
resp.getWriter().println("CIAO!");
}
}
void test()
{
MyServlet ms = new MyServlet();
addServlet(ms, "/ciao/*");
//removeServlet(ms);//uncomment this ilne in order to remove the servlet right after the deploy
}
public void addServlet(HttpServlet s, String path)
{
sh.addServletWithMapping(new ServletHolder(s), path);
for (ServletHolder so : sh.getServlets())
try
{
System.out.println((so.getServlet() == s));
} catch (ServletException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void removeServlet(HttpServlet s)
{
try
{
HashSet<String> names = new HashSet<String>();
for (ServletHolder so : sh.getServlets())
if (so.getServlet() == s)
names.add(so.getName());
HashSet<ServletMapping> sms = new HashSet<ServletMapping>();
for (ServletMapping sm : sh.getServletMappings())
{
if (!names.contains(sm.getServletName()))
sms.add(sm);
}
sh.setServletMappings(sms.toArray(new ServletMapping[] {}));
} catch (ServletException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Upvotes: 0
Reputation: 6519
Here's instructions for doing it on Jetty 7.
Jetty : Dynamically removing the registered servlet
It should be pretty straight forward to port that code to Jetty 6.
Upvotes: 1
Reputation: 7182
first off I would recommend updating to jetty 7 or 8 if its possible, jetty 6 is quite old at this point and is lacking the last couple years of development that are present in 7 and 8. heck, jetty 9 is being actively worked on now.
second I wouldn't look at this on the servlet level but the handler level, working with the server to add and remove handlers, which can be either static resource type handlers or full fledged servlet context handlers, or even webapp context handlers.
as to why the servlet context handlers do not have remove servlet type operations, its really not a part of the servlet spec to remove active servlets at that level, fits more at the war deploy/undeploy level. feel free to open an issue on it though, I did experiment with adding and removing at servlet context handler level and you can remove them but it seems to be problematic then adding more afterwards, so I suspect removing the context itself and adding a new one would be your best bet at this point.
Upvotes: 1