summaryrefslogtreecommitdiff
path: root/external/ikvm/openjdk/java/lang
diff options
context:
space:
mode:
Diffstat (limited to 'external/ikvm/openjdk/java/lang')
-rw-r--r--external/ikvm/openjdk/java/lang/Class.java181
-rw-r--r--external/ikvm/openjdk/java/lang/ClassLoader.java57
-rw-r--r--external/ikvm/openjdk/java/lang/Package.java615
-rw-r--r--external/ikvm/openjdk/java/lang/System.java11
-rw-r--r--external/ikvm/openjdk/java/lang/Thread.java37
-rw-r--r--external/ikvm/openjdk/java/lang/invoke/MethodHandles.java14
-rw-r--r--external/ikvm/openjdk/java/lang/reflect/Constructor.java6
-rw-r--r--external/ikvm/openjdk/java/lang/reflect/Field.java186
-rw-r--r--external/ikvm/openjdk/java/lang/reflect/Method.java6
-rw-r--r--external/ikvm/openjdk/java/lang/reflect/Proxy.java159
10 files changed, 1085 insertions, 187 deletions
diff --git a/external/ikvm/openjdk/java/lang/Class.java b/external/ikvm/openjdk/java/lang/Class.java
index 20f35534c3..bbc1d241f6 100644
--- a/external/ikvm/openjdk/java/lang/Class.java
+++ b/external/ikvm/openjdk/java/lang/Class.java
@@ -53,6 +53,7 @@ import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
@@ -65,7 +66,9 @@ import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation;
-import sun.reflect.annotation.AnnotationType;
+import java.lang.reflect.Proxy;
+import sun.reflect.annotation.*;
+import sun.reflect.misc.ReflectUtil;
import cli.System.Runtime.Serialization.IObjectReference;
import cli.System.Runtime.Serialization.SerializationException;
import cli.System.Runtime.Serialization.SerializationInfo;
@@ -281,10 +284,11 @@ public final
* by this method fails
* @exception ClassNotFoundException if the class cannot be located
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
- return forName0(className, true, ClassLoader.getCallerClassLoader());
+ return forName0(className, true,
+ ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
@@ -348,7 +352,7 @@ public final
* @see java.lang.ClassLoader
* @since 1.2
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
@@ -356,7 +360,7 @@ public final
if (loader == null) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
+ ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (ccl != null) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
@@ -418,19 +422,14 @@ public final
* </ul>
*
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
- return newInstance0(ikvm.internal.CallerID.getCallerID());
- }
- private T newInstance0(ikvm.internal.CallerID callerID)
- throws InstantiationException, IllegalAccessException
- {
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
@@ -464,7 +463,7 @@ public final
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
- Class<?> caller = callerID.getCallerClass();
+ Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
@@ -705,17 +704,14 @@ public final
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
}
@@ -996,6 +992,7 @@ public final
* that class is a local or anonymous class; otherwise {@code null}.
* @since 1.5
*/
+ @CallerSensitive
public Method getEnclosingMethod() {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@@ -1017,13 +1014,22 @@ public final
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
+ // Perform access check
+ Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+ //
+ // Note that we need to do this on the enclosing class
+ enclosingCandidate.checkMemberAccess(Member.DECLARED,
+ Reflection.getCallerClass(), true);
/*
* Loop over all declared methods; match method name,
* number of and type of parameters, *and* return
* type. Matching return type is also necessary
* because of covariant returns, etc.
*/
- for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) {
+ for(Method m: enclosingCandidate.getDeclaredMethods()) {
if (m.getName().equals(enclosingInfo.getName()) ) {
Class<?>[] candidateParamClasses = m.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
@@ -1124,6 +1130,7 @@ public final
* that class is a local or anonymous class; otherwise {@code null}.
* @since 1.5
*/
+ @CallerSensitive
public Constructor<?> getEnclosingConstructor() {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@@ -1144,11 +1151,20 @@ public final
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
+ // Perform access check
+ Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+ //
+ // Note that we need to do this on the enclosing class
+ enclosingCandidate.checkMemberAccess(Member.DECLARED,
+ Reflection.getCallerClass(), true);
/*
* Loop over all declared constructors; match number
* of and type of parameters.
*/
- for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) {
+ for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) {
Class<?>[] candidateParamClasses = c.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
@@ -1190,6 +1206,7 @@ public final
* @return the immediately enclosing class of the underlying class
* @since 1.5
*/
+ @CallerSensitive
public Class<?> getEnclosingClass() {
// There are five kinds of classes (or interfaces):
// a) Top level classes
@@ -1203,18 +1220,24 @@ public final
// attribute if and only if it is a local class or an
// anonymous class.
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
+ Class<?> enclosingCandidate;
if (enclosingInfo == null) {
// This is a top level or a nested class or an inner class (a, b, or c)
- return getDeclaringClass();
+ enclosingCandidate = getDeclaringClass();
} else {
Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
// This is a local class or an anonymous class (d or e)
if (enclosingClass == this || enclosingClass == null)
throw new InternalError("Malformed enclosing method information");
else
- return enclosingClass;
+ enclosingCandidate = enclosingClass;
}
+
+ if (enclosingCandidate != null)
+ enclosingCandidate.checkPackageAccess(
+ ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
+ return enclosingCandidate;
}
/**
@@ -1397,12 +1420,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Class<?>[] getClasses() {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
@@ -1473,12 +1496,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Field[] getFields() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyFields(privateGetPublicFields(null));
}
@@ -1525,12 +1548,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Method[] getMethods() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyMethods(privateGetPublicMethods());
}
@@ -1575,12 +1598,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
@@ -1634,13 +1657,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1720,13 +1743,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Method method = getMethod0(name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -1775,13 +1798,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
@@ -1819,12 +1842,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Class<?>[] getDeclaredClasses() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
return getDeclaredClasses0();
}
@@ -1864,12 +1887,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyFields(privateGetDeclaredFields(false));
}
@@ -1913,12 +1936,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
@@ -1959,12 +1982,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(false));
}
@@ -2003,13 +2026,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -2059,13 +2082,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -2110,13 +2133,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
@@ -2274,31 +2297,69 @@ public final
*/
static native Class getPrimitiveClass(String name);
+ private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) {
+ if (smgr.getClass() == SecurityManager.class) return false;
+
+ Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class};
+ return smgr.getClass().getMethod0("checkMemberAccess", paramTypes).
+ getDeclaringClass() != SecurityManager.class;
+ }
+
/*
* Check if client is allowed to access members. If access is denied,
* throw a SecurityException.
*
- * Be very careful not to change the stack depth of this checkMemberAccess
- * call for security reasons.
- * See java.lang.SecurityManager.checkMemberAccess.
+ * This method also enforces package access.
*
* <p> Default policy: allow all clients access with normal Java access
* control.
*/
- private void checkMemberAccess(int which, ClassLoader ccl) {
- SecurityManager s = System.getSecurityManager();
+ private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
+ final SecurityManager s = System.getSecurityManager();
if (s != null) {
- s.checkMemberAccess(this, which);
- ClassLoader cl = getClassLoader0();
- if ((ccl != null) && (ccl != cl) &&
- ((cl == null) || !cl.isAncestor(ccl))) {
+ final ClassLoader ccl = ClassLoader.getClassLoader(caller);
+ final ClassLoader cl = getClassLoader0();
+ if (!isCheckMemberAccessOverridden(s)) {
+ // Inlined SecurityManager.checkMemberAccess
+ if (which != Member.PUBLIC) {
+ if (ccl != cl) {
+ s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
+ }
+ }
+ } else {
+ // Don't refactor; otherwise break the stack depth for
+ // checkMemberAccess of subclasses of SecurityManager as specified.
+ s.checkMemberAccess(this, which);
+ }
+ this.checkPackageAccess(ccl, checkProxyInterfaces);
+ }
+ }
+
+ /*
+ * Checks if a client loaded in ClassLoader ccl is allowed to access this
+ * class under the current package access policy. If access is denied,
+ * throw a SecurityException.
+ */
+ private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) {
+ final SecurityManager s = System.getSecurityManager();
+ if (s != null) {
+ final ClassLoader cl = getClassLoader0();
+ if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
- s.checkPackageAccess(name.substring(0, i));
+ // skip the package access check on a proxy class in default proxy package
+ String pkg = name.substring(0, i);
+ if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
+ s.checkPackageAccess(pkg);
+ }
}
}
+ // check package access on the proxy interfaces
+ if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
+ ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
+ }
}
}
diff --git a/external/ikvm/openjdk/java/lang/ClassLoader.java b/external/ikvm/openjdk/java/lang/ClassLoader.java
index 8162ba81c0..57c1ee3e39 100644
--- a/external/ikvm/openjdk/java/lang/ClassLoader.java
+++ b/external/ikvm/openjdk/java/lang/ClassLoader.java
@@ -56,6 +56,7 @@ import sun.misc.CompoundEnumeration;
import sun.misc.Resource;
import sun.misc.URLClassPath;
import sun.misc.VM;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
@@ -1256,9 +1257,11 @@ public abstract class ClassLoader {
*
* @since 1.7
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
protected static boolean registerAsParallelCapable() {
- return ParallelLoaders.register(ikvm.internal.CallerID.getCallerID().getCallerClass());
+ Class<? extends ClassLoader> callerClass =
+ Reflection.getCallerClass().asSubclass(ClassLoader.class);
+ return ParallelLoaders.register(callerClass);
}
/**
@@ -1402,15 +1405,13 @@ public abstract class ClassLoader {
*
* @since 1.2
*/
+ @CallerSensitive
public final ClassLoader getParent() {
if (parent == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = getCallerClassLoader();
- if (ccl != null && !isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ checkClassLoaderPermission(parent, Reflection.getCallerClass());
}
return parent;
}
@@ -1470,7 +1471,7 @@ public abstract class ClassLoader {
*
* @revised 1.4
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public static ClassLoader getSystemClassLoader() {
initSystemClassLoader();
if (scl == null) {
@@ -1478,10 +1479,7 @@ public abstract class ClassLoader {
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = getCallerClassLoader();
- if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ checkClassLoaderPermission(scl, Reflection.getCallerClass());
}
return scl;
}
@@ -1529,13 +1527,25 @@ public abstract class ClassLoader {
return false;
}
- // Returns the invoker's class loader, or null if none.
- // NOTE: This must always be invoked when there is exactly one intervening
- // frame from the core libraries on the stack between this method's
- // invocation and the desired invoker.
- static ClassLoader getCallerClassLoader() {
- // NOTE use of more generic Reflection.getCallerClass()
- Class caller = Reflection.getCallerClass(3);
+ // Tests if class loader access requires "getClassLoader" permission
+ // check. A class loader 'from' can access class loader 'to' if
+ // class loader 'from' is same as class loader 'to' or an ancestor
+ // of 'to'. The class loader in a system domain can access
+ // any class loader.
+ private static boolean needsClassLoaderPermissionCheck(ClassLoader from,
+ ClassLoader to)
+ {
+ if (from == to)
+ return false;
+
+ if (from == null)
+ return false;
+
+ return !to.isAncestor(from);
+ }
+
+ // Returns the class's class loader, or null if none.
+ static ClassLoader getClassLoader(Class<?> caller) {
// This can be null if the VM is requesting it
if (caller == null) {
return null;
@@ -1544,6 +1554,17 @@ public abstract class ClassLoader {
return caller.getClassLoader0();
}
+ static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ // caller can be null if the VM is requesting it
+ ClassLoader ccl = getClassLoader(caller);
+ if (needsClassLoaderPermissionCheck(ccl, cl)) {
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ }
+ }
+ }
+
// The class loader for the system
// @GuardedBy("ClassLoader.class")
private static ClassLoader scl;
diff --git a/external/ikvm/openjdk/java/lang/Package.java b/external/ikvm/openjdk/java/lang/Package.java
new file mode 100644
index 0000000000..395cf3365e
--- /dev/null
+++ b/external/ikvm/openjdk/java/lang/Package.java
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+import java.io.InputStream;
+import java.util.Enumeration;
+
+import java.util.StringTokenizer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes;
+import java.util.jar.Attributes.Name;
+import java.util.jar.JarException;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import java.lang.annotation.Annotation;
+import sun.net.www.ParseUtil;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+
+/**
+ * {@code Package} objects contain version information
+ * about the implementation and specification of a Java package.
+ * This versioning information is retrieved and made available
+ * by the {@link ClassLoader} instance that
+ * loaded the class(es). Typically, it is stored in the manifest that is
+ * distributed with the classes.
+ *
+ * <p>The set of classes that make up the package may implement a
+ * particular specification and if so the specification title, version number,
+ * and vendor strings identify that specification.
+ * An application can ask if the package is
+ * compatible with a particular version, see the {@link
+ * #isCompatibleWith isCompatibleWith}
+ * method for details.
+ *
+ * <p>Specification version numbers use a syntax that consists of nonnegative
+ * decimal integers separated by periods ".", for example "2.0" or
+ * "1.2.3.4.5.6.7". This allows an extensible number to be used to represent
+ * major, minor, micro, etc. versions. The version specification is described
+ * by the following formal grammar:
+ * <blockquote>
+ * <dl>
+ * <dt><i>SpecificationVersion:
+ * <dd>Digits RefinedVersion<sub>opt</sub></i>
+
+ * <p><dt><i>RefinedVersion:</i>
+ * <dd>{@code .} <i>Digits</i>
+ * <dd>{@code .} <i>Digits RefinedVersion</i>
+ *
+ * <p><dt><i>Digits:
+ * <dd>Digit
+ * <dd>Digits</i>
+ *
+ * <p><dt><i>Digit:</i>
+ * <dd>any character for which {@link Character#isDigit} returns {@code true},
+ * e.g. 0, 1, 2, ...
+ * </dl>
+ * </blockquote>
+ *
+ * <p>The implementation title, version, and vendor strings identify an
+ * implementation and are made available conveniently to enable accurate
+ * reporting of the packages involved when a problem occurs. The contents
+ * all three implementation strings are vendor specific. The
+ * implementation version strings have no specified syntax and should
+ * only be compared for equality with desired version identifiers.
+ *
+ * <p>Within each {@code ClassLoader} instance all classes from the same
+ * java package have the same Package object. The static methods allow a package
+ * to be found by name or the set of all packages known to the current class
+ * loader to be found.
+ *
+ * @see ClassLoader#definePackage
+ */
+public class Package implements java.lang.reflect.AnnotatedElement {
+ /**
+ * Return the name of this package.
+ *
+ * @return The fully-qualified name of this package as defined in section 6.5.3 of
+ * <cite>The Java&trade; Language Specification</cite>,
+ * for example, {@code java.lang}
+ */
+ public String getName() {
+ return pkgName;
+ }
+
+
+ /**
+ * Return the title of the specification that this package implements.
+ * @return the specification title, null is returned if it is not known.
+ */
+ public String getSpecificationTitle() {
+ return specTitle;
+ }
+
+ /**
+ * Returns the version number of the specification
+ * that this package implements.
+ * This version string must be a sequence of nonnegative decimal
+ * integers separated by "."'s and may have leading zeros.
+ * When version strings are compared the most significant
+ * numbers are compared.
+ * @return the specification version, null is returned if it is not known.
+ */
+ public String getSpecificationVersion() {
+ return specVersion;
+ }
+
+ /**
+ * Return the name of the organization, vendor,
+ * or company that owns and maintains the specification
+ * of the classes that implement this package.
+ * @return the specification vendor, null is returned if it is not known.
+ */
+ public String getSpecificationVendor() {
+ return specVendor;
+ }
+
+ /**
+ * Return the title of this package.
+ * @return the title of the implementation, null is returned if it is not known.
+ */
+ public String getImplementationTitle() {
+ return implTitle;
+ }
+
+ /**
+ * Return the version of this implementation. It consists of any string
+ * assigned by the vendor of this implementation and does
+ * not have any particular syntax specified or expected by the Java
+ * runtime. It may be compared for equality with other
+ * package version strings used for this implementation
+ * by this vendor for this package.
+ * @return the version of the implementation, null is returned if it is not known.
+ */
+ public String getImplementationVersion() {
+ return implVersion;
+ }
+
+ /**
+ * Returns the name of the organization,
+ * vendor or company that provided this implementation.
+ * @return the vendor that implemented this package..
+ */
+ public String getImplementationVendor() {
+ return implVendor;
+ }
+
+ /**
+ * Returns true if this package is sealed.
+ *
+ * @return true if the package is sealed, false otherwise
+ */
+ public boolean isSealed() {
+ return sealBase != null;
+ }
+
+ /**
+ * Returns true if this package is sealed with respect to the specified
+ * code source url.
+ *
+ * @param url the code source url
+ * @return true if this package is sealed with respect to url
+ */
+ public boolean isSealed(URL url) {
+ return url.equals(sealBase);
+ }
+
+ /**
+ * Compare this package's specification version with a
+ * desired version. It returns true if
+ * this packages specification version number is greater than or equal
+ * to the desired version number. <p>
+ *
+ * Version numbers are compared by sequentially comparing corresponding
+ * components of the desired and specification strings.
+ * Each component is converted as a decimal integer and the values
+ * compared.
+ * If the specification value is greater than the desired
+ * value true is returned. If the value is less false is returned.
+ * If the values are equal the period is skipped and the next pair of
+ * components is compared.
+ *
+ * @param desired the version string of the desired version.
+ * @return true if this package's version number is greater
+ * than or equal to the desired version number
+ *
+ * @exception NumberFormatException if the desired or current version
+ * is not of the correct dotted form.
+ */
+ public boolean isCompatibleWith(String desired)
+ throws NumberFormatException
+ {
+ if (specVersion == null || specVersion.length() < 1) {
+ throw new NumberFormatException("Empty version string");
+ }
+
+ String [] sa = specVersion.split("\\.", -1);
+ int [] si = new int[sa.length];
+ for (int i = 0; i < sa.length; i++) {
+ si[i] = Integer.parseInt(sa[i]);
+ if (si[i] < 0)
+ throw NumberFormatException.forInputString("" + si[i]);
+ }
+
+ String [] da = desired.split("\\.", -1);
+ int [] di = new int[da.length];
+ for (int i = 0; i < da.length; i++) {
+ di[i] = Integer.parseInt(da[i]);
+ if (di[i] < 0)
+ throw NumberFormatException.forInputString("" + di[i]);
+ }
+
+ int len = Math.max(di.length, si.length);
+ for (int i = 0; i < len; i++) {
+ int d = (i < di.length ? di[i] : 0);
+ int s = (i < si.length ? si[i] : 0);
+ if (s < d)
+ return false;
+ if (s > d)
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Find a package by name in the callers {@code ClassLoader} instance.
+ * The callers {@code ClassLoader} instance is used to find the package
+ * instance corresponding to the named class. If the callers
+ * {@code ClassLoader} instance is null then the set of packages loaded
+ * by the system {@code ClassLoader} instance is searched to find the
+ * named package. <p>
+ *
+ * Packages have attributes for versions and specifications only if the class
+ * loader created the package instance with the appropriate attributes. Typically,
+ * those attributes are defined in the manifests that accompany the classes.
+ *
+ * @param name a package name, for example, java.lang.
+ * @return the package of the requested name. It may be null if no package
+ * information is available from the archive or codebase.
+ */
+ @CallerSensitive
+ public static Package getPackage(String name) {
+ ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
+ if (l != null) {
+ return l.getPackage(name);
+ } else {
+ return getSystemPackage(name);
+ }
+ }
+
+ /**
+ * Get all the packages currently known for the caller's {@code ClassLoader}
+ * instance. Those packages correspond to classes loaded via or accessible by
+ * name to that {@code ClassLoader} instance. If the caller's
+ * {@code ClassLoader} instance is the bootstrap {@code ClassLoader}
+ * instance, which may be represented by {@code null} in some implementations,
+ * only packages corresponding to classes loaded by the bootstrap
+ * {@code ClassLoader} instance will be returned.
+ *
+ * @return a new array of packages known to the callers {@code ClassLoader}
+ * instance. An zero length array is returned if none are known.
+ */
+ @CallerSensitive
+ public static Package[] getPackages() {
+ ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
+ if (l != null) {
+ return l.getPackages();
+ } else {
+ return getSystemPackages();
+ }
+ }
+
+ /**
+ * Get the package for the specified class.
+ * The class's class loader is used to find the package instance
+ * corresponding to the specified class. If the class loader
+ * is the bootstrap class loader, which may be represented by
+ * {@code null} in some implementations, then the set of packages
+ * loaded by the bootstrap class loader is searched to find the package.
+ * <p>
+ * Packages have attributes for versions and specifications only
+ * if the class loader created the package
+ * instance with the appropriate attributes. Typically those
+ * attributes are defined in the manifests that accompany
+ * the classes.
+ *
+ * @param class the class to get the package of.
+ * @return the package of the class. It may be null if no package
+ * information is available from the archive or codebase. */
+ static Package getPackage(Class<?> c) {
+ String name = c.getName();
+ int i = name.lastIndexOf('.');
+ if (i != -1) {
+ name = name.substring(0, i);
+ ClassLoader cl = c.getClassLoader();
+ if (cl != null) {
+ return cl.getPackage(name);
+ } else {
+ return getSystemPackage(name);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return the hash code computed from the package name.
+ * @return the hash code computed from the package name.
+ */
+ public int hashCode(){
+ return pkgName.hashCode();
+ }
+
+ /**
+ * Returns the string representation of this Package.
+ * Its value is the string "package " and the package name.
+ * If the package title is defined it is appended.
+ * If the package version is defined it is appended.
+ * @return the string representation of the package.
+ */
+ public String toString() {
+ String spec = specTitle;
+ String ver = specVersion;
+ if (spec != null && spec.length() > 0)
+ spec = ", " + spec;
+ else
+ spec = "";
+ if (ver != null && ver.length() > 0)
+ ver = ", version " + ver;
+ else
+ ver = "";
+ return "package " + pkgName + spec + ver;
+ }
+
+ private Class<?> getPackageInfo() {
+ if (packageInfo == null) {
+ try {
+ packageInfo = Class.forName(pkgName + ".package-info", false, loader);
+ } catch (ClassNotFoundException ex) {
+ // store a proxy for the package info that has no annotations
+ class PackageInfoProxy {}
+ packageInfo = PackageInfoProxy.class;
+ }
+ }
+ return packageInfo;
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
+ return getPackageInfo().getAnnotation(annotationClass);
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public boolean isAnnotationPresent(
+ Class<? extends Annotation> annotationClass) {
+ return getPackageInfo().isAnnotationPresent(annotationClass);
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getAnnotations() {
+ return getPackageInfo().getAnnotations();
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ return getPackageInfo().getDeclaredAnnotations();
+ }
+
+ /**
+ * Construct a package instance with the specified version
+ * information.
+ * @param pkgName the name of the package
+ * @param spectitle the title of the specification
+ * @param specversion the version of the specification
+ * @param specvendor the organization that maintains the specification
+ * @param impltitle the title of the implementation
+ * @param implversion the version of the implementation
+ * @param implvendor the organization that maintains the implementation
+ * @return a new package for containing the specified information.
+ */
+ Package(String name,
+ String spectitle, String specversion, String specvendor,
+ String impltitle, String implversion, String implvendor,
+ URL sealbase, ClassLoader loader)
+ {
+ pkgName = name;
+ implTitle = impltitle;
+ implVersion = implversion;
+ implVendor = implvendor;
+ specTitle = spectitle;
+ specVersion = specversion;
+ specVendor = specvendor;
+ sealBase = sealbase;
+ this.loader = loader;
+ }
+
+ /*
+ * Construct a package using the attributes from the specified manifest.
+ *
+ * @param name the package name
+ * @param man the optional manifest for the package
+ * @param url the optional code source url for the package
+ */
+ private Package(String name, Manifest man, URL url, ClassLoader loader) {
+ String path = name.replace('.', '/').concat("/");
+ String sealed = null;
+ String specTitle= null;
+ String specVersion= null;
+ String specVendor= null;
+ String implTitle= null;
+ String implVersion= null;
+ String implVendor= null;
+ URL sealBase= null;
+ Attributes attr = man.getAttributes(path);
+ if (attr != null) {
+ specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+ specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+ specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+ implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+ implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+ implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+ sealed = attr.getValue(Name.SEALED);
+ }
+ attr = man.getMainAttributes();
+ if (attr != null) {
+ if (specTitle == null) {
+ specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+ }
+ if (specVersion == null) {
+ specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+ }
+ if (specVendor == null) {
+ specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+ }
+ if (implTitle == null) {
+ implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+ }
+ if (implVersion == null) {
+ implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+ }
+ if (implVendor == null) {
+ implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+ }
+ if (sealed == null) {
+ sealed = attr.getValue(Name.SEALED);
+ }
+ }
+ if ("true".equalsIgnoreCase(sealed)) {
+ sealBase = url;
+ }
+ pkgName = name;
+ this.specTitle = specTitle;
+ this.specVersion = specVersion;
+ this.specVendor = specVendor;
+ this.implTitle = implTitle;
+ this.implVersion = implVersion;
+ this.implVendor = implVendor;
+ this.sealBase = sealBase;
+ this.loader = loader;
+ }
+
+ /*
+ * Returns the loaded system package for the specified name.
+ */
+ static Package getSystemPackage(String name) {
+ synchronized (pkgs) {
+ Package pkg = pkgs.get(name);
+ if (pkg == null) {
+ name = name.replace('.', '/').concat("/");
+ String fn = getSystemPackage0(name);
+ if (fn != null) {
+ pkg = defineSystemPackage(name, fn);
+ }
+ }
+ return pkg;
+ }
+ }
+
+ /*
+ * Return an array of loaded system packages.
+ */
+ static Package[] getSystemPackages() {
+ // First, update the system package map with new package names
+ String[] names = getSystemPackages0();
+ synchronized (pkgs) {
+ for (int i = 0; i < names.length; i++) {
+ defineSystemPackage(names[i], getSystemPackage0(names[i]));
+ }
+ return pkgs.values().toArray(new Package[pkgs.size()]);
+ }
+ }
+
+ private static Package defineSystemPackage(final String iname,
+ final String fn)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Package>() {
+ public Package run() {
+ String name = iname;
+ // Get the cached code source url for the file name
+ URL url = urls.get(fn);
+ if (url == null) {
+ // URL not found, so create one
+ File file = new File(fn);
+ try {
+ url = ParseUtil.fileToEncodedURL(file);
+ } catch (MalformedURLException e) {
+ }
+ if (url != null) {
+ urls.put(fn, url);
+ // If loading a JAR file, then also cache the manifest
+ if (file.isFile()) {
+ mans.put(fn, loadManifest(fn));
+ }
+ }
+ }
+ // Convert to "."-separated package name
+ name = name.substring(0, name.length() - 1).replace('/', '.');
+ Package pkg;
+ Manifest man = mans.get(fn);
+ if (man != null) {
+ pkg = new Package(name, man, url, null);
+ } else {
+ pkg = new Package(name, null, null, null,
+ null, null, null, null, null);
+ }
+ pkgs.put(name, pkg);
+ return pkg;
+ }
+ });
+ }
+
+ /*
+ * Returns the Manifest for the specified JAR file name.
+ */
+ private static Manifest loadManifest(String fn) {
+ try (FileInputStream fis = new FileInputStream(fn);
+ JarInputStream jis = new JarInputStream(fis, false))
+ {
+ return jis.getManifest();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ // The map of loaded system packages
+ private static Map<String, Package> pkgs = new HashMap<>(31);
+
+ // Maps each directory or zip file name to its corresponding url
+ private static Map<String, URL> urls = new HashMap<>(10);
+
+ // Maps each code source url for a jar file to its manifest
+ private static Map<String, Manifest> mans = new HashMap<>(10);
+
+ private static native String getSystemPackage0(String name);
+ private static native String[] getSystemPackages0();
+
+ /*
+ * Private storage for the package name and attributes.
+ */
+ private final String pkgName;
+ private final String specTitle;
+ private final String specVersion;
+ private final String specVendor;
+ private final String implTitle;
+ private final String implVersion;
+ private final String implVendor;
+ private final URL sealBase;
+ private transient final ClassLoader loader;
+ private transient Class packageInfo;
+}
diff --git a/external/ikvm/openjdk/java/lang/System.java b/external/ikvm/openjdk/java/lang/System.java
index e6f4d3cc02..e74187b9d3 100644
--- a/external/ikvm/openjdk/java/lang/System.java
+++ b/external/ikvm/openjdk/java/lang/System.java
@@ -33,7 +33,7 @@ import java.security.PrivilegedAction;
import java.security.AllPermission;
import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider;
-
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
@@ -1105,9 +1105,9 @@ public final class System {
* @see java.lang.Runtime#load(java.lang.String)
* @see java.lang.SecurityManager#checkLink(java.lang.String)
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public static void load(String filename) {
- Runtime.getRuntime().load0(Reflection.getCallerClass(2), filename);
+ Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
}
/**
@@ -1131,9 +1131,9 @@ public final class System {
* @see java.lang.Runtime#loadLibrary(java.lang.String)
* @see java.lang.SecurityManager#checkLink(java.lang.String)
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public static void loadLibrary(String libname) {
- Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(2), libname);
+ Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
}
/**
@@ -1160,7 +1160,6 @@ public final class System {
return "lib" + libname + ".so";
}
}
-
/* returns the class of the caller. */
static Class<?> getCallerClass() {
// NOTE use of more generic Reflection.getCallerClass()
diff --git a/external/ikvm/openjdk/java/lang/Thread.java b/external/ikvm/openjdk/java/lang/Thread.java
index 3de50ff741..e8f57d065a 100644
--- a/external/ikvm/openjdk/java/lang/Thread.java
+++ b/external/ikvm/openjdk/java/lang/Thread.java
@@ -37,6 +37,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.LockSupport;
import sun.nio.ch.Interruptible;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
@@ -169,7 +171,7 @@ class Thread implements Runnable {
private cli.System.Threading.Thread nativeThread;
private Throwable stillborn;
private boolean running; // used only for coordination with stop0(), is never set to false
- private boolean interruptPending;
+ private volatile boolean interruptPending;
private volatile boolean nativeInterruptPending;
private volatile boolean interruptableWait;
private boolean timedWait;
@@ -1228,7 +1230,12 @@ class Thread implements Runnable {
* @revised 6.0
*/
public static boolean interrupted() {
- return currentThread().isInterrupted(true);
+ Thread current = currentThread();
+ if (!current.interruptPending) {
+ return false;
+ }
+ current.interruptPending = false;
+ return true;
}
/**
@@ -1245,22 +1252,7 @@ class Thread implements Runnable {
* @revised 6.0
*/
public boolean isInterrupted() {
- return isInterrupted(false);
- }
-
- /**
- * Tests if some Thread has been interrupted. The interrupted state
- * is reset or not based on the value of ClearInterrupted that is
- * passed.
- */
- private boolean isInterrupted(boolean ClearInterrupted) {
- synchronized (lock) {
- boolean b = interruptPending;
- if (ClearInterrupted) {
- interruptPending = false;
- }
- return b;
- }
+ return interruptPending;
}
/**
@@ -1723,19 +1715,18 @@ class Thread implements Runnable {
*
* @since 1.2
*/
+ @CallerSensitive
public ClassLoader getContextClassLoader() {
if (contextClassLoader == ClassLoader.DUMMY) {
contextClassLoader = ClassLoader.getSystemClassLoader();
}
if (contextClassLoader == null)
return null;
+
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null && ccl != contextClassLoader &&
- !contextClassLoader.isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ ClassLoader.checkClassLoaderPermission(contextClassLoader,
+ Reflection.getCallerClass());
}
return contextClassLoader;
}
diff --git a/external/ikvm/openjdk/java/lang/invoke/MethodHandles.java b/external/ikvm/openjdk/java/lang/invoke/MethodHandles.java
index 710d6ab077..6f0db408fa 100644
--- a/external/ikvm/openjdk/java/lang/invoke/MethodHandles.java
+++ b/external/ikvm/openjdk/java/lang/invoke/MethodHandles.java
@@ -33,11 +33,10 @@ import sun.invoke.util.Wrapper;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
+import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
-import ikvm.internal.CallerID;
-import ikvm.internal.HasCallerID;
/**
* This class consists exclusively of static methods that operate on or return
@@ -68,9 +67,9 @@ public class MethodHandles {
* This lookup object is a <em>capability</em> which may be delegated to trusted agents.
* Do not store it in place where untrusted code can access it.
*/
- @HasCallerID
+ @CallerSensitive
public static Lookup lookup() {
- return new Lookup(CallerID.getCallerID());
+ return new Lookup(Reflection.getCallerClass());
}
/**
@@ -412,14 +411,9 @@ public class MethodHandles {
* Also, don't make it private, lest javac interpose
* an access$N method.
*/
- Lookup(CallerID caller) {
- this(caller.getCallerClass(), ALL_MODES);
- // make sure we haven't accidentally picked up a privileged class:
- checkUnprivilegedlookupClass(lookupClass);
- }
-
Lookup(Class<?> lookupClass) {
this(lookupClass, ALL_MODES);
+ checkUnprivilegedlookupClass(lookupClass);
}
private Lookup(Class<?> lookupClass, int allowedModes) {
diff --git a/external/ikvm/openjdk/java/lang/reflect/Constructor.java b/external/ikvm/openjdk/java/lang/reflect/Constructor.java
index e62e87728d..b13d30a543 100644
--- a/external/ikvm/openjdk/java/lang/reflect/Constructor.java
+++ b/external/ikvm/openjdk/java/lang/reflect/Constructor.java
@@ -25,6 +25,7 @@
package java.lang.reflect;
+import sun.reflect.CallerSensitive;
import sun.reflect.ConstructorAccessor;
import sun.reflect.Reflection;
import sun.reflect.generics.repository.ConstructorRepository;
@@ -501,15 +502,14 @@ public final
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails.
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- Class<?> caller = Reflection.getCallerClass(2);
-
+ Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers);
}
}
diff --git a/external/ikvm/openjdk/java/lang/reflect/Field.java b/external/ikvm/openjdk/java/lang/reflect/Field.java
index c796d20a1f..b2cb46b3f0 100644
--- a/external/ikvm/openjdk/java/lang/reflect/Field.java
+++ b/external/ikvm/openjdk/java/lang/reflect/Field.java
@@ -25,6 +25,7 @@
package java.lang.reflect;
+import sun.reflect.CallerSensitive;
import sun.reflect.FieldAccessor;
import sun.reflect.Reflection;
import sun.reflect.generics.repository.FieldRepository;
@@ -34,7 +35,6 @@ import sun.reflect.generics.scope.ClassScope;
import java.lang.annotation.Annotation;
import java.util.Map;
import sun.reflect.annotation.AnnotationParser;
-import ikvm.internal.CallerID;
/**
@@ -365,11 +365,16 @@ class Field extends AccessibleObject implements Member {
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails.
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Object get(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).get(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).get(obj);
}
/**
@@ -394,11 +399,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#get
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public boolean getBoolean(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).getBoolean(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).getBoolean(obj);
}
/**
@@ -423,11 +433,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#get
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public byte getByte(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).getByte(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).getByte(obj);
}
/**
@@ -454,11 +469,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#get
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public char getChar(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).getChar(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).getChar(obj);
}
/**
@@ -485,11 +505,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#get
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public short getShort(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).getShort(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).getShort(obj);
}
/**
@@ -516,11 +541,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#get
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public int getInt(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).getInt(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).getInt(obj);
}
/**
@@ -547,11 +577,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#get
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public long getLong(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).getLong(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).getLong(obj);
}
/**
@@ -578,11 +613,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#get
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public float getFloat(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).getFloat(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).getFloat(obj);
}
/**
@@ -609,11 +649,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#get
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public double getDouble(Object obj)
throws IllegalArgumentException, IllegalAccessException
{
- return getFieldAccessor(obj, CallerID.getCallerID()).getDouble(obj);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ return getFieldAccessor(obj).getDouble(obj);
}
/**
@@ -682,11 +727,16 @@ class Field extends AccessibleObject implements Member {
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails.
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).set(obj, value);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).set(obj, value);
}
/**
@@ -713,11 +763,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#set
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).setBoolean(obj, z);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).setBoolean(obj, z);
}
/**
@@ -744,11 +799,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#set
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).setByte(obj, b);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).setByte(obj, b);
}
/**
@@ -775,11 +835,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#set
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).setChar(obj, c);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).setChar(obj, c);
}
/**
@@ -806,11 +871,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#set
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).setShort(obj, s);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).setShort(obj, s);
}
/**
@@ -837,11 +907,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#set
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).setInt(obj, i);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).setInt(obj, i);
}
/**
@@ -868,11 +943,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#set
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).setLong(obj, l);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).setLong(obj, l);
}
/**
@@ -899,11 +979,16 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#set
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).setFloat(obj, f);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).setFloat(obj, f);
}
/**
@@ -930,21 +1015,25 @@ class Field extends AccessibleObject implements Member {
* by this method fails.
* @see Field#set
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
- getFieldAccessor(obj, CallerID.getCallerID()).setDouble(obj, d);
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers);
+ }
+ }
+ getFieldAccessor(obj).setDouble(obj, d);
}
- // Convenience routine which performs security checks
- private FieldAccessor getFieldAccessor(Object obj, CallerID callerID)
+ // security check is done before calling this method
+ private FieldAccessor getFieldAccessor(Object obj)
throws IllegalAccessException
{
- doSecurityCheck(obj, callerID);
boolean ov = override;
- FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor;
- return (a != null)? a : acquireFieldAccessor(ov);
+ FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
+ return (a != null) ? a : acquireFieldAccessor(ov);
}
// NOTE that there is no synchronization used here. It is correct
@@ -989,19 +1078,6 @@ class Field extends AccessibleObject implements Member {
}
}
- // NOTE: be very careful if you change the stack depth of this
- // routine. The depth of the "getCallerClass" call is hardwired so
- // that the compiler can have an easier time if this gets inlined.
- private void doSecurityCheck(Object obj, CallerID callerID) throws IllegalAccessException {
- if (!override) {
- if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- Class<?> caller = callerID.getCallerClass();
-
- checkAccess(caller, clazz, obj, modifiers);
- }
- }
- }
-
/*
* Utility routine to paper over array type names
*/
diff --git a/external/ikvm/openjdk/java/lang/reflect/Method.java b/external/ikvm/openjdk/java/lang/reflect/Method.java
index b1548d6bbe..dce789a4f1 100644
--- a/external/ikvm/openjdk/java/lang/reflect/Method.java
+++ b/external/ikvm/openjdk/java/lang/reflect/Method.java
@@ -26,6 +26,7 @@
package java.lang.reflect;
import ikvm.internal.CallerID;
+import sun.reflect.CallerSensitive;
import sun.reflect.MethodAccessor;
import sun.reflect.Reflection;
import sun.reflect.generics.repository.MethodRepository;
@@ -578,15 +579,14 @@ public final
* @exception ExceptionInInitializerError if the initialization
* provoked by this method fails.
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
- Class<?> caller = CallerID.getCallerID().getCallerClass();
-
+ Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
diff --git a/external/ikvm/openjdk/java/lang/reflect/Proxy.java b/external/ikvm/openjdk/java/lang/reflect/Proxy.java
index d4a391f738..3d9850e032 100644
--- a/external/ikvm/openjdk/java/lang/reflect/Proxy.java
+++ b/external/ikvm/openjdk/java/lang/reflect/Proxy.java
@@ -27,6 +27,9 @@ package java.lang.reflect;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -36,6 +39,10 @@ import java.util.Set;
import java.util.List;
import java.util.WeakHashMap;
import sun.misc.ProxyGenerator;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+import sun.reflect.misc.ReflectUtil;
+import sun.security.util.SecurityConstants;
/**
* {@code Proxy} provides static methods for creating dynamic proxy
@@ -265,9 +272,67 @@ public class Proxy implements java.io.Serializable {
* @param h the invocation handler for this proxy instance
*/
protected Proxy(InvocationHandler h) {
+ doNewInstanceCheck();
this.h = h;
}
+ private static class ProxyAccessHelper {
+ // The permission is implementation specific.
+ static final Permission PROXY_PERMISSION =
+ new ReflectPermission("proxyConstructorNewInstance");
+ // These system properties are defined to provide a short-term
+ // workaround if customers need to disable the new security checks.
+ static final boolean allowNewInstance;
+ static final boolean allowNullLoader;
+ static {
+ allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
+ allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
+ }
+
+ private static boolean getBooleanProperty(final String key) {
+ String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty(key);
+ }
+ });
+ return Boolean.valueOf(s);
+ }
+
+ static boolean needsNewInstanceCheck(Class<?> proxyClass) {
+ if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
+ return false;
+ }
+
+ if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
+ for (Class<?> intf : proxyClass.getInterfaces()) {
+ if (!Modifier.isPublic(intf.getModifiers())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /*
+ * Access check on a proxy class that implements any non-public interface.
+ *
+ * @throws SecurityException if a security manager exists, and
+ * the caller does not have the permission.
+ */
+ private void doNewInstanceCheck() {
+ SecurityManager sm = System.getSecurityManager();
+ Class<?> proxyClass = this.getClass();
+ if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
+ try {
+ sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
+ } catch (SecurityException e) {
+ throw new SecurityException("Not allowed to construct a Proxy "
+ + "instance that implements a non-public interface", e);
+ }
+ }
+ }
+
/**
* Returns the {@code java.lang.Class} object for a proxy class
* given a class loader and an array of interfaces. The proxy class
@@ -342,10 +407,59 @@ public class Proxy implements java.io.Serializable {
* @throws NullPointerException if the {@code interfaces} array
* argument or any of its elements are {@code null}
*/
+ @CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
+ }
+
+ return getProxyClass0(loader, interfaces);
+ }
+
+ /*
+ * Check permissions required to create a Proxy class.
+ *
+ * To define a proxy class, it performs the access checks as in
+ * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
+ * 1. "getClassLoader" permission check if loader == null
+ * 2. checkPackageAccess on the interfaces it implements
+ *
+ * To get a constructor and new instance of a proxy class, it performs
+ * the package access check on the interfaces it implements
+ * as in Class.getConstructor.
+ *
+ * If an interface is non-public, the proxy class must be defined by
+ * the defining loader of the interface. If the caller's class loader
+ * is not the same as the defining loader of the interface, the VM
+ * will throw IllegalAccessError when the generated proxy class is
+ * being defined via the defineClass0 method.
+ */
+ private static void checkProxyAccess(Class<?> caller,
+ ClassLoader loader,
+ Class<?>... interfaces)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ ClassLoader ccl = caller.getClassLoader();
+ if (loader == null && ccl != null) {
+ if (!ProxyAccessHelper.allowNullLoader) {
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ }
+ }
+ ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
+ }
+ }
+
+ /**
+ * Generate a proxy class. Must call the checkProxyAccess method
+ * to perform permission checks before calling this.
+ */
+ private static Class<?> getProxyClass0(ClassLoader loader,
+ Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
@@ -497,8 +611,9 @@ public class Proxy implements java.io.Serializable {
}
}
- if (proxyPkg == null) { // if no non-public proxy interfaces,
- proxyPkg = ""; // use the unnamed package
+ if (proxyPkg == null) {
+ // if no non-public proxy interfaces, use com.sun.proxy package
+ proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
generate: do
@@ -592,6 +707,7 @@ generate: do
* if the invocation handler, {@code h}, is
* {@code null}
*/
+ @CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
@@ -601,25 +717,50 @@ generate: do
throw new NullPointerException();
}
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
+ }
+
/*
* Look up or generate the designated proxy class.
*/
- Class<?> cl = getProxyClass(loader, interfaces);
+ Class<?> cl = getProxyClass0(loader, interfaces);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
- Constructor cons = cl.getConstructor(constructorParams);
- return cons.newInstance(new Object[] { h });
+ final Constructor<?> cons = cl.getConstructor(constructorParams);
+ final InvocationHandler ih = h;
+ if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
+ // create proxy instance with doPrivilege as the proxy class may
+ // implement non-public interfaces that requires a special permission
+ return AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ return newInstance(cons, ih);
+ }
+ });
+ } else {
+ return newInstance(cons, ih);
+ }
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
- } catch (IllegalAccessException e) {
- throw new InternalError(e.toString());
- } catch (InstantiationException e) {
+ }
+ }
+
+ private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
+ try {
+ return cons.newInstance(new Object[] {h} );
+ } catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString());
} catch (InvocationTargetException e) {
- throw new InternalError(e.toString());
+ Throwable t = e.getCause();
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ } else {
+ throw new InternalError(t.toString());
+ }
}
}