From 31280fb7c47e6a32289b4dfc47880a9f22a9d9b4 Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Sun, 26 Nov 2000 03:58:56 +0000 Subject: prims.cc (_Jv_NewObjectArray): Undo placement change. 2000-11-25 Anthony Green * prims.cc (_Jv_NewObjectArray): Undo placement change. (_Jv_NewPrimArray): Likewise. * gcj/array.h (__JArray): Undo const change. Removed constructor. (class JArray): Removed constructor. * java/lang/Thread.java (context_class_loader): New private data. (getContextClassLoader): New method. (setContextClassLoader): New method. (Thread): Initialize context_class_loader. * java/net/URLClassLoader.java: Import java.util.Enumeration. (getResource): Rename to findResource. (findResource): New method. Used to be getResource. (getResourceAsStream): Deleted. (jarFileize): Extracted logic from URLClassLoader constructor into this new private method. (addURL): New protected method. (URLClassLoader): Call jarFileize. Use addElement instead of insertElementAt. (findResources): New method. * java/lang/ClassLoader.java: Import java.util.Enumeration. (getResource): Implement correct logic. (findResource): New method. (getResources): New method. (findClass): Create a ClassNotFoundException with the name of the class rather than nothing at all. (defineClass) Only throw ClassFormatError. * java/lang/Class.java (forName): New method. * java/lang/Class.h (forName): New method. * java/lang/natClass.cc (forName): New method. From-SVN: r37751 --- libjava/gcj/array.h | 14 +--- libjava/java/lang/Class.h | 1 + libjava/java/lang/Class.java | 2 + libjava/java/lang/ClassLoader.java | 76 ++++++++++++++++---- libjava/java/lang/Thread.java | 30 +++++--- libjava/java/lang/natClass.cc | 19 +++-- libjava/java/net/URLClassLoader.java | 136 ++++++++++++++++++++++------------- libjava/prims.cc | 11 +-- 8 files changed, 191 insertions(+), 98 deletions(-) (limited to 'libjava') diff --git a/libjava/gcj/array.h b/libjava/gcj/array.h index 7c65924..b3ba993 100644 --- a/libjava/gcj/array.h +++ b/libjava/gcj/array.h @@ -17,21 +17,9 @@ extern "Java" { class __JArray : public java::lang::Object { -protected: - // FIXME: this is a hack to work around a bug in the g++ Java - // support. If we add a constructor with a jsize argument to - // JArray, then g++ complains. - __JArray () : length (0) - { - } public: - const jsize length; + jsize length; friend jsize JvGetArrayLength (__JArray*); - - // This probably shouldn't be public. - __JArray (jsize l) : length (l) - { - } }; template diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index 0f26c54..edaebb3 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -103,6 +103,7 @@ struct _Jv_ifaces class java::lang::Class : public java::lang::Object { public: + static jclass forName (jstring className, java::lang::ClassLoader *loader); static jclass forName (jstring className); JArray *getClasses (void); diff --git a/libjava/java/lang/Class.java b/libjava/java/lang/Class.java index 0125ab4..0f081eb 100644 --- a/libjava/java/lang/Class.java +++ b/libjava/java/lang/Class.java @@ -30,6 +30,8 @@ public final class Class implements Serializable { public static native Class forName (String className) throws ClassNotFoundException; + public static native Class forName (String className, ClassLoader loader) + throws ClassNotFoundException; public native Class[] getClasses (); public native ClassLoader getClassLoader (); public native Class getComponentType (); diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java index 90f852e..de95603 100644 --- a/libjava/java/lang/ClassLoader.java +++ b/libjava/java/lang/ClassLoader.java @@ -11,8 +11,10 @@ details. */ package java.lang; import java.io.InputStream; +import java.io.IOException; import java.net.URL; import java.net.URLConnection; +import java.util.Enumeration; import java.util.Stack; /** @@ -132,7 +134,7 @@ public abstract class ClassLoader { protected Class findClass (String name) throws ClassNotFoundException { - throw new ClassNotFoundException (); + throw new ClassNotFoundException (name); } /** @@ -154,7 +156,7 @@ public abstract class ClassLoader { * @exception java.lang.LinkageError * @see ClassLoader#defineClass(String,byte[],int,int) */ protected final Class defineClass(byte[] data, int off, int len) - throws java.lang.ClassNotFoundException, java.lang.LinkageError + throws ClassFormatError { return defineClass (null, data, off, len); } @@ -188,7 +190,7 @@ public abstract class ClassLoader { byte[] data, int off, int len) - throws java.lang.ClassNotFoundException, java.lang.LinkageError + throws ClassFormatError { if (data==null || data.length < off+len || off<0 || len<0) throw new ClassFormatError ("arguments to defineClass " @@ -207,10 +209,7 @@ public abstract class ClassLoader { return defineClass0 (name, data, off, len); - } catch (java.lang.LinkageError x) { - throw x; // rethrow - - } catch (java.lang.ClassNotFoundException x) { + } catch (ClassFormatError x) { throw x; // rethrow } catch (java.lang.VirtualMachineError x) { @@ -223,7 +222,7 @@ public abstract class ClassLoader { + "while defining class " + name + ": " + x.toString ()); - } + } } /** This is the entry point of defineClass into the native code */ @@ -231,7 +230,7 @@ public abstract class ClassLoader { byte[] data, int off, int len) - throws java.lang.ClassNotFoundException, java.lang.LinkageError; + throws ClassFormatError; /** @@ -356,8 +355,8 @@ public abstract class ClassLoader { if (res == null) return null; return res.openStream (); } catch (java.io.IOException x) { - return null; - } + return null; + } } /** @@ -369,9 +368,62 @@ public abstract class ClassLoader { * @see java.lang.ClassLoader#getResourceAsStream(String) * @see java.io.URL */ - public URL getResource(String name) { + public URL getResource (String name) + { + // The rules say search the parent class if non-null, + // otherwise search the built-in class loader (assumed to be + // the system ClassLoader). If not found, call + // findResource(). + URL result = null; + + ClassLoader delegate = parent; + + if (delegate == null) + delegate = getSystemClassLoader (); + + // Protect ourselves from looping. + if (this != delegate) + result = delegate.getResource (name); + + if (result != null) + return result; + else + return findResource (name); + } + + protected URL findResource (String name) + { + // Default to returning null. Derived classes implement this. return null; } + public Enumeration getResources (String name) throws IOException + { + // The rules say search the parent class if non-null, + // otherwise search the built-in class loader (assumed to be + // the system ClassLoader). If not found, call + // findResource(). + Enumeration result = null; + + ClassLoader delegate = parent; + + if (delegate == null) + delegate = getSystemClassLoader (); + + // Protect ourselves from looping. + if (this != delegate) + result = delegate.getResources (name); + + if (result != null) + return result; + else + return findResources (name); + } + + protected Enumeration findResources (String name) throws IOException + { + // Default to returning null. Derived classes implement this. + return null; + } } diff --git a/libjava/java/lang/Thread.java b/libjava/java/lang/Thread.java index 3ee03093..33fabf4 100644 --- a/libjava/java/lang/Thread.java +++ b/libjava/java/lang/Thread.java @@ -145,15 +145,23 @@ public class Thread implements Runnable daemon_flag = status; } - // TODO12: - // public ClassLoader getContextClassLoader() - // { - // } + public ClassLoader getContextClassLoader() + { + if (context_class_loader == null) + { + context_class_loader = ClassLoader.getSystemClassLoader (); + return context_class_loader; + } + + // FIXME: Add security manager stuff here. + return context_class_loader; + } - // TODO12: - // public void setContextClassLoader(ClassLoader cl) - // { - // } + public void setContextClassLoader(ClassLoader cl) + { + // FIXME: Add security manager stuff here. + context_class_loader = cl; + } public final void setName (String n) { @@ -227,13 +235,14 @@ public class Thread implements Runnable interrupt_flag = false; alive_flag = false; startable_flag = true; - + if (current != null) { daemon_flag = current.isDaemon(); int gmax = group.getMaxPriority(); int pri = current.getPriority(); priority = (gmax < pri ? gmax : pri); + context_class_loader = current.context_class_loader; } else { @@ -277,7 +286,7 @@ public class Thread implements Runnable public String toString () { return "Thread[" + name + "," + priority + "," + - (group == null ? "" : group.getName()) + "]"; + (group == null ? "" : group.getName()) + "]"; } public static native void yield (); @@ -291,6 +300,7 @@ public class Thread implements Runnable boolean interrupt_flag; private boolean alive_flag; private boolean startable_flag; + private ClassLoader context_class_loader; // Our native data. private Object data; diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index e3d4785..2eec179f 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -72,7 +72,7 @@ static _Jv_Utf8Const *finit_leg_name = _Jv_makeUtf8Const ("$finit$", 7); jclass -java::lang::Class::forName (jstring className) +java::lang::Class::forName (jstring className, java::lang::ClassLoader *loader) { if (! className) JvThrow (new java::lang::NullPointerException); @@ -85,10 +85,10 @@ java::lang::Class::forName (jstring className) // IllegalArgumentException on failure. _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length); - // FIXME: should use class loader from calling method. + // FIXME: should use bootstrap class loader if loader is null. jclass klass = (buffer[0] == '[' - ? _Jv_FindClassFromSignature (name->data, NULL) - : _Jv_FindClass (name, NULL)); + ? _Jv_FindClassFromSignature (name->data, loader) + : _Jv_FindClass (name, loader)); if (klass) _Jv_InitClass (klass); @@ -98,6 +98,13 @@ java::lang::Class::forName (jstring className) return klass; } +jclass +java::lang::Class::forName (jstring className) +{ + // FIXME: should use class loader from calling method. + return forName (className, NULL); +} + java::lang::reflect::Constructor * java::lang::Class::getConstructor (JArray *param_types) { @@ -608,7 +615,7 @@ java::lang::Class::getMethods (void) return result; } -jboolean +inline jboolean java::lang::Class::isAssignableFrom (jclass klass) { // Arguments may not have been initialized, given ".class" syntax. @@ -899,7 +906,7 @@ _Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, int method_idx) return cldt->cls.itable[idx]; } -inline jboolean +jboolean _Jv_IsAssignableFrom (jclass target, jclass source) { if (target == &ObjectClass diff --git a/libjava/java/net/URLClassLoader.java b/libjava/java/net/URLClassLoader.java index 441b7ca..eeec882 100644 --- a/libjava/java/net/URLClassLoader.java +++ b/libjava/java/net/URLClassLoader.java @@ -10,6 +10,7 @@ package java.net; import java.io.*; import java.util.jar.*; +import java.util.Enumeration; import java.util.Vector; public class URLClassLoader extends ClassLoader @@ -42,6 +43,56 @@ public class URLClassLoader extends ClassLoader this (urls, parent, null); } + // A File URL may actually be a Jar URL. Convert if possible. + private URL jarFileize (URL url) + { + if (! url.getProtocol ().equals ("jar")) + { + String f = url.getFile (); + + // If it ends with '/' we'll take it for a directory, + // otherwise it's a jar file. This is how JDK 1.2 defines + // it, so we will not try to be smart here. + if (f.charAt (f.length ()-1) != '/') + { + try + { + url = new URL ("jar", "", -1, (url.toExternalForm ())+"!/", + getHandler0 ("jar")); + } + catch (MalformedURLException x) + { + /* ignore */ + } + } + } + return url; + } + + protected void addURL (URL url) + { + JarURLConnection conn = null; + + // Convert a Jar File URL into Jar URL if possible. + url = jarFileize (url); + + path.addElement (url); + + if (url.getProtocol ().equals ("jar")) + { + try + { + conn = (JarURLConnection) url.openConnection (); + } + catch (java.io.IOException x) + { + /* ignore */ + } + } + + info.addElement (conn); + } + public URLClassLoader (URL[] urls, ClassLoader parent, URLStreamHandlerFactory fac) { @@ -61,31 +112,10 @@ public class URLClassLoader extends ClassLoader for (int i = 0; i < urls.length; i++) { - URL u = urls[i]; + // Convert a Jar File URL into a Jar URL is possible. + URL u = jarFileize(urls[i]); - // If it is a jar url, then we'll search it as is. - if (! u.getProtocol ().equals ("jar")) - { - String f = u.getFile (); - - // If it ends with '/' we'll take it for a directory, - // otherwise it's a jar file. This is how JDK 1.2 defines - // it, so we will not try to be smart here. - if (f.charAt (f.length ()-1) != '/') - { - try - { - u = new URL ("jar", "", -1, (u.toExternalForm ())+"!/", - getHandler0 ("jar")); - } - catch (MalformedURLException x) - { - /* ignore */ - } - } - } - - path.insertElementAt (u, i); + path.addElement (u); if (u.getProtocol ().equals ("jar")) { @@ -98,75 +128,83 @@ public class URLClassLoader extends ClassLoader { /* ignore */ } - info.insertElementAt (conn, i); + info.addElement (conn); } else { - info.insertElementAt (null, i); + info.addElement (null); } } } + + public URL[] getURLs () + { + URL[] urls = new URL[path.size()]; + path.copyInto (urls); + return urls; + } - public URL getResource (String name) + public Enumeration findResources (String name) { + Vector results = new Vector (); + for (int i = 0; i < path.size(); i++) { - URL u = (URL)path.elementAt (i); - + URL u = (URL)path.elementAt (i); + try { JarURLConnection conn = (JarURLConnection) info.elementAt (i); - + if (conn != null) { if (conn.getJarFile().getJarEntry (name) != null) - return new URL(u, name, getHandler0 (u.getProtocol())); + results.addElement (new URL(u, name, getHandler0 (u.getProtocol()))); } else { URL p = new URL (u, name, getHandler0 (u.getProtocol())); - + InputStream is = p.openStream(); if (is != null) { is.close(); - return p; + results.addElement (p); } } - + // if we get an exception ... try the next path element } catch (IOException x) { continue; } } - - return null; + + return results.elements (); } - /** IN jdk 1.2 this method is not overridden, but we gain performance - by doing so. - */ - - public InputStream getResourceAsStream (String name) + public URL findResource (String name) { for (int i = 0; i < path.size(); i++) { - URL u = (URL)path.elementAt (i); + URL u = (URL)path.elementAt (i); try { JarURLConnection conn = (JarURLConnection) info.elementAt (i); - + if (conn != null) { - JarFile file = conn.getJarFile (); - JarEntry ent = file.getJarEntry (name); - if (ent != null) - return file.getInputStream(ent); + if (conn.getJarFile().getJarEntry (name) != null) + return new URL(u, name, getHandler0 (u.getProtocol())); } else { - InputStream is = new URL(u, name, getHandler0 (u.getProtocol())).openStream(); + URL p = new URL (u, name, getHandler0 (u.getProtocol())); + + InputStream is = p.openStream(); if (is != null) - return is; + { + is.close(); + return p; + } } // if we get an exception ... try the next path element diff --git a/libjava/prims.cc b/libjava/prims.cc index 22fa4b6..b6ac7f8 100644 --- a/libjava/prims.cc +++ b/libjava/prims.cc @@ -67,9 +67,6 @@ details. */ #include #endif -// We use placement new. -#include - // We allocate a single OutOfMemoryError exception which we keep // around for use if we run out of memory. static java::lang::OutOfMemoryError *no_memory; @@ -414,9 +411,8 @@ _Jv_NewObjectArray (jsize count, jclass elementClass, jobject init) obj = (jobjectArray) _Jv_AllocArray (size, klass); if (__builtin_expect (! obj, false)) JvThrow (no_memory); - // Use placement new to initialize length field. - new (obj) __JArray (count); - jobject *ptr = elements(obj); + obj->length = count; + jobject *ptr = elements (obj); // We know the allocator returns zeroed memory. So don't bother // zeroing it again. if (init) @@ -450,8 +446,7 @@ _Jv_NewPrimArray (jclass eltype, jint count) __JArray *arr = (__JArray*) _Jv_AllocObj (size + elsize * count, klass); if (__builtin_expect (! arr, false)) JvThrow (no_memory); - // Use placement new to initialize length field. - new (arr) __JArray (count); + arr->length = count; // Note that we assume we are given zeroed memory by the allocator. return arr; -- cgit v1.1