1 |
/* ClassLoader.java -- responsible for loading classes into the VM |
/* ClassLoader.java -- responsible for loading classes into the VM |
2 |
Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. |
Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
38 |
|
|
39 |
package java.lang; |
package java.lang; |
40 |
|
|
41 |
|
import gnu.classpath.SystemProperties; |
42 |
|
import gnu.classpath.VMStackWalker; |
43 |
import gnu.java.util.DoubleEnumeration; |
import gnu.java.util.DoubleEnumeration; |
44 |
import gnu.java.util.EmptyEnumeration; |
import gnu.java.util.EmptyEnumeration; |
45 |
|
|
152 |
*/ |
*/ |
153 |
private final boolean initialized; |
private final boolean initialized; |
154 |
|
|
155 |
/** |
static class StaticData |
|
* The default protection domain, used when defining a class with a null |
|
|
* paramter for the domain. |
|
|
*/ |
|
|
static final ProtectionDomain defaultProtectionDomain; |
|
|
static |
|
156 |
{ |
{ |
157 |
CodeSource cs = new CodeSource(null, null); |
/** |
158 |
PermissionCollection perm = Policy.getPolicy().getPermissions(cs); |
* The System Class Loader (a.k.a. Application Class Loader). The one |
159 |
defaultProtectionDomain = new ProtectionDomain(cs, perm); |
* returned by ClassLoader.getSystemClassLoader. |
160 |
|
*/ |
161 |
|
static final ClassLoader systemClassLoader = |
162 |
|
VMClassLoader.getSystemClassLoader(); |
163 |
|
static |
164 |
|
{ |
165 |
|
// Find out if we have to install a default security manager. Note that |
166 |
|
// this is done here because we potentially need the system class loader |
167 |
|
// to load the security manager and note also that we don't need the |
168 |
|
// security manager until the system class loader is created. |
169 |
|
// If the runtime chooses to use a class loader that doesn't have the |
170 |
|
// system class loader as its parent, it is responsible for setting |
171 |
|
// up a security manager before doing so. |
172 |
|
String secman = SystemProperties.getProperty("java.security.manager"); |
173 |
|
if (secman != null && SecurityManager.current == null) |
174 |
|
{ |
175 |
|
if (secman.equals("") || secman.equals("default")) |
176 |
|
{ |
177 |
|
SecurityManager.current = new SecurityManager(); |
178 |
|
} |
179 |
|
else |
180 |
|
{ |
181 |
|
try |
182 |
|
{ |
183 |
|
Class cl = Class.forName(secman, false, StaticData.systemClassLoader); |
184 |
|
SecurityManager.current = (SecurityManager)cl.newInstance(); |
185 |
|
} |
186 |
|
catch (Exception x) |
187 |
|
{ |
188 |
|
throw (InternalError) |
189 |
|
new InternalError("Unable to create SecurityManager") |
190 |
|
.initCause(x); |
191 |
|
} |
192 |
|
} |
193 |
|
} |
194 |
|
} |
195 |
|
|
196 |
|
/** |
197 |
|
* The default protection domain, used when defining a class with a null |
198 |
|
* parameter for the domain. |
199 |
|
*/ |
200 |
|
static final ProtectionDomain defaultProtectionDomain; |
201 |
|
static |
202 |
|
{ |
203 |
|
CodeSource cs = new CodeSource(null, null); |
204 |
|
PermissionCollection perm = Policy.getPolicy().getPermissions(cs); |
205 |
|
defaultProtectionDomain = new ProtectionDomain(cs, perm); |
206 |
|
} |
207 |
|
/** |
208 |
|
* The command-line state of the package assertion status overrides. This |
209 |
|
* map is never modified, so it does not need to be synchronized. |
210 |
|
*/ |
211 |
|
// Package visible for use by Class. |
212 |
|
static final Map systemPackageAssertionStatus |
213 |
|
= VMClassLoader.packageAssertionStatus(); |
214 |
|
/** |
215 |
|
* The command-line state of the class assertion status overrides. This |
216 |
|
* map is never modified, so it does not need to be synchronized. |
217 |
|
*/ |
218 |
|
// Package visible for use by Class. |
219 |
|
static final Map systemClassAssertionStatus |
220 |
|
= VMClassLoader.classAssertionStatus(); |
221 |
} |
} |
222 |
|
|
223 |
/** |
/** |
228 |
boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus(); |
boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus(); |
229 |
|
|
230 |
/** |
/** |
|
* The command-line state of the package assertion status overrides. This |
|
|
* map is never modified, so it does not need to be synchronized. |
|
|
*/ |
|
|
// Package visible for use by Class. |
|
|
static final Map systemPackageAssertionStatus |
|
|
= VMClassLoader.packageAssertionStatus(); |
|
|
|
|
|
/** |
|
231 |
* The map of package assertion status overrides, or null if no package |
* The map of package assertion status overrides, or null if no package |
232 |
* overrides have been specified yet. The values of the map should be |
* overrides have been specified yet. The values of the map should be |
233 |
* Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented |
* Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented |
237 |
Map<String, Boolean> packageAssertionStatus; |
Map<String, Boolean> packageAssertionStatus; |
238 |
|
|
239 |
/** |
/** |
|
* The command-line state of the class assertion status overrides. This |
|
|
* map is never modified, so it does not need to be synchronized. |
|
|
*/ |
|
|
// Package visible for use by Class. |
|
|
static final Map<String, Boolean> systemClassAssertionStatus |
|
|
= VMClassLoader.classAssertionStatus(); |
|
|
|
|
|
/** |
|
240 |
* The map of class assertion status overrides, or null if no class |
* The map of class assertion status overrides, or null if no class |
241 |
* overrides have been specified yet. The values of the map should be |
* overrides have been specified yet. The values of the map should be |
242 |
* Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this |
* Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this |
253 |
*/ |
*/ |
254 |
protected ClassLoader() throws SecurityException |
protected ClassLoader() throws SecurityException |
255 |
{ |
{ |
256 |
this(System.systemClassLoader); |
this(StaticData.systemClassLoader); |
257 |
} |
} |
258 |
|
|
259 |
/** |
/** |
273 |
protected ClassLoader(ClassLoader parent) |
protected ClassLoader(ClassLoader parent) |
274 |
{ |
{ |
275 |
// May we create a new classloader? |
// May we create a new classloader? |
276 |
SecurityManager sm = System.getSecurityManager(); |
SecurityManager sm = SecurityManager.current; |
277 |
if (sm != null) |
if (sm != null) |
278 |
sm.checkCreateClassLoader(); |
sm.checkCreateClassLoader(); |
279 |
this.parent = parent; |
this.parent = parent; |
371 |
* { |
* { |
372 |
* String packageName = name.substring(0, lastDot); |
* String packageName = name.substring(0, lastDot); |
373 |
* // Look if the package already exists |
* // Look if the package already exists |
374 |
* if (getPackage(pkg) == null) |
* if (getPackage(packageName) == null) |
375 |
* { |
* { |
376 |
* // define the package |
* // define the package |
377 |
* definePackage(packageName, ...); |
* definePackage(packageName, ...); |
468 |
throws ClassFormatError |
throws ClassFormatError |
469 |
{ |
{ |
470 |
if (domain == null) |
if (domain == null) |
471 |
domain = defaultProtectionDomain; |
domain = StaticData.defaultProtectionDomain; |
472 |
if (! initialized) |
if (! initialized) |
473 |
throw new SecurityException("attempt to define class from uninitialized class loader"); |
throw new SecurityException("attempt to define class from uninitialized class loader"); |
474 |
Class<?> retval = VMClassLoader.defineClass(this, name, data, |
Class<?> retval = VMClassLoader.defineClass(this, name, data, |
511 |
protected final Class<?> findSystemClass(String name) |
protected final Class<?> findSystemClass(String name) |
512 |
throws ClassNotFoundException |
throws ClassNotFoundException |
513 |
{ |
{ |
514 |
return Class.forName(name, false, System.systemClassLoader); |
return Class.forName(name, false, StaticData.systemClassLoader); |
515 |
} |
} |
516 |
|
|
517 |
/** |
/** |
527 |
public final ClassLoader getParent() |
public final ClassLoader getParent() |
528 |
{ |
{ |
529 |
// Check if we may return the parent classloader. |
// Check if we may return the parent classloader. |
530 |
SecurityManager sm = System.getSecurityManager(); |
SecurityManager sm = SecurityManager.current; |
531 |
if (sm != null) |
if (sm != null) |
532 |
{ |
{ |
533 |
Class<?> c = VMSecurityManager.getClassContext()[1]; |
ClassLoader cl = VMStackWalker.getCallingClassLoader(); |
|
ClassLoader cl = c.getClassLoader(); |
|
534 |
if (cl != null && ! cl.isAncestorOf(this)) |
if (cl != null && ! cl.isAncestorOf(this)) |
535 |
sm.checkPermission(new RuntimePermission("getClassLoader")); |
sm.checkPermission(new RuntimePermission("getClassLoader")); |
536 |
} |
} |
672 |
*/ |
*/ |
673 |
public static final URL getSystemResource(String name) |
public static final URL getSystemResource(String name) |
674 |
{ |
{ |
675 |
return System.systemClassLoader.getResource(name); |
return StaticData.systemClassLoader.getResource(name); |
676 |
} |
} |
677 |
|
|
678 |
/** |
/** |
689 |
public static Enumeration<URL> getSystemResources(String name) |
public static Enumeration<URL> getSystemResources(String name) |
690 |
throws IOException |
throws IOException |
691 |
{ |
{ |
692 |
return System.systemClassLoader.getResources(name); |
return StaticData.systemClassLoader.getResources(name); |
693 |
} |
} |
694 |
|
|
695 |
/** |
/** |
770 |
public static ClassLoader getSystemClassLoader() |
public static ClassLoader getSystemClassLoader() |
771 |
{ |
{ |
772 |
// Check if we may return the system classloader |
// Check if we may return the system classloader |
773 |
SecurityManager sm = System.getSecurityManager(); |
SecurityManager sm = SecurityManager.current; |
774 |
if (sm != null) |
if (sm != null) |
775 |
{ |
{ |
776 |
Class<?> c = VMSecurityManager.getClassContext()[1]; |
ClassLoader cl = VMStackWalker.getCallingClassLoader(); |
777 |
ClassLoader cl = c.getClassLoader(); |
if (cl != null && cl != StaticData.systemClassLoader) |
|
if (cl != null && cl != System.systemClassLoader) |
|
778 |
sm.checkPermission(new RuntimePermission("getClassLoader")); |
sm.checkPermission(new RuntimePermission("getClassLoader")); |
779 |
} |
} |
780 |
|
|
781 |
return System.systemClassLoader; |
return StaticData.systemClassLoader; |
782 |
} |
} |
783 |
|
|
784 |
/** |
/** |
937 |
{ |
{ |
938 |
if (packageAssertionStatus == null) |
if (packageAssertionStatus == null) |
939 |
packageAssertionStatus |
packageAssertionStatus |
940 |
= new HashMap<String, Boolean>(systemPackageAssertionStatus); |
= new HashMap<String, Boolean>(StaticData.systemPackageAssertionStatus); |
941 |
packageAssertionStatus.put(name, Boolean.valueOf(enabled)); |
packageAssertionStatus.put(name, Boolean.valueOf(enabled)); |
942 |
} |
} |
943 |
|
|
958 |
{ |
{ |
959 |
if (classAssertionStatus == null) |
if (classAssertionStatus == null) |
960 |
classAssertionStatus |
classAssertionStatus |
961 |
= new HashMap<String, Boolean>(systemClassAssertionStatus); |
= new HashMap<String, Boolean>(StaticData.systemClassAssertionStatus); |
962 |
// The toString() hack catches null, as required. |
// The toString() hack catches null, as required. |
963 |
classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled)); |
classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled)); |
964 |
} |
} |
998 |
|
|
999 |
private static URL[] getExtClassLoaderUrls() |
private static URL[] getExtClassLoaderUrls() |
1000 |
{ |
{ |
1001 |
String classpath = getSystemProperty("java.ext.dirs", ""); |
String classpath = SystemProperties.getProperty("java.ext.dirs", ""); |
1002 |
StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator); |
StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator); |
1003 |
ArrayList list = new ArrayList(); |
ArrayList list = new ArrayList(); |
1004 |
while (tok.hasMoreTokens()) |
while (tok.hasMoreTokens()) |
1034 |
|
|
1035 |
private static URL[] getSystemClassLoaderUrls() |
private static URL[] getSystemClassLoaderUrls() |
1036 |
{ |
{ |
1037 |
String classpath = getSystemProperty("java.class.path", "."); |
String classpath = SystemProperties.getProperty("java.class.path", "."); |
1038 |
StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator, true); |
StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator, true); |
1039 |
ArrayList list = new ArrayList(); |
ArrayList list = new ArrayList(); |
1040 |
while (tok.hasMoreTokens()) |
while (tok.hasMoreTokens()) |
1072 |
boolean resolve) |
boolean resolve) |
1073 |
throws ClassNotFoundException |
throws ClassNotFoundException |
1074 |
{ |
{ |
1075 |
SecurityManager sm = Runtime.securityManager; |
SecurityManager sm = SecurityManager.current; |
1076 |
if (sm != null) |
if (sm != null) |
1077 |
{ |
{ |
1078 |
int lastDot = name.lastIndexOf('.'); |
int lastDot = name.lastIndexOf('.'); |
1082 |
return super.loadClass(name, resolve); |
return super.loadClass(name, resolve); |
1083 |
} |
} |
1084 |
}; |
}; |
1085 |
String loader = getSystemProperty("java.system.class.loader", null); |
String loader = SystemProperties.getProperty("java.system.class.loader", null); |
1086 |
if (loader == null) |
if (loader == null) |
1087 |
{ |
{ |
1088 |
return systemClassLoader; |
return systemClassLoader; |
1101 |
.initCause(e); |
.initCause(e); |
1102 |
} |
} |
1103 |
} |
} |
|
|
|
|
static String getSystemProperty(String name, String defaultValue) |
|
|
{ |
|
|
// access properties directly to bypass security |
|
|
String val = System.properties.getProperty(name); |
|
|
if (val == null) |
|
|
{ |
|
|
val = defaultValue; |
|
|
} |
|
|
return val; |
|
|
} |
|
1104 |
} |
} |