From - Tue Sep 16 12:57:02 1997 Received: from mail.fth.sbs.de (mail.fth.sbs.de [192.129.41.35]) by marina.fth.sbs.de (8.8.5/8.8.2) with ESMTP id KAA08585 for ; Tue, 16 Sep 1997 10:57:36 +0200 (MET DST) Received: from ns.sbs.de (firewall.fth.sbs.de [192.129.41.254]) by mail.fth.sbs.de (8.8.6/8.8.6) with ESMTP id KAA06779 for ; Tue, 16 Sep 1997 10:58:12 +0200 (MET DST) Received: from www19.w3.org (www19.w3.org [18.29.0.19]) by ns.sbs.de (8.8.3/8.8.6) with ESMTP id LAA26361 for ; Tue, 16 Sep 1997 11:00:08 +0200 (MDT) Received: by www19.w3.org (8.8.5/8.6.12) id EAA21691; Tue, 16 Sep 1997 04:36:08 -0400 (EDT) Resent-Date: Tue, 16 Sep 1997 04:36:08 -0400 (EDT) Resent-Message-Id: <199709160836.EAA21691@www19.w3.org> Message-Id: <199709160832.KAA17918@www43.inria.fr> X-Mailer: exmh version 1.6.9 8/22/96 To: Ross Golder cc: Yves Lafon , www-jigsaw@w3.org, bmahe@www43.inria.fr In-reply-to: Your message of "Mon, 15 Sep 1997 10:21:50 BST." <341CFE2D.8F74BAC@cpd.co.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Date: Tue, 16 Sep 1997 10:32:44 +0200 From: Benoit Mahe Subject: Re: ServletDirectory resource X-List-URL: http://www.w3.org/pub/WWW/Archives/Public/www-jigsaw/ Resent-From: www-jigsaw@w3.org X-Mailing-List: archive/latest/1746 X-Loop: www-jigsaw@w3.org Sender: www-jigsaw-request@w3.org Resent-Sender: www-jigsaw-request@w3.org Precedence: list Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by marina.fth.sbs.de id KAA08585 X-UIDL: f08553dbe9e78f5bd4c0ef9bc3d6d2b8 Status: U X-Mozilla-Status: 0011 Content-Length: 10543 Hi all! I made some modifications in the servlet support of jigsaw in order to remove some bugs. One of These bugs appears when the Servlet class file is in the classpath. In this case, the servlet is destroyed and inited on each invocation. This is due to the LocalServletLoader. new version of LocalServletLoader.java (in w3c/jigsaw/servlet/ ) --------------- // ServletLoader.java // $Id: LocalServletLoader.java,v 1.9 1997/09/15 09:56:30 bmahe Exp $ // (c) COPYRIGHT MIT and INRIA, 1996. // Please first read the full copyright statement in file COPYRIGHT.html package w3c.jigsaw.servlet; import java.io.*; import java.net.*; import java.util.*; import java.util.zip.*; class ServletClassEntry { long classStamp = 0; Class servletClass = null; File classFile = null; boolean systemClass = false; public boolean isModified() { return (classFile.lastModified() > classStamp); } public void update() { classStamp = classFile.lastModified(); } public ServletClassEntry (File classFile, Class servletClass, boolean systemClass) { this.classFile = classFile; this.servletClass = servletClass; this.classStamp = classFile.lastModified(); this.systemClass = systemClass; } } /** * LocalServletLoader : * @author Benoit Mahe */ public class LocalServletLoader extends ClassLoader { private static final boolean debug = false; private Hashtable classes = null; ServletWrapper wrapper = null; private void trace(String msg) { System.out.println("["+wrapper.getURLPath()+"]: "+msg); } private String packaged(String name) { String cname = new String(name); try { if (cname.endsWith(".class")) { int idx = cname.lastIndexOf("."); cname = cname.substring(0,idx); } return cname.replace('.', '/')+".class"; } catch (Exception ex) { return null; } } /** * Given the class name, return its File name. * @param name The class to be loaded. * @return The File for the class. */ protected File locateClass(String name) { File classfile = null; File base = wrapper.getServletDirectory(); String cname = null; cname = packaged(name); classfile = new File(base, cname); if (classfile != null) if (classfile.exists()) return classfile; String classpath = (String)System.getProperties().get("java.class.path"); StringTokenizer st = new StringTokenizer(classpath, ":"); while (st.hasMoreTokens()) { String path = st.nextToken(); if (path.endsWith(".zip")) { try { ZipFile zfile = new ZipFile(path); ZipEntry zentry = zfile.getEntry(cname); if (zentry != null) return new File(path); } catch (IOException ex) {} } else { classfile = new File(path,cname); if (classfile.exists()) return classfile; } } return null; } public URL getResource(String name) { String url = wrapper.getServletDirectory().getAbsolutePath(); // Return the location of that resource (name resolved by j.l.Class) if ( File.separatorChar != '/' ) url = url.replace(File.separatorChar, '/'); try { return new URL("file", "localhost", url+"/"+name); } catch (MalformedURLException ex) { // Shouldn't fall here return null; } } /** * Get a resource as a stream. * @param name The name of the resource to locate. */ public InputStream getResourceAsStream(String name) { try { URLConnection c = getResource(name).openConnection(); return c.getInputStream(); } catch (IOException ex) { return null; } } protected Class loadClassFile(File file) throws ClassNotFoundException { byte data[] = null; if ( file == null ) throw new ClassNotFoundException("invalid servlet base"); if ( debug ) trace(" located at "+file); try { BufferedInputStream in = new BufferedInputStream( new FileInputStream( file) ); ByteArrayOutputStream out = new ByteArrayOutputStream(512); byte buf[] = new byte[512]; for (int got = 0 ; (got = in.read(buf)) > 0 ; ) out.write(buf, 0, got); data = out.toByteArray(); in.close(); } catch (Exception ex) { if (debug) ex.printStackTrace(); throw new ClassNotFoundException(file.getAbsolutePath()); } // Define the class: return defineClass(data, 0, data.length); } protected Class loadServletClass(String name, boolean resolve) throws ClassNotFoundException { Class c = null; if ( debug ) trace("loading servlet class : "+name); // Look for a cached class first: ServletClassEntry entry = (ServletClassEntry)classes.get(name); if (entry != null) { if (! entry.isModified()) return entry.servletClass; else if (! entry.systemClass) { entry.servletClass = loadClassFile(entry.classFile); if ( resolve ) resolveClass(entry.servletClass); entry.update(); return entry.servletClass; } } SecurityManager s = System.getSecurityManager(); if ( s != null ) { int i = name.lastIndexOf('.'); if ( i >= 0 ) s.checkPackageAccess(name.substring(0, i)); } File file = locateClass(name); // Then look for a system class: try { if ((c = findSystemClass(name)) != null) { classes.put(name, new ServletClassEntry(file,c,true)); return c; } } catch (Exception ex) {} c = loadClassFile(file); if ( resolve ) resolveClass(c); classes.put(name, new ServletClassEntry(file,c,false)); if ( debug ) trace(name+": loading done."); return c; } protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class c = null; if ( debug ) trace("loading class : "+name); // Look for a cached class first: ServletClassEntry entry = (ServletClassEntry)classes.get(name); if (entry != null) { if (! entry.isModified()) return entry.servletClass; else if (! entry.systemClass) { entry.servletClass = loadClassFile(entry.classFile); if ( resolve ) resolveClass(entry.servletClass); entry.update(); return entry.servletClass; } } SecurityManager s = System.getSecurityManager(); if ( s != null ) { int i = name.lastIndexOf('.'); if ( i >= 0 ) s.checkPackageAccess(name.substring(0, i)); } // Then look for a system class: try { if ((c = findSystemClass(name)) != null) return c; } catch (Exception ex) { } File file = locateClass(name); c = loadClassFile(file); if ( resolve ) resolveClass(c); classes.put(name, new ServletClassEntry(file,c,false)); if ( debug ) trace(name+": loading done."); return c; } protected LocalServletLoader(ServletWrapper wrapper) { super(); this.wrapper = wrapper; this.classes = new Hashtable(13); } protected LocalServletLoader(LocalServletLoader loader) { super(); this.wrapper = loader.wrapper; // this.classes = loader.classes; this.classes = new Hashtable(13); } public File getClassFile(String name) { ServletClassEntry entry = (ServletClassEntry)classes.get(name); if (entry != null) return entry.classFile; return null; } public boolean classChanged(String name) { ServletClassEntry entry = (ServletClassEntry)classes.get(name); if (entry != null) { if (debug) { System.out.println("entry : "+name); System.out.println("file : "+entry.classFile.getAbsolutePath()); System.out.println("Stamp : "+entry.classStamp); System.out.println("System : "+entry.systemClass); System.out.println("modified : "+entry.isModified()); } return entry.isModified(); } return true; } } --------------- in ServletWrapper.java change method launchServlet() by protected boolean launchServlet() { // Get and check the servlet class: if ( servlet != null ) destroyServlet(); String clsname = getServletClass(); if ( clsname == null ) { getServer().errlog(this, "no servlet class attribute defined."); return false; } else { Class c = null; try { if (loader.classChanged(clsname)) loader = new LocalServletLoader(this.loader); c = loader.loadServletClass(clsname, true); } catch (ClassNotFoundException ex) { if ( debug ) ex.printStackTrace(); String msg = ("unable to load servlet class \""+ getServletClass()+ "\" : "+ ex.getMessage()); getServer().errlog(msg); } return (c != null) ? launchServlet(c) : false; } } ---------------- in JigsawHttpServletRequest.java change method getPathTranslated by public String getPathTranslated() { String pathinfo = getPathInfo(); if ( pathinfo != null ) { httpd server = request.getClient().getServer(); HTTPResource root = server.root; try { LookupState ls = new LookupState(pathinfo); LookupResult lr = new LookupResult(root); HTTPResource path = null; if (root.lookup(ls,lr)) path = lr.getTarget(); if (path != null) if (path instanceof FileResource) return ((FileResource)path).getFile().getAbsolutePath(); else if (path instanceof DirectoryResource) return ((DirectoryResource)path).getDirectory().getAbsolutePath(); else return null; else return null; } catch (HTTPException ex) {return null;} } return null; } thanks to Andreas Bufe -------- in JigsawHttpServletResponse.java change method containsHeader public boolean containsHeader(String header) { return reply.hasHeader(header); } ------- So, that's all. (I hope :) ) I made some tests and it seems to work correctly now. - Benoît Mahé ------------------------------------------------------- World Wide Web Consortium bmahe@sophia.inria.fr Architecture domain - Jigsaw Team tel : 04 93 65 79 89 ---------------------------------------------------------------------