43 import java.util.Collections;
44 import java.util.Deque;
45 import java.util.Enumeration;
46 import java.util.HashMap;
47 import java.util.HashSet;
48 import java.util.Hashtable;
49 import java.util.Map;
50 import java.util.NoSuchElementException;
51 import java.util.Objects;
52 import java.util.Set;
53 import java.util.Spliterator;
54 import java.util.Spliterators;
55 import java.util.Vector;
56 import java.util.WeakHashMap;
57 import java.util.concurrent.ConcurrentHashMap;
58 import java.util.function.Supplier;
59 import java.util.stream.Stream;
60 import java.util.stream.StreamSupport;
61
62 import jdk.internal.loader.BuiltinClassLoader;
63 import jdk.internal.perf.PerfCounter;
64 import jdk.internal.loader.BootLoader;
65 import jdk.internal.loader.ClassLoaders;
66 import jdk.internal.misc.Unsafe;
67 import jdk.internal.misc.VM;
68 import jdk.internal.ref.CleanerFactory;
69 import jdk.internal.reflect.CallerSensitive;
70 import jdk.internal.reflect.Reflection;
71 import sun.reflect.misc.ReflectUtil;
72 import sun.security.util.SecurityConstants;
73
74 /**
75 * A class loader is an object that is responsible for loading classes. The
76 * class {@code ClassLoader} is an abstract class. Given the <a
77 * href="#binary-name">binary name</a> of a class, a class loader should attempt to
78 * locate or generate data that constitutes a definition for the class. A
79 * typical strategy is to transform the name into a file name and then read a
80 * "class file" of that name from a file system.
81 *
82 * <p> Every {@link java.lang.Class Class} object contains a {@link
2952 // assert Thread.holdsLock(assertionLock);
2953
2954 classAssertionStatus = new HashMap<>();
2955 packageAssertionStatus = new HashMap<>();
2956 AssertionStatusDirectives directives = retrieveDirectives();
2957
2958 for(int i = 0; i < directives.classes.length; i++)
2959 classAssertionStatus.put(directives.classes[i],
2960 directives.classEnabled[i]);
2961
2962 for(int i = 0; i < directives.packages.length; i++)
2963 packageAssertionStatus.put(directives.packages[i],
2964 directives.packageEnabled[i]);
2965
2966 defaultAssertionStatus = directives.deflt;
2967 }
2968
2969 // Retrieves the assertion directives from the VM.
2970 private static native AssertionStatusDirectives retrieveDirectives();
2971
2972
2973 // -- Misc --
2974
2975 /**
2976 * Returns the ConcurrentHashMap used as a storage for ClassLoaderValue(s)
2977 * associated with this ClassLoader, creating it if it doesn't already exist.
2978 */
2979 ConcurrentHashMap<?, ?> createOrGetClassLoaderValueMap() {
2980 ConcurrentHashMap<?, ?> map = classLoaderValueMap;
2981 if (map == null) {
2982 map = new ConcurrentHashMap<>();
2983 boolean set = trySetObjectField("classLoaderValueMap", map);
2984 if (!set) {
2985 // beaten by someone else
2986 map = classLoaderValueMap;
2987 }
2988 }
2989 return map;
2990 }
2991
|
43 import java.util.Collections;
44 import java.util.Deque;
45 import java.util.Enumeration;
46 import java.util.HashMap;
47 import java.util.HashSet;
48 import java.util.Hashtable;
49 import java.util.Map;
50 import java.util.NoSuchElementException;
51 import java.util.Objects;
52 import java.util.Set;
53 import java.util.Spliterator;
54 import java.util.Spliterators;
55 import java.util.Vector;
56 import java.util.WeakHashMap;
57 import java.util.concurrent.ConcurrentHashMap;
58 import java.util.function.Supplier;
59 import java.util.stream.Stream;
60 import java.util.stream.StreamSupport;
61
62 import jdk.internal.loader.BuiltinClassLoader;
63 import jdk.internal.loader.ClassLoaderValue;
64 import jdk.internal.perf.PerfCounter;
65 import jdk.internal.loader.BootLoader;
66 import jdk.internal.loader.ClassLoaders;
67 import jdk.internal.misc.Unsafe;
68 import jdk.internal.misc.VM;
69 import jdk.internal.ref.CleanerFactory;
70 import jdk.internal.reflect.CallerSensitive;
71 import jdk.internal.reflect.Reflection;
72 import sun.reflect.misc.ReflectUtil;
73 import sun.security.util.SecurityConstants;
74
75 /**
76 * A class loader is an object that is responsible for loading classes. The
77 * class {@code ClassLoader} is an abstract class. Given the <a
78 * href="#binary-name">binary name</a> of a class, a class loader should attempt to
79 * locate or generate data that constitutes a definition for the class. A
80 * typical strategy is to transform the name into a file name and then read a
81 * "class file" of that name from a file system.
82 *
83 * <p> Every {@link java.lang.Class Class} object contains a {@link
2953 // assert Thread.holdsLock(assertionLock);
2954
2955 classAssertionStatus = new HashMap<>();
2956 packageAssertionStatus = new HashMap<>();
2957 AssertionStatusDirectives directives = retrieveDirectives();
2958
2959 for(int i = 0; i < directives.classes.length; i++)
2960 classAssertionStatus.put(directives.classes[i],
2961 directives.classEnabled[i]);
2962
2963 for(int i = 0; i < directives.packages.length; i++)
2964 packageAssertionStatus.put(directives.packages[i],
2965 directives.packageEnabled[i]);
2966
2967 defaultAssertionStatus = directives.deflt;
2968 }
2969
2970 // Retrieves the assertion directives from the VM.
2971 private static native AssertionStatusDirectives retrieveDirectives();
2972
2973
2974 // A RuntimeException that acts as a substitute for the original exception
2975 // (checked or unchecked) and mimics the original exception in every aspect
2976 // except it's type.
2977 private static class InitExceptionSubst extends RuntimeException {
2978 static final ClassLoaderValue<InitExceptionSubst> INIT_EXCEPTIONS =
2979 new ClassLoaderValue<>();
2980
2981 private static final long serialVersionUID = 1;
2982
2983 private final String threadName;
2984 private final long time;
2985 private final String originalExceptionClassName;
2986 private final String localizedMessage;
2987
2988 InitExceptionSubst(Throwable originalException, boolean top) {
2989 super(originalException.getMessage());
2990
2991 this.threadName = top ? Thread.currentThread().getName() : null;
2992 this.time = top ? System.currentTimeMillis() : 0L;
2993 this.originalExceptionClassName = originalException.getClass().getName();
2994 this.localizedMessage = originalException.getLocalizedMessage();
2995
2996 // substitute originalException's cause
2997 Throwable cause = originalException.getCause();
2998 initCause(cause == null ? null : new InitExceptionSubst(cause, false));
2999
3000 // substitute originalException's suppressed exceptions if any
3001 for (Throwable suppressed : originalException.getSuppressed()) {
3002 addSuppressed(new InitExceptionSubst(suppressed, false));
3003 }
3004
3005 // inherit stack trace elements from originalException
3006 setStackTrace(originalException.getStackTrace());
3007 }
3008
3009 @Override
3010 public Throwable fillInStackTrace() {
3011 // don't need our backtrace -
3012 // will inherit stack trace elements from originalException
3013 return this;
3014 }
3015
3016 @Override
3017 public String getLocalizedMessage() {
3018 return localizedMessage;
3019 }
3020
3021 @Override
3022 public String toString() {
3023 // Emulate toString() method as if called upon originalException
3024 String message = getLocalizedMessage();
3025 return time == 0L
3026 ? (message != null
3027 ? originalExceptionClassName + ": " + message
3028 : originalExceptionClassName
3029 )
3030 : (message != null
3031 ? originalExceptionClassName + ": " +
3032 (System.currentTimeMillis() - time) + " ms ago in thread " +
3033 threadName + ": " + message
3034 : originalExceptionClassName + ": " +
3035 (System.currentTimeMillis() - time) + " ms ago in thread " +
3036 threadName
3037 );
3038 }
3039 }
3040
3041 // Called by the VM as notification just before exception
3042 // (typically ExceptionInInitializerError) is thrown after unsuccessful
3043 // attempt to initialize the class for the 1st time
3044 private static void recordInitException(Class<?> clazz, Throwable exc) {
3045 InitExceptionSubst.INIT_EXCEPTIONS
3046 .sub(clazz)
3047 .putIfAbsent(clazz.getClassLoader0(), new InitExceptionSubst(exc, true));
3048 }
3049
3050 // Called by the vm to throw NoClassDefFoundError as a consequence of
3051 // class re-initialization attempt after the 1st class initialization
3052 // attempt failed
3053 private static void throwReinitException(Class<?> clazz) {
3054 InitExceptionSubst cause = InitExceptionSubst.INIT_EXCEPTIONS
3055 .sub(clazz)
3056 .get(clazz.getClassLoader0());
3057 throw (Error) new NoClassDefFoundError(
3058 "Could not initialize " + clazz).initCause(cause);
3059 }
3060
3061 // -- Misc --
3062
3063 /**
3064 * Returns the ConcurrentHashMap used as a storage for ClassLoaderValue(s)
3065 * associated with this ClassLoader, creating it if it doesn't already exist.
3066 */
3067 ConcurrentHashMap<?, ?> createOrGetClassLoaderValueMap() {
3068 ConcurrentHashMap<?, ?> map = classLoaderValueMap;
3069 if (map == null) {
3070 map = new ConcurrentHashMap<>();
3071 boolean set = trySetObjectField("classLoaderValueMap", map);
3072 if (!set) {
3073 // beaten by someone else
3074 map = classLoaderValueMap;
3075 }
3076 }
3077 return map;
3078 }
3079
|