This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Allow getResource() for core classes


This fixes a longstanding compatibility problem.  Some code likes to
do things like

    InputStream is 
      = (ResourceTest.class
	 .getClassLoader()
	 .getResourceAsStream("java/lang/Object.class"));

and this hasn't ever worked with gcj.  I've worked around the problem
here by creating a URLClassLoader that is only used for getResource*
invocations.

Andrew.


2007-04-13  Andrew Haley  <aph@redhat.com>

	* gnu/gcj/runtime/BootClassLoader.java (getBootURLLoader): New
	method.
	(bootGetResource): Use getBootURLLoader() to load resources.
	(bootGetResources): Likewise.

Index: BootClassLoader.java
===================================================================
--- BootClassLoader.java	(revision 123473)
+++ BootClassLoader.java	(working copy)
@@ -9,9 +9,13 @@
 package gnu.gcj.runtime;
 
 import gnu.java.net.protocol.core.Handler;
+import java.io.File;
 import java.io.IOException;
 import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
 
 /**
  * This is a helper for the bootstrap class loader.  It is a
@@ -27,6 +31,9 @@
   // path fails otherwise.
   static Class coreHandler = gnu.java.net.protocol.core.Handler.class;
 
+  private boolean initialized;
+  private URLClassLoader bootURLLoader;
+
   BootClassLoader(String libdir)
   {
     // The BootClassLoader is the top of the delegation chain. It does not
@@ -68,13 +75,64 @@
     return c;
   }
 
+  // Parse the boot classpath and create a URLClassLoader that loads
+  // resources from it.  This is provided for the benefit of code that
+  // does things like
+  //   ClassLoader.getResourceAsStream("java/lang/Object.class")
+  private synchronized URLClassLoader getBootURLLoader()
+  {
+    if (initialized)
+      return bootURLLoader;
+    initialized = true;
+
+    Vector<URL> urls = new Vector<URL>();
+    String bootClasspath = System.getProperty ("sun.boot.class.path");
+    StringTokenizer st =
+      new StringTokenizer(bootClasspath, File.pathSeparator);
+    while (st.hasMoreTokens())
+      {
+	try
+	  {
+	    urls.add(new File(st.nextToken().toURL());
+	  }
+	catch (java.net.MalformedURLException e)
+	  {
+	  }
+      }
+
+    if (urls.size() > 0)
+      bootURLLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
+    return bootURLLoader;
+  }
+
   public URL bootGetResource(String name)
   {
-    return findResource(name);
+    URL url = findResource(name);
+    if (url != null)
+      return url;
+
+    URLClassLoader loader = getBootURLLoader();
+    if (loader != null)
+      url = loader.findResource(name);
+
+    return url;
   }
 
   public Enumeration bootGetResources(String name) throws IOException
   {
-    return findResources(name);
+    URLClassLoader loader = getBootURLLoader();
+    Enumeration[] e =
+      {
+	findResources(name),
+	(loader != null) ? loader.findResources(name) : null
+      };
+
+    Vector v = new Vector();
+    for (Enumeration en : e)
+      if (en != null)
+	while (en.hasMoreElements())
+	  v.add(en.nextElement());
+
+    return v.elements();
   }
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]