Bug 19219 - Exception from java.util.zip.ZipFile after reloading an application
Summary: Exception from java.util.zip.ZipFile after reloading an application
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Jasper (show other bugs)
Version: Nightly Build
Hardware: PC other
: P3 major (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-04-22 15:16 UTC by Petr Jiricka
Modified: 2004-11-16 19:05 UTC (History)
1 user (show)



Attachments
The first version of the test web module (3.04 KB, application/octet-stream)
2003-04-22 15:18 UTC, Petr Jiricka
Details
The second version of the test web module (4.18 KB, application/octet-stream)
2003-04-22 15:18 UTC, Petr Jiricka
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Petr Jiricka 2003-04-22 15:16:48 UTC
I am getting the following exception after after reloading an application which
uses tag libraries. I am using Tomcat 5.0 nightly build 20030421 with JDK 1.4.2
beta (I believe this will be reproducible on 1.4.1 as well, though).

I am attaching only the root cause, not the ServletException which wraps it.
Steps to reproduce are below.


java.lang.InternalError: jzentry == 0,
 jzfile = 406263984,
 total = 4,
 name = E:\software\tomcat50nightly\webapps\taglibtest\WEB-INF\lib\Test1.jar,
 i = 3,
 message = invalid LOC header (bad signature)
	at java.util.zip.ZipFile$2.nextElement(ZipFile.java:321)
	at java.util.jar.JarFile$1.nextElement(JarFile.java:211)
	at
org.apache.jasper.compiler.TldLocationsCache.processTldsInJar(TldLocationsCache.java:320)
	at
org.apache.jasper.compiler.TldLocationsCache.processTldsInGlobalJars(TldLocationsCache.java:455)
	at org.apache.jasper.compiler.TldLocationsCache.init(TldLocationsCache.java:215)
	at
org.apache.jasper.compiler.TldLocationsCache.getLocation(TldLocationsCache.java:188)
	at
org.apache.jasper.JspCompilationContext.getTldLocation(JspCompilationContext.java:557)
	at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:452)
	at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:514)
	at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1562)
	at org.apache.jasper.compiler.Parser.parse(Parser.java:171)
	at org.apache.jasper.compiler.ParserController.parse(ParserController.java:248)
	at org.apache.jasper.compiler.ParserController.parse(ParserController.java:150)
	at org.apache.jasper.compiler.ParserController.parse(ParserController.java:137)
	at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:250)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:458)
	at org.apache.jasper.compiler.Compiler.compile(Compiler.java:444)
	at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:593)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:300)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:293)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:240)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
	at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:288)
	at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:263)
	at
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:552)
	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1017)
	at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:196)
	at
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:552)
	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1017)
	at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2708)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:186)
	at
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
	at
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
	at
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
	at
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:552)
	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1017)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:163)
	at
org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:552)
	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1017)
	at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:199)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:630)
	at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:463)
	at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:568)
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:631)
	at java.lang.Thread.run(Thread.java:534)


The scenario in which this occurs is basically the following:
1. Create a web application with a tag library and a JSP which uses this taglib
2. Run the application in Tomcat (put it to e.g. webapps/taglibtest) and run the JSP
3. Add a tag to the tag library, use this new tag in the JSP and copy it over to
Tomcat again
4. Reload the application using the manager application:
http://localhost:8080/manager/reload?path=/taglibtest
5. Run the JSP again
This is basically a consequence of JDK bug 4425695/4843994:

http://developer.java.sun.com/developer/bugParade/bugs/4843994.html
http://developer.java.sun.com/developer/bugParade/bugs/4425695.html

I believe it could be fixed by not caching the JarURLConnection in
TldLocationsCache.processTldsInJar(...) by setting connection.setUseCaches(false).

I am attaching two versions of the web module I tested this with, and steps to
reproduce with these:

1. Unzip wm1.zip to webapps/taglibtest
2. Start Tomcat
3. Run http://localhost:8080/taglibtest/UsesTestTL.jsp
4. Unzip wm2.zip to webapps/taglibtest
5. "Touch" the UsesTestTL.jsp file, so Jasper reloads it
6. Reload the application using
http://localhost:8080/manager/reload?path=/taglibtest
7. Run http://localhost:8080/taglibtest/UsesTestTL.jsp again
The exception is displayed in the browser.
Comment 1 Petr Jiricka 2003-04-22 15:18:02 UTC
Created attachment 5953 [details]
The first version of the test web module
Comment 2 Petr Jiricka 2003-04-22 15:18:35 UTC
Created attachment 5954 [details]
The second version of the test web module
Comment 3 Remy Maucherat 2003-06-25 08:25:09 UTC
Many file locking issues were fixed, and this should make this kind of webapp
update scenario work a lot better.

However, I don't see how the scenario you describe could work reliably (on
Windows, the JAR could be locked if you try to ovewrite it while the webapp is
running). IMO, you should do:
- stop webapp
- update it
- start webapp
Comment 4 Petr Jiricka 2003-06-25 09:52:53 UTC
Remy, thanks for all the fixes.

As for whether this scenario can or can not work - I agree it won't work in 100%
of cases. However documentation:

http://jakarta.apache.org/tomcat/tomcat-5.0-doc/appdev/source.html
http://jakarta.apache.org/tomcat/tomcat-5.0-doc/appdev/processes.html

seems to suggest that you should be doing 'compile' and then 'reload'. So do we
want to change the documentation to recommend doing 'undeploy', then 'compile'
and then 'deploy' ?

What should Tomcat recommend to the users so development works reliably and
correctly for them ?