DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25079>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND
INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=25079
Tomcat 5.0.14 classloader bug
Summary: Tomcat 5.0.14 classloader bug
Product: Tomcat 5
Version: 5.0.14
Platform: Other
OS/Version: Linux
Status: NEW
Severity: Critical
Priority: Other
Component: Catalina
AssignedTo: tomcat-dev@jakarta.apache.org
ReportedBy: gbevin@uwyn.com
I think I've stumbled into a bug in the webapp classloader in Tomcat 5.0.14.
Consider the following servlet, which I mapped to /* for testing convenience.
import java.io.*;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Test extends HttpServlet
{
public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
PrintWriter out = res.getWriter();
URL rsrc = getClass().getResource("Test.class");
String tst = rsrc.toString()+" : "+
rsrc.openStream()+" : "+
getClass().getResourceAsStream("Test.class");
out.println(tst);
out.close();
}
}
When I put the compiled class file in ROOT/WEB-INF/classes
and visit http://localhost:8080/ after a server startup, I get the following page:
file:/jakarta-tomcat-5.0.14/webapps/ROOT/WEB-INF/classes/Test.class :
java.io.BufferedInputStream@6a3960 : java.io.ByteArrayInputStream@1dccedd
When I create a jar file with just that class inside, put it in ROOT/WEB-INF/lib
(after removing everything from ROOT/WEB-INF/classes before) and visit
http://localhost:8080/ after a server restart, I get the following page:
HTTP Status 500 -
type Exception report
message
description The server encountered an internal error () that prevented it from
fulfilling this request.
exception
java.io.FileNotFoundException:
/jakarta-tomcat-5.0.14/work/Catalina/localhost/_/loader/Test.class
(No such file or directory)
java.io.FileInputStream.open(Native Method)
java.io.FileInputStream.(FileInputStream.java:106)
java.io.FileInputStream.(FileInputStream.java:66)
sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:69)
sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:156)
java.net.URL.openStream(URL.java:913)
Test.service(Test.java:13)
javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
The openStream() method has thrown this exception, and the
getResourceAsStream("Test.class") method returns null.
There's clearly something wrong here, since the file is indeed not available on
that location. The work directory
"/jakarta-tomcat-5.0.14/work/Catalina/localhost/_" just contains one file:
"tldCache.ser" and no directory "loader" at all.
I've looked through the sources and found some things in
org.apache.catalina.loader.WebappClassLoader.
On line 552, the following is done:
public void setWorkDir(File workDir) {
this.loaderDir = new File(workDir, "loader");
}
Which is where the "loader" directory comes from.
On line 1085, the following is done:
if (repository.endsWith(".jar")) {
// Copy binary content to the work directory if not present
File resourceFile = new File(loaderDir, name);
url = resourceFile.toURL();
}
On line 1814, I found this:
// Extract resources contained in JAR to the workdir
if (!(path.endsWith(".class"))) {
byte[] buf = new byte[1024];
File resourceFile = new File
(loaderDir, jarEntry.getName());
if (!resourceFile.exists()) {
...
To me it seems that the code on line 1085 assumes that the code on line 1814 has
already been executed before, somehow this isn't the case which leads to
unretrieval resources when they are stored in jar files.
I hope I identified this issue correctly and that it can be fixed for the next
release.
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org
|