Created attachment 22549 [details] demo jsp and servlet with index.html. Install into $CATALINA_HOME/webapps I am not sure if this is a duplicate of https://issues.apache.org/bugzilla/show_bug.cgi?id=41606, but it sounds a bit different and applies to 5.5.26. The jsp is deployed without explicit web.xml definition, so it is loaded when the first client request arrives. The call sequence is usually (but not always) as follows: jspInit _jspService jspDestroy jspInit _jspService _jspService etc.. This is hard to program around when using jspInit to set up a complex set of background processes. They get torn down unnecessarily, only to be loaded up immediately afterward. However, there is enough variability to make it dangerous to assume the first jspDestroy will always be followed by jspInit - it might be a REAL jspDestroy and the cleanup is really necessary. I have attached a war that demonstrates the problem. There is an index.html that will run either a demo servlet (which works properly with init/destroy) or a demo jsp (which usually fails). The apps display the call sequence graphically, but entries are also written to the catalina log file.
Thanks for the test case. A good test case makes it so much easier to investigate an issue. Unfortunately in this case I can't reproduce this on the latest 5.5.x code with your test case. I also tested trunk with the same result. I would point out that Servlet containers are free to create and destroy servlet instances as they see fit. See SRV.2.3.4 for the exact wording. I would guess that for your use case a ServletContextListener would be a better choice.
I made a clean install of the new 5.5.27 release on a different machine. I added my demo war and started tomcat. The servlet still works as designed and the jsp still flags the antisocial behaviour.... the jsp was destroyed after the first service and then was immediately re-initialised. I then stopped tomcat and restarted it using the already deployed webapp. This time (to my surprise) the jsp was not destroyed. I used the tomcat manager to stop and start the webapp. It worked fine. I undeployed it and re-copied the war to automatically deploy. 2 services and then an unnecessary destroy/init. I reloaded the webapp, and it worked fine. I copied the war to get it redeployed - 2 services and then an unnecessary destroy/init. I have no problem with the specification allowing Servlet containers to create and destroy servlet (and jsp) instances when necessary, but this behaviour is just perverse and wasteful of resources. The whole point of init/destroy is to be able to setup a shared pool of "expensive" resources that need to be conserved over a long period of time. I can do more work on this if you would like. At the moment, the evidence points to some kind of timing issue related to deployment of a new war and subsequent compilation of the jsp. My earlier tests with 5.5.26 (and older releases) on other machines showed the perverse behaviour could occur after a simple tomcat stop/start cycle (i.e. no jsp compilation), but I have no evidence of this happening on a clean install of the latest version of tomcat. Regards, Brian
Thanks for the additional testing - it explains why I couldn't reproduce it. I'll take another look at what is going on. If you need to create long-lived resources I really do encourage you to look at ServletContextListener.
(In reply to comment #3) > Thanks for the additional testing - it explains why I couldn't reproduce it. > I'll take another look at what is going on. I can confirm the behavior posted by Brian for Tomcat 5.5.20 and 5.5.27. After changing a JSP, the generated Servlet will be instantiated twice, so the described sequence init-destroy-init will appear. I tested with the following JSP: <%-- Bug 45774 - jspDestroy called after deployment, the second jspInit follows Bug 41606 - The jspInit method is called twice. --%> <jsp:declaration> int counter = 0; private static long st = System.currentTimeMillis(); private long it = System.currentTimeMillis(); private long time = it - st; private static Object firstInstance; private Object secondInstance; public void init() throws ServletException { long ltime = System.currentTimeMillis() - st; System.out.println("init: " + this + ", time=" + time); if (time == 0) firstInstance = this; if (firstInstance != this) secondInstance = this; } </jsp:declaration> <html> <head> <title>InitTwice.jsp</title> </head> <body> <h1>InitTwice.jsp</h1> counter=<jsp:expression>++counter</jsp:expression> <br> current page=<jsp:expression>page</jsp:expression> <hr> first=<%= firstInstance %> <br> second=<%= secondInstance %> <br> time=<%= time %> </body> </html> Gerhard
The original report contains a patch. The dup contains a test case. *** This bug has been marked as a duplicate of bug 41606 ***