1 /* VMClassLoader.java -- Reference implementation of native interface
2 required by ClassLoader
3 Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
41 import gnu.java.util.EmptyEnumeration;
42 import java.lang.reflect.Constructor;
44 import java.io.IOException;
46 import java.net.URLClassLoader;
47 import java.security.AllPermission;
48 import java.security.Permission;
49 import java.security.Permissions;
50 import java.security.ProtectionDomain;
51 import java.util.ArrayList;
52 import java.util.Enumeration;
53 import java.util.HashMap;
55 import java.util.StringTokenizer;
56 import gnu.gcj.runtime.BootClassLoader;
59 * java.lang.VMClassLoader is a package-private helper for VMs to implement
60 * on behalf of java.lang.ClassLoader.
63 * @author Mark Wielaard <mark@klomp.org>
64 * @author Eric Blake <ebb9@email.byu.edu>
66 final class VMClassLoader
68 // Protection Domain definitions
69 // FIXME: should there be a special protection domain used for native code?
71 // The permission required to check what a classes protection domain is.
72 static final Permission protectionDomainPermission
73 = new RuntimePermission("getProtectionDomain");
74 // The protection domain returned if we cannot determine it.
75 static ProtectionDomain unknownProtectionDomain;
79 Permissions permissions = new Permissions();
80 permissions.add(new AllPermission());
81 unknownProtectionDomain = new ProtectionDomain(null, permissions);
84 static final HashMap definedPackages = new HashMap();
86 // This is a helper for handling java.endorsed.dirs. It is null
87 // until we've initialized the system, at which point it is created.
88 static BootClassLoader bootLoader;
91 * Helper to define a class using a string of bytes. This assumes that
92 * the security checks have already been performed, if necessary.
94 * <strong>For backward compatibility, this just ignores the protection
95 * domain; that is the wrong behavior, and you should directly implement
96 * this method natively if you can.</strong>
98 * @param name the name to give the class, or null if unknown
99 * @param data the data representing the classfile, in classfile format
100 * @param offset the offset into the data where the classfile starts
101 * @param len the length of the classfile data in the array
102 * @param pd the protection domain
103 * @return the class that was defined
104 * @throws ClassFormatError if data is not in proper classfile format
106 static final native Class defineClass(ClassLoader cl, String name,
107 byte[] data, int offset, int len,
109 throws ClassFormatError;
112 * Helper to resolve all references to other classes from this class.
114 * @param c the class to resolve
116 static final native void resolveClass(Class clazz);
118 static final void transformException(Class clazz, Throwable x)
121 if (x instanceof LinkageError)
122 e = (LinkageError) x;
123 else if (x instanceof ClassNotFoundException)
125 e = new NoClassDefFoundError("while resolving class: "
131 e = new LinkageError ("unexpected exception during linking: "
139 * Helper to load a class from the bootstrap class loader.
141 * @param name the class name to load
142 * @param resolve whether to resolve it
143 * @return the class, loaded by the bootstrap classloader or null
144 * if the class wasn't found. Returning null is equivalent to throwing
145 * a ClassNotFoundException (but a possible performance optimization).
147 static final native Class loadClass(String name, boolean resolve)
148 throws ClassNotFoundException;
151 * Helper to load a resource from the bootstrap class loader.
153 * In libgcj, this does nothing, as the default system loader knows
154 * how to find resources that have been linked in.
156 * @param name the resource to find
157 * @return the URL to the resource
159 static URL getResource(String name)
161 if (bootLoader != null)
162 return bootLoader.bootGetResource(name);
167 * Helper to get a list of resources from the bootstrap class loader.
169 * In libgcj, this does nothing, as the default system loader knows
170 * how to find resources that have been linked in.
172 * @param name the resource to find
173 * @return an enumeration of resources
174 * @throws IOException if one occurs
176 static Enumeration getResources(String name) throws IOException
178 if (bootLoader != null)
179 return bootLoader.bootGetResources(name);
180 return EmptyEnumeration.getInstance();
184 * Helper to get a package from the bootstrap class loader. The default
185 * implementation of returning null may be adequate, or you may decide
186 * that this needs some native help.
188 * @param name the name to find
189 * @return the named package, if it exists
191 static synchronized Package getPackage(String name)
193 return (Package) definedPackages.get(name);
197 * Helper to get all packages from the bootstrap class loader. The default
198 * implementation of returning an empty array may be adequate, or you may
199 * decide that this needs some native help.
201 * @return all named packages, if any exist
203 static synchronized Package[] getPackages()
205 Package[] packages = new Package[definedPackages.size()];
206 return (Package[]) definedPackages.values().toArray(packages);
209 // Define a package for something loaded natively.
210 static synchronized void definePackageForNative(String className)
212 int lastDot = className.lastIndexOf('.');
215 String packageName = className.substring(0, lastDot);
216 if (getPackage(packageName) == null)
218 // FIXME: this assumes we're defining the core, which
219 // isn't necessarily so. We could detect this and set up
220 // appropriately. We could also look at a manifest file
221 // compiled into the .so.
222 Package p = new Package(packageName,
223 "Java Platform API Specification",
224 "GNU", "1.4", "gcj", "GNU",
225 null, // FIXME: gcj version.
227 definedPackages.put(packageName, p);
233 * Helper for java.lang.Integer, Byte, etc to get the TYPE class
234 * at initialization time. The type code is one of the chars that
235 * represents the primitive type as in JNI.
238 * <li>'Z' - boolean</li>
239 * <li>'B' - byte</li>
240 * <li>'C' - char</li>
241 * <li>'D' - double</li>
242 * <li>'F' - float</li>
244 * <li>'J' - long</li>
245 * <li>'S' - short</li>
246 * <li>'V' - void</li>
249 * @param type the primitive type
250 * @return a "bogus" class representing the primitive type
252 static final native Class getPrimitiveClass(char type);
255 * The system default for assertion status. This is used for all system
256 * classes (those with a null ClassLoader), as well as the initial value for
257 * every ClassLoader's default assertion status.
259 * XXX - Not implemented yet; this requires native help.
261 * @return the system-wide default assertion status
263 static final boolean defaultAssertionStatus()
269 * The system default for package assertion status. This is used for all
270 * ClassLoader's packageAssertionStatus defaults. It must be a map of
271 * package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package
272 * represented as a null key.
274 * XXX - Not implemented yet; this requires native help.
276 * @return a (read-only) map for the default packageAssertionStatus
278 static final Map packageAssertionStatus()
280 return new HashMap();
284 * The system default for class assertion status. This is used for all
285 * ClassLoader's classAssertionStatus defaults. It must be a map of
286 * class names to Boolean.TRUE or Boolean.FALSE
288 * XXX - Not implemented yet; this requires native help.
290 * @return a (read-only) map for the default classAssertionStatus
292 static final Map classAssertionStatus()
294 return new HashMap();
297 static native ClassLoader getSystemClassLoaderInternal();
299 static native void initBootLoader(String libdir);
301 static ClassLoader getSystemClassLoader()
303 // This method is called as the initialization of systemClassLoader,
304 // so if there is a null value, this is the first call and we must check
305 // for java.system.class.loader.
306 String loader = System.getProperty("java.system.class.loader");
307 ClassLoader default_sys = getSystemClassLoaderInternal();
312 Class load_class = Class.forName(loader, true, default_sys);
314 = load_class.getConstructor(new Class[] { ClassLoader.class });
316 = (ClassLoader) c.newInstance(new Object[] { default_sys });
320 throw new Error("Failed to load requested system classloader "