49 import java.util.Map; |
49 import java.util.Map; |
50 import java.util.Vector; |
50 import java.util.Vector; |
51 import java.util.Hashtable; |
51 import java.util.Hashtable; |
52 import java.util.WeakHashMap; |
52 import java.util.WeakHashMap; |
53 import java.util.concurrent.ConcurrentHashMap; |
53 import java.util.concurrent.ConcurrentHashMap; |
|
54 import sun.misc.BootClassLoaderHook; |
54 import sun.misc.ClassFileTransformer; |
55 import sun.misc.ClassFileTransformer; |
55 import sun.misc.CompoundEnumeration; |
56 import sun.misc.CompoundEnumeration; |
56 import sun.misc.Resource; |
57 import sun.misc.Resource; |
57 import sun.misc.URLClassPath; |
58 import sun.misc.URLClassPath; |
58 import sun.misc.VM; |
59 import sun.misc.VM; |
59 import sun.reflect.Reflection; |
60 import sun.reflect.Reflection; |
60 import sun.security.util.SecurityConstants; |
61 import sun.security.util.SecurityConstants; |
61 import sun.jkernel.DownloadManager; |
|
62 |
62 |
63 /** |
63 /** |
64 * A class loader is an object that is responsible for loading classes. The |
64 * A class loader is an object that is responsible for loading classes. The |
65 * class <tt>ClassLoader</tt> is an abstract class. Given the <a |
65 * class <tt>ClassLoader</tt> is an abstract class. Given the <a |
66 * href="#name">binary name</a> of a class, a class loader should attempt to |
66 * href="#name">binary name</a> of a class, a class loader should attempt to |
362 { |
362 { |
363 synchronized (getClassLoadingLock(name)) { |
363 synchronized (getClassLoadingLock(name)) { |
364 // First, check if the class has already been loaded |
364 // First, check if the class has already been loaded |
365 Class c = findLoadedClass(name); |
365 Class c = findLoadedClass(name); |
366 if (c == null) { |
366 if (c == null) { |
|
367 long t0 = System.nanoTime(); |
367 try { |
368 try { |
368 if (parent != null) { |
369 if (parent != null) { |
369 c = parent.loadClass(name, false); |
370 c = parent.loadClass(name, false); |
370 } else { |
371 } else { |
371 c = findBootstrapClass0(name); |
372 c = findBootstrapClassOrNull(name); |
372 } |
373 } |
373 } catch (ClassNotFoundException e) { |
374 } catch (ClassNotFoundException e) { |
|
375 // ClassNotFoundException thrown if class not found |
|
376 // from the non-null parent class loader |
|
377 } |
|
378 |
|
379 if (c == null) { |
374 // If still not found, then invoke findClass in order |
380 // If still not found, then invoke findClass in order |
375 // to find the class. |
381 // to find the class. |
|
382 long t1 = System.nanoTime(); |
376 c = findClass(name); |
383 c = findClass(name); |
|
384 |
|
385 // this is the defining class loader; record the stats |
|
386 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); |
|
387 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); |
|
388 sun.misc.PerfCounter.getFindClasses().increment(); |
377 } |
389 } |
378 } |
390 } |
379 if (resolve) { |
391 if (resolve) { |
380 resolveClass(c); |
392 resolveClass(c); |
381 } |
393 } |
985 { |
997 { |
986 ClassLoader system = getSystemClassLoader(); |
998 ClassLoader system = getSystemClassLoader(); |
987 if (system == null) { |
999 if (system == null) { |
988 if (!checkName(name)) |
1000 if (!checkName(name)) |
989 throw new ClassNotFoundException(name); |
1001 throw new ClassNotFoundException(name); |
990 return findBootstrapClass(name); |
1002 Class cls = findBootstrapClass(name); |
|
1003 if (cls == null) { |
|
1004 throw new ClassNotFoundException(name); |
|
1005 } |
|
1006 return cls; |
991 } |
1007 } |
992 return system.loadClass(name); |
1008 return system.loadClass(name); |
993 } |
1009 } |
994 |
1010 |
995 private Class findBootstrapClass0(String name) |
1011 /** |
996 throws ClassNotFoundException |
1012 * Returns a class loaded by the bootstrap class loader; |
|
1013 * or return null if not found. |
|
1014 */ |
|
1015 private Class findBootstrapClassOrNull(String name) |
997 { |
1016 { |
998 if (!checkName(name)) |
1017 if (!checkName(name)) return null; |
999 throw new ClassNotFoundException(name); |
1018 |
1000 return findBootstrapClass(name); |
1019 return findBootstrapClass(name); |
1001 } |
1020 } |
1002 |
1021 |
1003 private native Class findBootstrapClass(String name) |
1022 // return null if not found |
1004 throws ClassNotFoundException; |
1023 private native Class findBootstrapClass(String name); |
1005 |
1024 |
1006 /** |
1025 /** |
1007 * Returns the class with the given <a href="#name">binary name</a> if this |
1026 * Returns the class with the given <a href="#name">binary name</a> if this |
1008 * loader has been recorded by the Java virtual machine as an initiating |
1027 * loader has been recorded by the Java virtual machine as an initiating |
1009 * loader of a class with that <a href="#name">binary name</a>. Otherwise |
1028 * loader of a class with that <a href="#name">binary name</a>. Otherwise |
1248 |
1267 |
1249 /** |
1268 /** |
1250 * Find resources from the VM's built-in classloader. |
1269 * Find resources from the VM's built-in classloader. |
1251 */ |
1270 */ |
1252 private static URL getBootstrapResource(String name) { |
1271 private static URL getBootstrapResource(String name) { |
1253 try { |
1272 BootClassLoaderHook.preLoadResource(name); |
1254 // If this is a known JRE resource, ensure that its bundle is |
|
1255 // downloaded. If it isn't known, we just ignore the download |
|
1256 // failure and check to see if we can find the resource anyway |
|
1257 // (which is possible if the boot class path has been modified). |
|
1258 if (sun.misc.VM.isBootedKernelVM()) { |
|
1259 sun.jkernel.DownloadManager.getBootClassPathEntryForResource( |
|
1260 name); |
|
1261 } |
|
1262 } catch (NoClassDefFoundError e) { |
|
1263 // This happens while Java itself is being compiled; DownloadManager |
|
1264 // isn't accessible when this code is first invoked. It isn't an |
|
1265 // issue, as if we can't find DownloadManager, we can safely assume |
|
1266 // that additional code is not available for download. |
|
1267 } |
|
1268 URLClassPath ucp = getBootstrapClassPath(); |
1273 URLClassPath ucp = getBootstrapClassPath(); |
1269 Resource res = ucp.getResource(name); |
1274 Resource res = ucp.getResource(name); |
1270 return res != null ? res.getURL() : null; |
1275 return res != null ? res.getURL() : null; |
1271 } |
1276 } |
1272 |
1277 |
1779 } |
1784 } |
1780 |
1785 |
1781 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. |
1786 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. |
1782 static void loadLibrary(Class fromClass, String name, |
1787 static void loadLibrary(Class fromClass, String name, |
1783 boolean isAbsolute) { |
1788 boolean isAbsolute) { |
1784 try { |
1789 BootClassLoaderHook.preLoadLibrary(name); |
1785 if (VM.isBootedKernelVM() && !DownloadManager.isJREComplete() && |
|
1786 !DownloadManager.isCurrentThreadDownloading()) { |
|
1787 DownloadManager.downloadFile("bin/" + |
|
1788 System.mapLibraryName(name)); |
|
1789 // it doesn't matter if the downloadFile call returns false -- |
|
1790 // it probably just means that this is a user library, as |
|
1791 // opposed to a JRE library |
|
1792 } |
|
1793 } catch (IOException e) { |
|
1794 throw new UnsatisfiedLinkError("Error downloading library " + |
|
1795 name + ": " + e); |
|
1796 } catch (NoClassDefFoundError e) { |
|
1797 // This happens while Java itself is being compiled; DownloadManager |
|
1798 // isn't accessible when this code is first invoked. It isn't an |
|
1799 // issue, as if we can't find DownloadManager, we can safely assume |
|
1800 // that additional code is not available for download. |
|
1801 } |
|
1802 ClassLoader loader = |
1790 ClassLoader loader = |
1803 (fromClass == null) ? null : fromClass.getClassLoader(); |
1791 (fromClass == null) ? null : fromClass.getClassLoader(); |
1804 if (sys_paths == null) { |
1792 if (sys_paths == null) { |
1805 usr_paths = initializePath("java.library.path"); |
1793 usr_paths = initializePath("java.library.path"); |
1806 sys_paths = initializePath("sun.boot.library.path"); |
1794 sys_paths = initializePath("sun.boot.library.path"); |