diff options
author | Bryce McKinlay <bryce@gcc.gnu.org> | 2001-04-25 16:45:15 +0100 |
---|---|---|
committer | Bryce McKinlay <bryce@gcc.gnu.org> | 2001-04-25 16:45:15 +0100 |
commit | 28f7d9d05ad70afad626d4bc54c633d31eb7430a (patch) | |
tree | e9e280e2d95c4a16d714ee23d9f0345ef0401260 /libjava/java/lang/ClassLoader.java | |
parent | 744cfa53c3f98a0cb0d952a176c8bc03aee1abba (diff) | |
download | gcc-28f7d9d05ad70afad626d4bc54c633d31eb7430a.zip gcc-28f7d9d05ad70afad626d4bc54c633d31eb7430a.tar.gz gcc-28f7d9d05ad70afad626d4bc54c633d31eb7430a.tar.bz2 |
decl.c (init_decl_processing): Add new class "protectionDomain" field.
gcc/java:
2001-04-25 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
* decl.c (init_decl_processing): Add new class "protectionDomain"
field.
* class.c (make_class_data): Set initial value for "protectionDomain".
libjava:
2001-04-25 Bryce McKinlay <bryce@albatross.co.nz>
java.security merge and ClassLoader compliance fixes.
* java/lang/Class.h (Class): Include ProtectionDomain.h.
New protectionDomain field.
(forName): Add initialize parameter. Fixes declaration to comply with
JDK spec.
* java/lang/natClass.cc (forName): Correct declaration of the three-arg
variant. Honour "initialize" flag.
(getProtectionDomain0): New method.
* java/lang/Class.java: Fix forName() declaration.
(getPackage): New method based on Classpath implementation.
(getProtectionDomain0): New native method decl.
(getProtectionDomain): New method.
* java/lang/ClassLoader.java (getParent): Now final.
(definedPackages): New field.
(getPackage): New.
(defineClass): New variant with protectionDomain argument.
(definePackage): New.
(getPackages): New.
(findSystemClass): Now final.
(getSystemResourceAsStream): Remove redundant "final" modifier.
(getSystemResource): Remove redundant "final" modifier.
(getResources): Now final.
(protectionDomainPermission): New static field.
(unknownProtectionDomain): Ditto.
(defaultProtectionDomain): Ditto.
(getSystemClassLoader): Now non-native.
* java/util/ResourceBundle.java (tryGetSomeBundle): Use the correct
arguments for Class.forName().
* java/lang/Package.java: New file.
* gnu/gcj/runtime/VMClassLoader.java (getVMClassLoader): Removed.
(instance): Static initialize singleton.
(findClass): Override this, not findSystemClass.
* java/lang/natClassLoader.cc (defineClass0): Set class's
protectionDomain field as specified.
(getSystemClassLoader): Removed.
(findClass): Renamed from findSystemClass. Call the interpreter via
URLClassLoader.findClass if loading class via dlopen fails.
* java/security/*.java: java.security import/merge with Classpath.
* java/security/acl/*.java: Likewise.
* java/security/interfaces/*.java: Likewise.
* java/security/spec/*.java: Likewise.
* java/net/NetPermission.java: Likewise.
* java/net/SocketPermission.java: Likewise.
* gnu/java/security/provider/DefaultPolicy.java: Likewise.
* Makefile.am: Add new classes.
* Makefile.in: Rebuilt.
* gcj/javaprims.h: CNI namespace rebuild.
From-SVN: r41543
Diffstat (limited to 'libjava/java/lang/ClassLoader.java')
-rw-r--r-- | libjava/java/lang/ClassLoader.java | 210 |
1 files changed, 184 insertions, 26 deletions
diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java index 402e812..56d73e6 100644 --- a/libjava/java/lang/ClassLoader.java +++ b/libjava/java/lang/ClassLoader.java @@ -1,6 +1,6 @@ // ClassLoader.java - Define policies for loading Java classes. -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation This file is part of libgcj. @@ -14,7 +14,14 @@ import java.io.InputStream; import java.io.IOException; import java.net.URL; import java.net.URLConnection; +import java.security.AllPermission; +import java.security.CodeSource; +import java.security.Permission; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; import java.util.Enumeration; +import java.util.HashMap; import java.util.Stack; /** @@ -25,18 +32,24 @@ import java.util.Stack; * @author Kresten Krab Thorup */ -public abstract class ClassLoader { - +public abstract class ClassLoader +{ static private ClassLoader system; private ClassLoader parent; + private HashMap definedPackages = new HashMap(); - public ClassLoader getParent () + public final ClassLoader getParent () { /* FIXME: security */ return parent; } - - public static native ClassLoader getSystemClassLoader (); + + public static ClassLoader getSystemClassLoader () + { + if (system == null) + system = gnu.gcj.runtime.VMClassLoader.instance; + return system; + } /** * Creates a <code>ClassLoader</code> with no parent. @@ -55,6 +68,7 @@ public abstract class ClassLoader { * <code>checkCreateClassLoader</code> on the current * security manager. * @exception java.lang.SecurityException if not allowed + * @since 1.2 */ protected ClassLoader(ClassLoader parent) { @@ -71,11 +85,15 @@ public abstract class ClassLoader { * @see ClassLoader#loadClass(String,boolean) * @exception java.lang.ClassNotFoundException */ - public Class loadClass(String name) - throws java.lang.ClassNotFoundException, java.lang.LinkageError + public Class loadClass(String name) + throws java.lang.ClassNotFoundException { return loadClass (name, false); } + + /* findClass implementation for the system classloader. + native Class systemFindClass(String name) + throws java.lang.ClassNotFoundException; /** * Loads the class by the given name. The default implementation @@ -96,7 +114,7 @@ public abstract class ClassLoader { * @deprecated */ protected Class loadClass(String name, boolean link) - throws java.lang.ClassNotFoundException, java.lang.LinkageError + throws java.lang.ClassNotFoundException { Class c = findLoadedClass (name); @@ -106,7 +124,7 @@ public abstract class ClassLoader { if (parent != null) return parent.loadClass (name, link); else - c = findSystemClass (name); + c = system.findClass (name); } catch (ClassNotFoundException ex) { /* ignore, we'll try findClass */; } @@ -130,6 +148,7 @@ public abstract class ClassLoader { * @param name Name of the class to find. * @return The class found. * @exception java.lang.ClassNotFoundException + * @since 1.2 */ protected Class findClass (String name) throws ClassNotFoundException @@ -137,6 +156,28 @@ public abstract class ClassLoader { throw new ClassNotFoundException (name); } + // Protection Domain definitions + // FIXME: should there be a special protection domain used for native code? + + // The permission required to check what a classes protection domain is. + static final Permission protectionDomainPermission + = new RuntimePermission("getProtectionDomain"); + // The protection domain returned if we cannot determine it. + static ProtectionDomain unknownProtectionDomain; + // Protection domain to use when a class is defined without one specified. + static ProtectionDomain defaultProtectionDomain; + + static + { + Permissions permissions = new Permissions(); + permissions.add(new AllPermission()); + unknownProtectionDomain = new ProtectionDomain(null, permissions); + + CodeSource cs = new CodeSource(null, null); + defaultProtectionDomain = + new ProtectionDomain(cs, Policy.getPolicy().getPermissions(cs)); + } + /** * Defines a class, given the class-data. According to the JVM, this * method should not be used; instead use the variant of this method @@ -158,9 +199,14 @@ public abstract class ClassLoader { protected final Class defineClass(byte[] data, int off, int len) throws ClassFormatError { - return defineClass (null, data, off, len); + return defineClass (null, data, off, len, defaultProtectionDomain); } + protected final Class defineClass(String name, byte[] data, int off, int len) + { + return defineClass (name, data, off, len, defaultProtectionDomain); + } + /** * Defines a class, given the class-data. This is preferable * over <code>defineClass(byte[],off,len)</code> since it is more @@ -182,6 +228,7 @@ public abstract class ClassLoader { * @param data bytes in class file format. * @param off offset to start interpreting data. * @param len length of data in class file. + * @param protectionDomain security protection domain for the class. * @return the class defined. * @exception java.lang.ClassNotFoundException * @exception java.lang.LinkageError @@ -189,7 +236,8 @@ public abstract class ClassLoader { protected final synchronized Class defineClass(String name, byte[] data, int off, - int len) + int len, + ProtectionDomain protectionDomain) throws ClassFormatError { if (data==null || data.length < off+len || off<0 || len<0) @@ -201,13 +249,16 @@ public abstract class ClassLoader { throw new java.lang.LinkageError ("class " + name + " already loaded"); + + if (protectionDomain == null) + protectionDomain = defaultProtectionDomain; try { // Since we're calling into native code here, // we better make sure that any generated // exception is to spec! - return defineClass0 (name, data, off, len); + return defineClass0 (name, data, off, len, protectionDomain); } catch (ClassFormatError x) { throw x; // rethrow @@ -229,10 +280,10 @@ public abstract class ClassLoader { private native Class defineClass0 (String name, byte[] data, int off, - int len) + int len, + ProtectionDomain protectionDomain) throws ClassFormatError; - /** * Link the given class. This will bring the class to a state where * the class initializer can be run. Linking involves the following @@ -262,13 +313,11 @@ public abstract class ClassLoader { * @exception java.lang.LinkageError */ protected final void resolveClass(Class clazz) - throws java.lang.LinkageError { resolveClass0(clazz); } static void resolveClass0(Class clazz) - throws java.lang.LinkageError { synchronized (clazz) { @@ -288,14 +337,123 @@ public abstract class ClassLoader { /** Internal method. Calls _Jv_PrepareClass and * _Jv_PrepareCompiledClass. This is only called from resolveClass. */ - private static native void linkClass0(Class clazz) - throws java.lang.LinkageError; + private static native void linkClass0(Class clazz); /** Internal method. Marks the given clazz to be in an erroneous * state, and calls notifyAll() on the class object. This should only * be called when the caller has the lock on the class object. */ private static native void markClassErrorState0(Class clazz); + /** + * Defines a new package and creates a Package object. + * The package should be defined before any class in the package is + * defined with <code>defineClass()</code>. The package should not yet + * be defined before in this classloader or in one of its parents (which + * means that <code>getPackage()</code> should return <code>null</code>). + * All parameters except the <code>name</code> of the package may be + * <code>null</code>. + * <p> + * Subclasses should call this method from their <code>findClass()</code> + * implementation before calling <code>defineClass()</code> on a Class + * in a not yet defined Package (which can be checked by calling + * <code>getPackage()</code>). + * + * @param name The name of the Package + * @param specTitle The name of the specification + * @param specVendor The name of the specification designer + * @param specVersion The version of this specification + * @param implTitle The name of the implementation + * @param implVendor The vendor that wrote this implementation + * @param implVersion The version of this implementation + * @param sealed If sealed the origin of the package classes + * @return the Package object for the specified package + * + * @exception IllegalArgumentException if the package name is null or if + * it was already defined by this classloader or one of its parents. + * + * @see Package + * @since 1.2 + */ + protected Package definePackage(String name, + String specTitle, String specVendor, + String specVersion, String implTitle, + String implVendor, String implVersion, + URL sealed) + { + if (getPackage(name) != null) + throw new IllegalArgumentException("Package " + name + + " already defined"); + Package p = new Package(name, + specTitle, specVendor, specVersion, + implTitle, implVendor, implVersion, + sealed); + synchronized (definedPackages) + { + definedPackages.put(name, p); + } + return p; + } + + /** + * Returns the Package object for the requested package name. It returns + * null when the package is not defined by this classloader or one of its + * parents. + * + * @since 1.2 + */ + protected Package getPackage(String name) + { + Package p; + if (parent == null) + // XXX - Should we use the bootstrap classloader? + p = null; + else + p = parent.getPackage(name); + + if (p == null) + { + synchronized (definedPackages) + { + p = (Package) definedPackages.get(name); + } + } + + return p; + } + + /** + * Returns all Package objects defined by this classloader and its parents. + * + * @since 1.2 + */ + protected Package[] getPackages() + { + Package[] allPackages; + + // Get all our packages. + Package[] packages; + synchronized(definedPackages) + { + packages = new Package[definedPackages.size()]; + definedPackages.values().toArray(packages); + } + + // If we have a parent get all packages defined by our parents. + if (parent != null) + { + Package[] parentPackages = parent.getPackages(); + allPackages = new Package[parentPackages.length + packages.length]; + System.arraycopy(parentPackages, 0, allPackages, 0, + parentPackages.length); + System.arraycopy(packages, 0, allPackages, parentPackages.length, + packages.length); + } + else + // XXX - Should we use the bootstrap classloader? + allPackages = packages; + + return allPackages; + } /** * Returns a class found in a system-specific way, typically @@ -307,14 +465,14 @@ public abstract class ClassLoader { * @exception java.lang.LinkageError * @exception java.lang.ClassNotFoundException */ - protected Class findSystemClass(String name) - throws java.lang.ClassNotFoundException, java.lang.LinkageError + protected final Class findSystemClass(String name) + throws java.lang.ClassNotFoundException { return getSystemClassLoader ().loadClass (name); } /* - * Does currently nothing. + * Does currently nothing. FIXME. */ protected final void setSigners(Class claz, Object[] signers) { /* claz.setSigners (signers); */ @@ -328,13 +486,13 @@ public abstract class ClassLoader { * @param name class to find. * @return the class loaded, or null. */ - protected native Class findLoadedClass(String name); + protected final native Class findLoadedClass(String name); - public static final InputStream getSystemResourceAsStream(String name) { + public static InputStream getSystemResourceAsStream(String name) { return getSystemClassLoader().getResourceAsStream (name); } - public static final URL getSystemResource(String name) { + public static URL getSystemResource(String name) { return getSystemClassLoader().getResource (name); } @@ -397,7 +555,7 @@ public abstract class ClassLoader { return null; } - public Enumeration getResources (String name) throws IOException + public final 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 |