You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2001/01/13 06:27:54 UTC
cvs commit: jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader StandardClassLoader.java StandardLoader.java
remm 01/01/12 21:27:54
Modified: catalina/src/share/org/apache/catalina/loader
StandardClassLoader.java StandardLoader.java
Log:
- "Fixes" webapp classloading.
- Class files in /WEB-INF/classes are loaded through a URL to a DirContext
(good :).
- JAR files couldn't work that way, so it uses direct filesystem access :(
- You can read the comments about my failed attempt in StandardLoader.
I left the commented code which tries to register JNDI URL repositories.
Unfortunately, it appears that the URLClassLoader (and its hidden helper
classes) don't like my URLs. Any explanation / solution would be greatly
appreciated.
Revision Changes Path
1.6 +116 -18 jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java
Index: StandardClassLoader.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- StandardClassLoader.java 2000/10/09 21:04:02 1.5
+++ StandardClassLoader.java 2001/01/13 05:27:54 1.6
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v 1.5 2000/10/09 21:04:02 craigmcc Exp $
- * $Revision: 1.5 $
- * $Date: 2000/10/09 21:04:02 $
+ * $Header: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v 1.6 2001/01/13 05:27:54 remm Exp $
+ * $Revision: 1.6 $
+ * $Date: 2001/01/13 05:27:54 $
*
* ====================================================================
*
@@ -71,11 +71,16 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.net.URLStreamHandlerFactory;
+import java.net.URLStreamHandler;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.jar.JarFile;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
@@ -99,7 +104,8 @@
* independently.
*
* @author Craig R. McClanahan
- * @version $Revision: 1.5 $ $Date: 2000/10/09 21:04:02 $
+ * @author Remy Maucherat
+ * @version $Revision: 1.6 $ $Date: 2001/01/13 05:27:54 $
*/
public class StandardClassLoader
@@ -122,6 +128,20 @@
/**
+ * Construct a new ClassLoader with no defined repositories and no
+ * parent ClassLoader, but with a stream handler factory.
+ *
+ * @param factory the URLStreamHandlerFactory to use when creating URLs
+ */
+ public StandardClassLoader(URLStreamHandlerFactory factory) {
+
+ super(new URL[0], null, factory);
+ this.factory = factory;
+
+ }
+
+
+ /**
* Construct a new ClassLoader with no defined repositories and the
* specified parent ClassLoader.
*
@@ -135,6 +155,22 @@
/**
+ * Construct a new ClassLoader with no defined repositories and the
+ * specified parent ClassLoader.
+ *
+ * @param parent The parent ClassLoader
+ * @param factory the URLStreamHandlerFactory to use when creating URLs
+ */
+ public StandardClassLoader(ClassLoader parent,
+ URLStreamHandlerFactory factory) {
+
+ super((new URL[0]), parent, factory);
+ this.factory = factory;
+
+ }
+
+
+ /**
* Construct a new ClassLoader with the specified repositories and
* no parent ClassLoader.
*
@@ -263,6 +299,12 @@
protected String systems[] = { "java." };
+ /**
+ * URL stream handler for additional protocols.
+ */
+ protected URLStreamHandlerFactory factory = null;
+
+
// ------------------------------------------------------------- Properties
@@ -352,7 +394,12 @@
// Add this repository to our underlying class loader
try {
- super.addURL(new URL(repository));
+ URLStreamHandler streamHandler = null;
+ String protocol = parseProtocol(repository);
+ if (factory != null)
+ streamHandler = factory.createURLStreamHandler(protocol);
+ URL url = new URL(null, repository, streamHandler);
+ super.addURL(url);
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e.toString());
}
@@ -1028,6 +1075,21 @@
/**
+ * Parse URL protocol.
+ *
+ * @return String protocol
+ */
+ protected static String parseProtocol(String spec) {
+ if (spec == null)
+ return "";
+ int pos = spec.indexOf(':');
+ if (pos <= 0)
+ return "";
+ return spec.substring(0, pos).trim();
+ }
+
+
+ /**
* Add a repository to our internal array only.
*
* @param repository The new repository
@@ -1037,12 +1099,18 @@
*/
protected void addRepositoryInternal(String repository) {
+ URLStreamHandler streamHandler = null;
+ String protocol = parseProtocol(repository);
+ if (factory != null)
+ streamHandler = factory.createURLStreamHandler(protocol);
+
// Validate the manifest of a JAR file repository
if (!repository.endsWith("/")) {
try {
JarFile jarFile = null;
+ Manifest manifest = null;
if (repository.startsWith("jar:")) {
- URL url = new URL(repository);
+ URL url = new URL(null, repository, streamHandler);
JarURLConnection conn =
(JarURLConnection) url.openConnection();
conn.setAllowUserInteraction(false);
@@ -1054,23 +1122,34 @@
jarFile = new JarFile(repository.substring(7));
} else if (repository.startsWith("file:")) {
jarFile = new JarFile(repository.substring(5));
+ } else if (repository.endsWith(".jar")) {
+ URL url = new URL(null, repository, streamHandler);
+ URLConnection conn = url.openConnection();
+ JarInputStream jis =
+ new JarInputStream(conn.getInputStream());
+ manifest = jis.getManifest();
} else {
throw new IllegalArgumentException
("addRepositoryInternal: Invalid URL '" +
repository + "'");
+ }
+ if (!((manifest == null) && (jarFile == null))) {
+ if ((manifest == null) && (jarFile != null))
+ manifest = jarFile.getManifest();
+ Iterator extensions =
+ Extension.getAvailable(manifest).iterator();
+ while (extensions.hasNext())
+ available.add(extensions.next());
+ extensions =
+ Extension.getRequired(manifest).iterator();
+ while (extensions.hasNext())
+ required.add(extensions.next());
+ jarFile.close();
}
- Manifest manifest = jarFile.getManifest();
- Iterator extensions =
- Extension.getAvailable(manifest).iterator();
- while (extensions.hasNext())
- available.add(extensions.next());
- extensions =
- Extension.getRequired(manifest).iterator();
- while (extensions.hasNext())
- required.add(extensions.next());
- jarFile.close();
} catch (Throwable t) {
- throw new IllegalArgumentException("addRepositoryInternal: " + t);
+ t.printStackTrace();
+ throw new IllegalArgumentException
+ ("addRepositoryInternal: " + t);
}
}
@@ -1091,11 +1170,30 @@
* @param input The array of String to be converted
*/
protected static URL[] convert(String input[]) {
+ return convert(input, null);
+ }
+
+
+ /**
+ * Convert an array of String to an array of URL and return it.
+ *
+ * @param input The array of String to be converted
+ * @param factory Handler factory to use to generate the URLs
+ */
+ protected static URL[] convert(String input[],
+ URLStreamHandlerFactory factory) {
+
+ URLStreamHandler streamHandler = null;
URL url[] = new URL[input.length];
for (int i = 0; i < url.length; i++) {
try {
- url[i] = new URL(input[i]);
+ String protocol = parseProtocol(input[i]);
+ if (factory != null)
+ streamHandler = factory.createURLStreamHandler(protocol);
+ else
+ streamHandler = null;
+ url[i] = new URL(null, input[i], streamHandler);
} catch (MalformedURLException e) {
url[i] = null;
}
1.15 +78 -29 jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader/StandardLoader.java
Index: StandardLoader.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader/StandardLoader.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- StandardLoader.java 2001/01/12 06:46:54 1.14
+++ StandardLoader.java 2001/01/13 05:27:54 1.15
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader/StandardLoader.java,v 1.14 2001/01/12 06:46:54 remm Exp $
- * $Revision: 1.14 $
- * $Date: 2001/01/12 06:46:54 $
+ * $Header: /home/cvs/jakarta-tomcat-4.1/catalina/src/share/org/apache/catalina/loader/StandardLoader.java,v 1.15 2001/01/13 05:27:54 remm Exp $
+ * $Revision: 1.15 $
+ * $Date: 2001/01/13 05:27:54 $
*
* ====================================================================
*
@@ -73,7 +73,13 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
import javax.servlet.ServletContext;
+import javax.naming.NamingException;
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.DirContext;
+import org.apache.naming.resources.DirContextURLStreamHandlerFactory;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
@@ -100,7 +106,8 @@
* is not present, the system class loader will be used instead.
*
* @author Craig R. McClanahan
- * @version $Revision: 1.14 $ $Date: 2001/01/12 06:46:54 $
+ * @author Remy Maucherat
+ * @version $Revision: 1.15 $ $Date: 2001/01/13 05:27:54 $
*/
public final class StandardLoader
@@ -580,10 +587,16 @@
// Construct a class loader based on our current repositories list
try {
+ URLStreamHandlerFactory shFactory = null;
+ if ((this.container != null) &&
+ (this.container.getResources() != null))
+ shFactory = new DirContextURLStreamHandlerFactory
+ (this.container.getResources());
if (parentClassLoader == null)
- classLoader = new StandardClassLoader();
+ classLoader = new StandardClassLoader(shFactory);
else
- classLoader = new StandardClassLoader(parentClassLoader);
+ classLoader = new StandardClassLoader
+ (parentClassLoader, shFactory);
for (int i = 0; i < repositories.length; i++)
classLoader.addRepository(repositories[i]);
classLoader.addRestricted("org.apache.catalina.");
@@ -858,34 +871,70 @@
}
// Add the WEB-INF/lib/*.jar files
- URL libURL = null;
- try {
- libURL = servletContext.getResource("/WEB-INF/lib");
- } catch (MalformedURLException e) {
- libURL = null;
- }
// FIXME - This still requires disk directory! Scan JARs if present
- if ((libURL != null) && "file".equals(libURL.getProtocol())) {
- File libFile = new File(libURL.getFile());
- if (libFile.exists() && libFile.canRead() &&
- libFile.isDirectory()) {
- String filenames[] = libFile.list();
- for (int i = 0; i < filenames.length; i++) {
- if (!filenames[i].endsWith(".jar"))
+ File libFile = new File(((Context) container).getDocBase(),
+ "/WEB-INF/lib");
+ if (libFile.exists() && libFile.canRead() &&
+ libFile.isDirectory()) {
+ String filenames[] = libFile.list();
+ for (int i = 0; i < filenames.length; i++) {
+ if (!filenames[i].endsWith(".jar"))
+ continue;
+ File jarFile = new File(libFile, filenames[i]);
+ try {
+ if (debug > 0)
+ log(" Adding '" + "file: " +
+ jarFile.getCanonicalPath() + "'");
+ addRepository("file:" + jarFile.getCanonicalPath());
+ } catch (IOException e) {
+ log(jarFile.getAbsolutePath(), e);
+ }
+ }
+ }
+
+ // FIXME: The code below is the elegant version of the ten lines of
+ // code above. The problem is that it doesn't work due to some
+ // classloading issues (the URL classloader doesn't seem to like my
+ // URL objects when they point to JAR files, although loading of
+ // individual classes work fine).
+
+/*
+ DirContext resources = container.getResources();
+ String libName = "/WEB-INF/lib";
+ DirContext libDir = null;
+ // Looking up directory /WEB-INF/lib in the context
+ try {
+ Object object = resources.lookup(libName);
+ if (object instanceof DirContext)
+ libDir = (DirContext) object;
+ } catch(NamingException e) {
+ // Silent catch: it's valid that no /WEB-INF/lib directory exists
+ }
+
+ // Add the WEB-INF/lib/*.jar files
+ if (libDir != null) {
+ // Enumerate children
+ try {
+ NamingEnumeration enum = resources.list(libName);
+ while (enum.hasMoreElements()) {
+ NameClassPair ncPair = (NameClassPair) enum.nextElement();
+ String filename = ncPair.getName();
+ if (!filename.endsWith(".jar"))
continue;
- File jarFile = new File(libFile, filenames[i]);
try {
- if (debug > 0)
- log(" Adding '" + "file: " +
- jarFile.getCanonicalPath() + "'");
- addRepository("file:" + jarFile.getCanonicalPath());
- } catch (IOException e) {
- log(jarFile.getAbsolutePath(), e);
+ URL fileURL = servletContext.getResource
+ (libName + "/" + filename);
+ log(" Adding '" + "file: " +
+ libName + "/" + filename + "'");
+ addRepository(fileURL.toString());
+ } catch (MalformedURLException e) {
}
- }
- }
+ }
+ } catch(NamingException e) {
+ }
}
-
+*/
+
}