--- old/src/java.base/share/classes/java/lang/Class.java 2017-06-21 13:11:17.000000000 -0700 +++ new/src/java.base/share/classes/java/lang/Class.java 2017-06-21 13:11:16.000000000 -0700 @@ -288,7 +288,11 @@ public static Class forName(String className) throws ClassNotFoundException { Class caller = Reflection.getCallerClass(); - return forName0(className, true, ClassLoader.getClassLoader(caller), caller); + Class c = forName0(className, true, ClassLoader.getClassLoader(caller), caller); + if (c.isValueClass()) { + throw new ClassNotFoundException(className + " is a derived value class"); + } + return c; } @@ -371,13 +375,17 @@ } } } - return forName0(name, initialize, loader, caller); + Class c = forName0(name, initialize, loader, caller); + if (c.isValueClass()) { + throw new ClassNotFoundException(name + " is a derived value class"); + } + return c; } /** Called after security check for system loader access checks have been made. */ - private static native Class forName0(String name, boolean initialize, - ClassLoader loader, - Class caller) + static native Class forName0(String name, boolean initialize, + ClassLoader loader, + Class caller) throws ClassNotFoundException; @@ -443,10 +451,32 @@ PrivilegedAction pa = module::getClassLoader; ClassLoader cl = AccessController.doPrivileged(pa); + Class c; if (cl != null) { - return cl.loadClass(module, name); + c = cl.loadClass(module, name); } else { - return BootLoader.loadClass(module, name); + c = BootLoader.loadClass(module, name); + } + + return c != null && !c.isValueClass() ? c : null; + } + + boolean isValueClass() { + Class c = this; + while (c.isArray()) { + c = c.getComponentType(); + } + + // This could call MinimalValueTypes_1_0::isValueType or check ACC_VALUE. + // For now, check if it is a subtype of __Value to avoid + // initializing MinimalValueTypes_1_0 class during early startup. + return __Value.class.isAssignableFrom(c) && c != __Value.class; + } + + private void ensureNotValueClass() { + if (this.isValueClass()) { + throw new UnsupportedOperationException("cannot reflect on derived value type " + + this.getName()); } } @@ -508,6 +538,8 @@ public T newInstance() throws InstantiationException, IllegalAccessException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false); @@ -1237,6 +1269,8 @@ // Perform access check final Class enclosingCandidate = enclosingInfo.getEnclosingClass(); + enclosingCandidate.ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { enclosingCandidate.checkMemberAccess(sm, Member.DECLARED, @@ -1393,6 +1427,8 @@ // Perform access check final Class enclosingCandidate = enclosingInfo.getEnclosingClass(); + enclosingCandidate.ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { enclosingCandidate.checkMemberAccess(sm, Member.DECLARED, @@ -1689,6 +1725,8 @@ */ @CallerSensitive public Class[] getClasses() { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false); @@ -1758,6 +1796,8 @@ */ @CallerSensitive public Field[] getFields() throws SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true); @@ -1848,6 +1888,8 @@ */ @CallerSensitive public Method[] getMethods() throws SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true); @@ -1887,6 +1929,8 @@ */ @CallerSensitive public Constructor[] getConstructors() throws SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true); @@ -1940,6 +1984,8 @@ @CallerSensitive public Field getField(String name) throws NoSuchFieldException, SecurityException { + ensureNotValueClass(); + Objects.requireNonNull(name); SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -2049,6 +2095,8 @@ @CallerSensitive public Method getMethod(String name, Class... parameterTypes) throws NoSuchMethodException, SecurityException { + ensureNotValueClass(); + Objects.requireNonNull(name); SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -2113,6 +2161,8 @@ public Constructor getConstructor(Class... parameterTypes) throws NoSuchMethodException, SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true); @@ -2159,6 +2209,8 @@ */ @CallerSensitive public Class[] getDeclaredClasses() throws SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), false); @@ -2211,6 +2263,8 @@ */ @CallerSensitive public Field[] getDeclaredFields() throws SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true); @@ -2273,6 +2327,8 @@ */ @CallerSensitive public Method[] getDeclaredMethods() throws SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true); @@ -2321,6 +2377,8 @@ */ @CallerSensitive public Constructor[] getDeclaredConstructors() throws SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true); @@ -2372,6 +2430,8 @@ @CallerSensitive public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException { + ensureNotValueClass(); + Objects.requireNonNull(name); SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -2436,6 +2496,8 @@ @CallerSensitive public Method getDeclaredMethod(String name, Class... parameterTypes) throws NoSuchMethodException, SecurityException { + ensureNotValueClass(); + Objects.requireNonNull(name); SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -2491,6 +2553,8 @@ public Constructor getDeclaredConstructor(Class... parameterTypes) throws NoSuchMethodException, SecurityException { + ensureNotValueClass(); + SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);