< prev index next >

src/java.base/share/classes/java/lang/ClassLoader.java

Print this page




  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 


< prev index next >