diff options
Diffstat (limited to 'libjava/java/lang')
-rw-r--r-- | libjava/java/lang/Class.h | 7 | ||||
-rw-r--r-- | libjava/java/lang/Class.java | 58 | ||||
-rw-r--r-- | libjava/java/lang/ClassLoader.java | 210 | ||||
-rw-r--r-- | libjava/java/lang/Package.java | 287 | ||||
-rw-r--r-- | libjava/java/lang/natClass.cc | 19 | ||||
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 26 |
6 files changed, 561 insertions, 46 deletions
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index 9736b78..a0cd730 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -19,6 +19,7 @@ details. */ #include <java/lang/String.h> #include <java/net/URL.h> #include <java/lang/reflect/Modifier.h> +#include <java/security/ProtectionDomain.h> // We declare these here to avoid including gcj/cni.h. extern "C" void _Jv_InitClass (jclass klass); @@ -105,7 +106,8 @@ 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, jboolean initialize, + java::lang::ClassLoader *loader); static jclass forName (jstring className); JArray<jclass> *getClasses (void); @@ -135,6 +137,7 @@ private: jint offset); java::lang::reflect::Field *getPrivateField (jstring); java::lang::reflect::Method *getPrivateMethod (jstring, JArray<jclass> *); + java::security::ProtectionDomain *getProtectionDomain0 (); public: JArray<java::lang::reflect::Field *> *getFields (void); @@ -380,6 +383,8 @@ private: _Jv_IDispatchTable *idt; // Pointer to the class that represents an array of this class. jclass arrayclass; + // Security Domain to which this class belongs (or null). + java::security::ProtectionDomain *protectionDomain; }; #endif /* __JAVA_LANG_CLASS_H__ */ diff --git a/libjava/java/lang/Class.java b/libjava/java/lang/Class.java index 0f081eb..549eaec 100644 --- a/libjava/java/lang/Class.java +++ b/libjava/java/lang/Class.java @@ -12,6 +12,7 @@ package java.lang; import java.io.Serializable; import java.io.InputStream; import java.lang.reflect.*; +import java.security.*; /** * @author Tom Tromey <tromey@cygnus.com> @@ -30,7 +31,9 @@ public final class Class implements Serializable { public static native Class forName (String className) throws ClassNotFoundException; - public static native Class forName (String className, ClassLoader loader) + /** @since 1.2 */ + public static native Class forName (String className, boolean initialize, + ClassLoader loader) throws ClassNotFoundException; public native Class[] getClasses (); public native ClassLoader getClassLoader (); @@ -88,6 +91,30 @@ public final class Class implements Serializable private native Field[] _getFields (Field[] result, int offset); public native Field[] getFields () throws SecurityException; + /** + * Returns the <code>Package</code> in which this class is defined + * Returns null when this information is not available from the + * classloader of this class or when the classloader of this class + * is null. + * + * @since 1.2 + */ + public Package getPackage() + { + ClassLoader cl = getClassLoader(); + if (cl != null) + { + String name = getName(); + String pkg = ""; + int idx = name.lastIndexOf('.'); + if (idx >= 0) + pkg = name.substring(0, idx); + return cl.getPackage(pkg); + } + else + return null; + } + public native Class[] getInterfaces (); private final native void getSignature (StringBuffer buffer); @@ -154,6 +181,35 @@ public final class Class implements Serializable public native Object newInstance () throws InstantiationException, IllegalAccessException; + // We need a native method to retrieve the protection domain, because we + // can't add fields to java.lang.Class that are accessible from Java. + private native ProtectionDomain getProtectionDomain0(); + + /** + * Returns the protection domain of this class. If the classloader + * did not record the protection domain when creating this class + * the unknown protection domain is returned which has a <code>null</code> + * code source and all permissions. + * + * @exception SecurityException if a security manager exists and the caller + * does not have <code>RuntimePermission("getProtectionDomain")</code>. + * + * @since 1.2 + */ + public ProtectionDomain getProtectionDomain() + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(ClassLoader.protectionDomainPermission); + + ProtectionDomain protectionDomain = getProtectionDomain0(); + + if (protectionDomain == null) + return ClassLoader.unknownProtectionDomain; + else + return protectionDomain; + } + public String toString () { if (isPrimitive ()) 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 diff --git a/libjava/java/lang/Package.java b/libjava/java/lang/Package.java new file mode 100644 index 0000000..26bcb98 --- /dev/null +++ b/libjava/java/lang/Package.java @@ -0,0 +1,287 @@ +/* java.lang.Package - Everything you ever wanted to know about a package. + Copyright (C) 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + +package java.lang; + +import java.net.URL; +import java.util.NoSuchElementException; +import java.util.StringTokenizer; + +/** + * Everything you ever wanted to know about a package. This class makes it + * possible to attach specification and implementation information to a + * package as explained in the + * <a href="http://java.sun.com/products/jdk/1.3/docs/guide/versioning/spec/VersioningSpecification.html#PackageVersionSpecification">Package Versioning Specification</a> + * section of the + * <a href="http://java.sun.com/products/jdk/1.3/docs/guide/versioning/spec/VersioningSpecification.html">Product Versioning Specification</a>. + * It also allows packages to be sealed with respect to the originating URL. + * <p> + * The most usefull method is the <code>isCompatibleWith()</code> method that + * compares a desired version of a specification with the version of the + * specification as implemented by a package. A package is considered + * compatible with another version if the version of the specification is + * equal or higher then the requested version. Version numbers are represented + * as strings of positive numbers seperated by dots (e.g. "1.2.0"). + * The first number is called the major number, the second the minor, + * the third the micro, etc. A version is considered higher then another + * version if it has a bigger major number then the another version or when + * the major numbers of the versions are equal if it has a bigger minor number + * then the other version, etc. (If a version has no minor, micro, etc numbers + * then they are considered the be 0.) + * + * @since 1.2 + * @author Mark Wielaard (mark@klomp.org) + */ +public class Package +{ + /** The name of the Package */ + final private String name; + + /** The name if the implementation */ + final private String implTitle; + /** The vendor that wrote this implementation */ + final private String implVendor; + /** The version of this implementation */ + final private String implVersion; + + /** The name of the specification */ + final private String specTitle; + /** The name of the specification designer */ + final private String specVendor; + /** The version of this specification */ + final private String specVersion; + + /** If sealed the origin of the package classes, otherwise null */ + final private URL sealed; + + /** + * A package local constructor for the Package class. + * All parameters except the <code>name</code> of the package may be + * <code>null</code>. + * There are no public constructors defined for Package this is a package + * local constructor that is used by java.lang.Classloader.definePackage(). + * + * @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 + */ + Package(String name, + String specTitle, String specVendor, String specVersion, + String implTitle, String implVendor, String implVersion, URL sealed) + { + if (name == null) + throw new IllegalArgumentException("null Package name"); + + this.name = name; + + this.implTitle = implTitle; + this.implVendor = implVendor; + this.implVersion = implVersion; + + this.specTitle = specTitle; + this.specVendor = specVendor; + this.specVersion = specVersion; + + this.sealed = sealed; + } + + /** + * Returns the Package name. + */ + public String getName() + { + return name; + } + + /** + * Returns the name of the implementation or null if unknown. + */ + public String getImplementationTitle() + { + return implTitle; + } + + /** + * Returns the vendor that wrote this implementation or null if unknown. + */ + public String getImplementationVendor() + { + return implVendor; + } + + /** + * Returns the version of this implementation or null if unknown. + */ + public String getImplementationVersion() + { + return implVersion; + } + + /** + * Returns the name of the specification or null if unknown. + */ + public String getSpecificationTitle() + { + return specTitle; + } + + /** + * Returns the name of the specification designer or null if unknown. + */ + public String getSpecificationVendor() + { + return specVendor; + } + + /** + * Returns the version of the specification or null if unknown. + */ + public String getSpecificationVersion() + { + return specVersion; + } + + /** + * Returns true if this Package is sealed. + */ + public boolean isSealed() + { + return (sealed != null); + } + + /** + * Returns true if this Package is sealed and the origin of the classes is + * the given URL. + * + * @param url + */ + public boolean isSealed(URL url) + { + return url.equals(sealed); + } + + /** + * Checks if the version of the specification is higher or at least as high + * as the desired version. + * @param version the (minimal) desired version of the specification + * @exception NumberFormatException when either version or the + * specification version is not a correctly formatted version number + * @exception NullPointerException if the supplied version or the + * Package specification version is null. + */ + public boolean isCompatibleWith(String version) throws NumberFormatException + { + StringTokenizer versionTokens = new StringTokenizer(version, "."); + StringTokenizer specTokens = new StringTokenizer(specVersion, "."); + try + { + while (versionTokens.hasMoreElements()) + { + int vers = Integer.parseInt(versionTokens.nextToken()); + int spec = Integer.parseInt(specTokens.nextToken()); + if (spec < vers) + return false; + else if (spec > vers) + return true; + // They must be equal, next Token please! + } + } + catch (NoSuchElementException e) + { + // this must have been thrown by spec.netToken() so return false + return false; + } + + // They must have been exactly the same version. + // Or the specVersion has more subversions. That is also good. + return true; + } + + /** + * Returns the named package if it is known by the callers class loader. + * It may return null if the package is unknown, when there is no + * information on that particular package available or when the callers + * classloader is null. + * @param name the name of the desired package + */ + public static Package getPackage(String name) + { + // Get the caller's classloader + SecurityManager sm = System.getSecurityManager(); + Class c = sm.getClassContext()[1]; + ClassLoader cl = c.getClassLoader(); + + if (cl != null) + return cl.getPackage(name); + else + return null; + } + + /** + * Returns all the packages that are known to the callers class loader. + * It may return an empty array if the classloader of the caller is null. + */ + public static Package[] getPackages() + { + // Get the caller's classloader + SecurityManager sm = System.getSecurityManager(); + Class c = sm.getClassContext()[1]; + ClassLoader cl = c.getClassLoader(); + + if (cl != null) + return cl.getPackages(); + else + return new Package[0]; + } + + /** + * Returns the hashCode of the name of this package. + */ + public int hashCode() + { + return name.hashCode(); + } + + /** + * Returns a string representation of this package name, specification, + * implementation and class origin if sealed. + */ + public String toString() + { + return "package: " + name + + " spec: " + specTitle + + " version: " + specVersion + + " vendor: " + specVendor + + " implementation: " + implTitle + + " version: " + implVersion + + " vendor: " + implVendor + " sealed: " + sealed; + } +} diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index 25e92c7..d7c2a54 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -72,7 +72,8 @@ static _Jv_Utf8Const *finit_leg_name = _Jv_makeUtf8Const ("$finit$", 7); jclass -java::lang::Class::forName (jstring className, java::lang::ClassLoader *loader) +java::lang::Class::forName (jstring className, jboolean initialize, + java::lang::ClassLoader *loader) { if (! className) throw new java::lang::NullPointerException; @@ -90,11 +91,12 @@ java::lang::Class::forName (jstring className, java::lang::ClassLoader *loader) ? _Jv_FindClassFromSignature (name->data, loader) : _Jv_FindClass (name, loader)); - if (klass) - _Jv_InitClass (klass); - else + if (klass == NULL) throw new java::lang::ClassNotFoundException (className); + if (initialize) + _Jv_InitClass (klass); + return klass; } @@ -102,7 +104,7 @@ jclass java::lang::Class::forName (jstring className) { // FIXME: should use class loader from calling method. - return forName (className, NULL); + return forName (className, true, NULL); } java::lang::reflect::Constructor * @@ -1415,3 +1417,10 @@ java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types) } throw new java::lang::NoSuchMethodException; } + +// Private accessor method for Java code to retrieve the protection domain. +java::security::ProtectionDomain * +java::lang::Class::getProtectionDomain0 () +{ + return protectionDomain; +} diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index 84fe0c4..6b7f5fa 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -48,20 +48,12 @@ details. */ /////////// java.lang.ClassLoader native methods //////////// -java::lang::ClassLoader * -java::lang::ClassLoader::getSystemClassLoader (void) -{ - JvSynchronize sync (&ClassLoaderClass); - if (! system) - system = gnu::gcj::runtime::VMClassLoader::getVMClassLoader (); - return system; -} - java::lang::Class * java::lang::ClassLoader::defineClass0 (jstring name, jbyteArray data, jint offset, - jint length) + jint length, + java::security::ProtectionDomain *pd) { #ifdef INTERPRETER jclass klass; @@ -109,6 +101,8 @@ java::lang::ClassLoader::defineClass0 (jstring name, throw ex; } + + klass->protectionDomain = pd; // if everything proceeded sucessfully, we're loaded. JvAssert (klass->state == JV_STATE_LOADED); @@ -180,10 +174,10 @@ java::lang::ClassLoader::markClassErrorState0 (java::lang::Class *klass) } -/** this is the only native method in VMClassLoader, so - we define it here. */ +// This is the findClass() implementation for the System classloader. It is +// the only native method in VMClassLoader, so we define it here. jclass -gnu::gcj::runtime::VMClassLoader::findSystemClass (jstring name) +gnu::gcj::runtime::VMClassLoader::findClass (jstring name) { _Jv_Utf8Const *name_u = _Jv_makeUtf8Const (name); jclass klass = _Jv_FindClassInCache (name_u, 0); @@ -213,6 +207,12 @@ gnu::gcj::runtime::VMClassLoader::findSystemClass (jstring name) } } + // Now try loading using the interpreter. + if (! klass) + { + klass = java::net::URLClassLoader::findClass (name); + } + return klass; } |