开发者

With Tomcat 5.5, how can I programmatically locate a specific servlet instance or add new mappings?

I understand that this is nor开发者_StackOverflowmally not done, and I've found a number of instances of this question around the web with answers of the sort: "Your design is wrong if you need to do this." Let me explain my goal.

I have a web app that at one site somehow caused one servlet's init() method to be called repeatedly. I don't know how this happened and I cannot repeat it. However, from a binary heap dump (caused by an out-of-memory exception), it is very clear from objects on the heap that a specific servlet's init() method got called about 10,000 times, as that is the only place these objects are created and there were 10,000+ instances of an object that is supposed to have no more than one instance.

Since I cannot reproduce what happened at this one site, I instead want to forcefully invoke init() many times on this servlet, preferably via a JSP file, so I can test before and after a fix is applied. Testing the "after" case is easy in theory because I can change the code to (for example) stick this servlet into the context so I can get it and repeatedly call init() to prove that there is no leak of this object. But this does not help me test the "before" case with the existing code.

I cannot just "(new MyServlet()).init()" in a JSP. This fails as the servlet is created with a null context and fails to initialize. By Tomcat 5.5, it seems that ServletContext.getServlets() always returns an empty Enumeration and that ServletContext.getServlet(String) always returns null.

It seems the easiest way to test is if I can somehow programmatically (preferably from a JSP) get access to the servlet instance in question, or alternately, programmatically add new mappings to that same servlet class, which might create new instances. (?)


You've already figured out that what you are attempting is highly out of the ordinary and far from a best practice so I won't go into any detail on that subject. Having said that, if you want to invoke MyServlet.init() many times on an instance of MyServlet running within Tomcat, you could subclass MyServlet, override the doGet() or doPost() method, add a loop that simply calls this.init(); 1000 times and then call the parent classes doGet()/doPost(). Edit WEB-INF/web.xml to use your subclass in place of MyServlet. Then just hit the servlet with your web browser and see init() called 1000 times prior to serving the page normally. And you haven't modified the original MyServlet class at all, keeping your before test pure.


You can create a servlet instance like any other class object. Get hold of the servlet config by overriding the method init(ServletConfig config). And create the servlet class instance as many as u want, and call init(ServletConfig config) on all those instances created.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜