< prev index next >
src/java.base/share/classes/java/lang/Class.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2018, 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
@@ -3853,30 +3853,44 @@
* is a member of the nest consisting only of itself, and is the
* nest host. Every class and interface is a member of exactly one nest.
*
* @return the nest host of this class, or {@code this} if we cannot
* obtain a valid nest host
- *
+ * @throws SecurityException
+ * If the returned class is not the current class, and
+ * if a security manager, <i>s</i>, is present and the caller's
+ * class loader is not the same as or an ancestor of the class
+ * loader for the returned class and invocation of {@link
+ * SecurityManager#checkPackageAccess s.checkPackageAccess()}
+ * denies access to the package of the returned class
* @since 11
*/
+ @CallerSensitive
public Class<?> getNestHost() {
if (isPrimitive() || isArray()) {
return this;
}
+ Class<?> host;
try {
- Class<?> host = getNestHost0();
- // if null then nest membership validation failed, so we
- // act as-if we have no nest-host
- if (host == null) {
- host = this;
- }
- return host;
+ host = getNestHost0();
} catch (LinkageError e) {
// if we couldn't load our nest-host then we
- // again act as-if we have no nest-host
+ // act as-if we have no nest-host
return this;
}
+ // if null then nest membership validation failed, so we
+ // act as-if we have no nest-host
+ if (host == null || host == this) {
+ return this;
+ }
+ // returning a different class requires a security check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkPackageAccess(sm,
+ ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
+ }
+ return host;
}
/**
* Determines if the given {@code Class} is a nestmate of the
* object represented by this {@code Class}. Two classes are nestmates
@@ -3887,23 +3901,31 @@
* nest; and {@code false} otherwise.
*
* @since 11
*/
public boolean isNestmateOf(Class<?> c) {
- // We could use Reflection.areNestmates(this, c) and ignore
- // any IllegalAccessError, but prefer to minimize exception
- // creation by using getNestHost() directly.
- return getNestHost() == c.getNestHost();
+ if (this == c) {
+ return true;
+ }
+ if (isPrimitive() || isArray() ||
+ c.isPrimitive() || c.isArray()) {
+ return false;
+ }
+ try {
+ return getNestHost0() == c.getNestHost0();
+ } catch (LinkageError e) {
+ return false;
+ }
}
private native Class<?>[] getNestMembers0();
/**
* Returns an array containing {@code Class} objects representing all the
* classes and interfaces that are declared in the
* {@linkplain #getNestHost() nest host} of this class, as being members
- * of its nest. The nest host will always be the zeroeth element.
+ * of its nest. The nest host will always be the zeroth element.
*
* <p>Each listed nest member must be validated by checking its own
* declared nest host. Any exceptions that occur as part of this process
* will be thrown.
*
@@ -3915,17 +3937,39 @@
* are present.
*
* @return an array of all classes and interfaces in the same nest as
* this class
*
- * @throws LinkageError if there is any problem loading or validating
- * a nest member or its nest host
+ * @throws LinkageError
+ * If there is any problem loading or validating a nest member or
+ * its nest host
+ * @throws SecurityException
+ * If any returned class is not the current class, and
+ * if a security manager, <i>s</i>, is present and the caller's
+ * class loader is not the same as or an ancestor of the class
+ * loader for that returned class and invocation of {@link
+ * SecurityManager#checkPackageAccess s.checkPackageAccess()}
+ * denies access to the package of that returned class
*
* @since 11
*/
+ @CallerSensitive
public Class<?>[] getNestMembers() {
if (isPrimitive() || isArray()) {
return new Class<?>[] { this };
}
- return getNestMembers0();
+ Class<?>[] members = getNestMembers0();
+ // Can't actually enable this due to bootstrapping issues
+ // assert(members.length != 1 || members[0] == this); // expected invariant from VM
+
+ if (members.length > 1) {
+ // If we return anything other than the current class we need
+ // a security check
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkPackageAccess(sm,
+ ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
+ }
+ }
+ return members;
}
}
< prev index next >