author | redestad |
Tue, 11 Apr 2017 18:57:46 +0200 | |
changeset 44591 | b9bf065070fe |
parent 43712 | 5dfd0950317c |
child 44599 | 942f3546b679 |
permissions | -rw-r--r-- |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
1 |
/* |
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
2 |
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
4 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
5 |
* This code is free software; you can redistribute it and/or modify it |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
10 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
15 |
* accompanied this code). |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
16 |
* |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License version |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
20 |
* |
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
24 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
25 |
|
8822
8145ab9f5f86
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
8821
diff
changeset
|
26 |
package sun.invoke.util; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
27 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
28 |
import java.lang.reflect.Modifier; |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
29 |
import static java.lang.reflect.Modifier.*; |
36511 | 30 |
import java.lang.reflect.Module; |
40272
6af4511ee5a4
8163878: Remove unnecessary bridge methods, allocations in java.lang.invoke
redestad
parents:
37585
diff
changeset
|
31 |
import java.util.Objects; |
37363
329dba26ffd2
8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents:
36511
diff
changeset
|
32 |
import jdk.internal.reflect.Reflection; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
33 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
34 |
/** |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
35 |
* This class centralizes information about the JVM's linkage access control. |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
36 |
* @author jrose |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
37 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
38 |
public class VerifyAccess { |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
39 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
40 |
private VerifyAccess() { } // cannot instantiate |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
41 |
|
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
42 |
private static final int UNCONDITIONAL_ALLOWED = java.lang.invoke.MethodHandles.Lookup.UNCONDITIONAL; |
36511 | 43 |
private static final int MODULE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.MODULE; |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
44 |
private static final int PACKAGE_ONLY = 0; |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
45 |
private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE; |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
46 |
private static final int PROTECTED_OR_PACKAGE_ALLOWED = (PACKAGE_ALLOWED|PROTECTED); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
47 |
private static final int ALL_ACCESS_MODES = (PUBLIC|PRIVATE|PROTECTED|PACKAGE_ONLY); |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
5725
diff
changeset
|
48 |
private static final boolean ALLOW_NESTMATE_ACCESS = false; |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
49 |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
50 |
/** |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
51 |
* Evaluate the JVM linkage rules for access to the given method |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
52 |
* on behalf of a caller class which proposes to perform the access. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
53 |
* Return true if the caller class has privileges to invoke a method |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
54 |
* or access a field with the given properties. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
55 |
* This requires an accessibility check of the referencing class, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
56 |
* plus an accessibility check of the member within the class, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
57 |
* which depends on the member's modifier flags. |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
58 |
* <p> |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
59 |
* The relevant properties include the defining class ({@code defc}) |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
60 |
* of the member, and its modifier flags ({@code mods}). |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
61 |
* Also relevant is the class used to make the initial symbolic reference |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
62 |
* to the member ({@code refc}). If this latter class is not distinguished, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
63 |
* the defining class should be passed for both arguments ({@code defc == refc}). |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
64 |
* <h3>JVM Specification, 5.4.4 "Access Control"</h3> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
65 |
* A field or method R is accessible to a class or interface D if |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
66 |
* and only if any of the following conditions is true:<ul> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
67 |
* <li>R is public. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
68 |
* <li>R is protected and is declared in a class C, and D is either |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
69 |
* a subclass of C or C itself. Furthermore, if R is not |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
70 |
* static, then the symbolic reference to R must contain a |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
71 |
* symbolic reference to a class T, such that T is either a |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
72 |
* subclass of D, a superclass of D or D itself. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
73 |
* <li>R is either protected or has default access (that is, |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
74 |
* neither public nor protected nor private), and is declared |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
75 |
* by a class in the same runtime package as D. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
76 |
* <li>R is private and is declared in D. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
77 |
* </ul> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
78 |
* This discussion of access control omits a related restriction |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
79 |
* on the target of a protected field access or method invocation |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
80 |
* (the target must be of class D or a subtype of D). That |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
81 |
* requirement is checked as part of the verification process |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
82 |
* (5.4.1); it is not part of link-time access control. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
83 |
* @param refc the class used in the symbolic reference to the proposed member |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
84 |
* @param defc the class in which the proposed member is actually defined |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
85 |
* @param mods modifier flags for the proposed member |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
86 |
* @param lookupClass the class for which the access check is being made |
28059
e576535359cc
8067377: My hobby: caning, then then canning, the the can-can
martin
parents:
27070
diff
changeset
|
87 |
* @return true iff the accessing class can access such a member |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
88 |
*/ |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
89 |
public static boolean isMemberAccessible(Class<?> refc, // symbolic ref class |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
90 |
Class<?> defc, // actual def class |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
91 |
int mods, // actual member mods |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
92 |
Class<?> lookupClass, |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
93 |
int allowedModes) { |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
94 |
if (allowedModes == 0) return false; |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
95 |
assert((allowedModes & PUBLIC) != 0 && |
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
96 |
(allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0); |
23022
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
97 |
// The symbolic reference class (refc) must always be fully verified. |
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
98 |
if (!isClassAccessible(refc, lookupClass, allowedModes)) { |
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
99 |
return false; |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
100 |
} |
23022
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
101 |
// Usually refc and defc are the same, but verify defc also in case they differ. |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
102 |
if (defc == lookupClass && |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
103 |
(allowedModes & PRIVATE) != 0) |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
5725
diff
changeset
|
104 |
return true; // easy check; all self-access is OK |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
105 |
switch (mods & ALL_ACCESS_MODES) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
106 |
case PUBLIC: |
23022
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
107 |
return true; // already checked above |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
108 |
case PROTECTED: |
27070
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
109 |
assert !defc.isInterface(); // protected members aren't allowed in interfaces |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
110 |
if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 && |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
111 |
isSamePackage(defc, lookupClass)) |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
112 |
return true; |
23022
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
113 |
if ((allowedModes & PROTECTED) == 0) |
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
114 |
return false; |
27070
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
115 |
// Protected members are accessible by subclasses, which does not include interfaces. |
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
116 |
// Interfaces are types, not classes. They should not have access to |
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
117 |
// protected members in j.l.Object, even though it is their superclass. |
23022
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
118 |
if ((mods & STATIC) != 0 && |
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
119 |
!isRelatedClass(refc, lookupClass)) |
ede1afdc49a2
8032585: JSR292: IllegalAccessError when attempting to invoke protected method from different package
vlivanov
parents:
20872
diff
changeset
|
120 |
return false; |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
121 |
if ((allowedModes & PROTECTED) != 0 && |
27070
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
122 |
isSubClass(lookupClass, defc)) |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
123 |
return true; |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
124 |
return false; |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
125 |
case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. |
27070
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
126 |
assert !defc.isInterface(); // package-private members aren't allowed in interfaces |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
127 |
return ((allowedModes & PACKAGE_ALLOWED) != 0 && |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
128 |
isSamePackage(defc, lookupClass)); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
129 |
case PRIVATE: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
130 |
// Loosened rules for privates follows access rules for inner classes. |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
5725
diff
changeset
|
131 |
return (ALLOW_NESTMATE_ACCESS && |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
132 |
(allowedModes & PRIVATE) != 0 && |
7555
a279ebc3b25c
6981777: implement JSR 292 EG adjustments from summer 2010
jrose
parents:
5725
diff
changeset
|
133 |
isSamePackageMember(defc, lookupClass)); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
134 |
default: |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
135 |
throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods)); |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
136 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
137 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
138 |
|
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
139 |
static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) { |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
140 |
return (refc == lookupClass || |
27070
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
141 |
isSubClass(refc, lookupClass) || |
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
142 |
isSubClass(lookupClass, refc)); |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
143 |
} |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
144 |
|
27070
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
145 |
static boolean isSubClass(Class<?> lookupClass, Class<?> defc) { |
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
146 |
return defc.isAssignableFrom(lookupClass) && |
55b657214bb9
8037326: VerifyAccess.isMemberAccessible() has incorrect access check
vlivanov
parents:
25859
diff
changeset
|
147 |
!lookupClass.isInterface(); // interfaces are types, not classes. |
20872
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
148 |
} |
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
149 |
|
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
150 |
static int getClassModifiers(Class<?> c) { |
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
151 |
// This would return the mask stored by javac for the source-level modifiers. |
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
152 |
// return c.getModifiers(); |
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
153 |
// But what we need for JVM access checks are the actual bits from the class header. |
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
154 |
// ...But arrays and primitives are synthesized with their own odd flags: |
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
155 |
if (c.isArray() || c.isPrimitive()) |
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
156 |
return c.getModifiers(); |
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
157 |
return Reflection.getClassAccessFlags(c); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
158 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
159 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
160 |
/** |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
161 |
* Evaluate the JVM linkage rules for access to the given class on behalf of caller. |
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
162 |
* <h3>JVM Specification, 5.4.4 "Access Control"</h3> |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
163 |
* A class or interface C is accessible to a class or interface D |
36511 | 164 |
* if and only if any of the following conditions are true:<ul> |
165 |
* <li>C is public and in the same module as D. |
|
166 |
* <li>D is in a module that reads the module containing C, C is public and in a |
|
167 |
* package that is exported to the module that contains D. |
|
5722
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
168 |
* <li>C and D are members of the same runtime package. |
4ada807383c8
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
4537
diff
changeset
|
169 |
* </ul> |
8347
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
7668
diff
changeset
|
170 |
* @param refc the symbolic reference class to which access is being checked (C) |
e5daa5772ffd
7013730: JSR 292 reflective operations should report errors with standard exception types
jrose
parents:
7668
diff
changeset
|
171 |
* @param lookupClass the class performing the lookup (D) |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
172 |
*/ |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
173 |
public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass, |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
174 |
int allowedModes) { |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
175 |
if (allowedModes == 0) return false; |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
176 |
assert((allowedModes & PUBLIC) != 0 && |
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
177 |
(allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0); |
20872
8e486b70dff8
8022718: Runtime accessibility checking: protected class, if extended, should be accessible from another package
drchase
parents:
20535
diff
changeset
|
178 |
int mods = getClassModifiers(refc); |
36511 | 179 |
if (isPublic(mods)) { |
180 |
||
181 |
Module lookupModule = lookupClass.getModule(); |
|
182 |
Module refModule = refc.getModule(); |
|
183 |
||
184 |
// early VM startup case, java.base not defined |
|
185 |
if (lookupModule == null) { |
|
186 |
assert refModule == null; |
|
187 |
return true; |
|
188 |
} |
|
189 |
||
190 |
// trivially allow |
|
191 |
if ((allowedModes & MODULE_ALLOWED) != 0 && |
|
192 |
(lookupModule == refModule)) |
|
193 |
return true; |
|
194 |
||
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
195 |
// check readability when UNCONDITIONAL not allowed |
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
196 |
if (((allowedModes & UNCONDITIONAL_ALLOWED) != 0) |
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
197 |
|| lookupModule.canRead(refModule)) { |
36511 | 198 |
|
199 |
// check that refc is in an exported package |
|
200 |
if ((allowedModes & MODULE_ALLOWED) != 0) { |
|
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
201 |
if (refModule.isExported(refc.getPackageName(), lookupModule)) |
36511 | 202 |
return true; |
203 |
} else { |
|
204 |
// exported unconditionally |
|
43712
5dfd0950317c
8173393: Module system implementation refresh (2/2017)
alanb
parents:
40272
diff
changeset
|
205 |
if (refModule.isExported(refc.getPackageName())) |
36511 | 206 |
return true; |
207 |
} |
|
208 |
||
209 |
// not exported but allow access during VM initialization |
|
210 |
// because java.base does not have its exports setup |
|
211 |
if (!jdk.internal.misc.VM.isModuleSystemInited()) |
|
212 |
return true; |
|
213 |
} |
|
214 |
||
215 |
// public class not accessible to lookupClass |
|
216 |
return false; |
|
217 |
} |
|
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
218 |
if ((allowedModes & PACKAGE_ALLOWED) != 0 && |
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
219 |
isSamePackage(lookupClass, refc)) |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
220 |
return true; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
221 |
return false; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
222 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
223 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
224 |
/** |
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
225 |
* Decide if the given method type, attributed to a member or symbolic |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
226 |
* reference of a given reference class, is really visible to that class. |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
227 |
* @param type the supposed type of a member or symbolic reference of refc |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
14342
diff
changeset
|
228 |
* @param refc the class attempting to make the reference |
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
229 |
*/ |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
230 |
public static boolean isTypeVisible(Class<?> type, Class<?> refc) { |
37585 | 231 |
if (type == refc) { |
232 |
return true; // easy check |
|
233 |
} |
|
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
234 |
while (type.isArray()) type = type.getComponentType(); |
37585 | 235 |
if (type.isPrimitive() || type == Object.class) { |
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
236 |
return true; |
37585 | 237 |
} |
238 |
ClassLoader typeLoader = type.getClassLoader(); |
|
239 |
ClassLoader refcLoader = refc.getClassLoader(); |
|
240 |
if (typeLoader == refcLoader) { |
|
241 |
return true; |
|
242 |
} |
|
243 |
if (refcLoader == null && typeLoader != null) { |
|
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
244 |
return false; |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
245 |
} |
37585 | 246 |
if (typeLoader == null && type.getName().startsWith("java.")) { |
247 |
// Note: The API for actually loading classes, ClassLoader.defineClass, |
|
248 |
// guarantees that classes with names beginning "java." cannot be aliased, |
|
249 |
// because class loaders cannot load them directly. |
|
250 |
return true; |
|
251 |
} |
|
252 |
||
253 |
// Do it the hard way: Look up the type name from the refc loader. |
|
254 |
// |
|
255 |
// Force the refc loader to report and commit to a particular binding for this type name (type.getName()). |
|
256 |
// |
|
257 |
// In principle, this query might force the loader to load some unrelated class, |
|
258 |
// which would cause this query to fail (and the original caller to give up). |
|
259 |
// This would be wasted effort, but it is expected to be very rare, occurring |
|
260 |
// only when an attacker is attempting to create a type alias. |
|
261 |
// In the normal case, one class loader will simply delegate to the other, |
|
262 |
// and the same type will be visible through both, with no extra loading. |
|
263 |
// |
|
264 |
// It is important to go through Class.forName instead of ClassLoader.loadClass |
|
265 |
// because Class.forName goes through the JVM system dictionary, which records |
|
266 |
// the class lookup once for all. This means that even if a not-well-behaved class loader |
|
267 |
// would "change its mind" about the meaning of the name, the Class.forName request |
|
268 |
// will use the result cached in the JVM system dictionary. Note that the JVM system dictionary |
|
269 |
// will record the first successful result. Unsuccessful results are not stored. |
|
270 |
// |
|
271 |
// We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary |
|
272 |
// class loader about the binding of the proposed name (type.getName()). |
|
273 |
// The looked up type ("res") is compared for equality against the proposed |
|
274 |
// type ("type") and then is discarded. Thus, the worst that can happen to |
|
275 |
// the "child" class loader is that it is bothered to load and report a class |
|
276 |
// that differs from "type"; this happens once due to JVM system dictionary |
|
277 |
// memoization. And the caller never gets to look at the alternate type binding |
|
278 |
// ("res"), whether it exists or not. |
|
279 |
final String name = type.getName(); |
|
280 |
Class<?> res = java.security.AccessController.doPrivileged( |
|
281 |
new java.security.PrivilegedAction<>() { |
|
282 |
public Class<?> run() { |
|
283 |
try { |
|
284 |
return Class.forName(name, false, refcLoader); |
|
285 |
} catch (ClassNotFoundException | LinkageError e) { |
|
286 |
return null; // Assume the class is not found |
|
287 |
} |
|
288 |
} |
|
289 |
}); |
|
290 |
return (type == res); |
|
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
291 |
} |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
292 |
|
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
293 |
/** |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
294 |
* Decide if the given method type, attributed to a member or symbolic |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
295 |
* reference of a given reference class, is really visible to that class. |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
296 |
* @param type the supposed type of a member or symbolic reference of refc |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
14342
diff
changeset
|
297 |
* @param refc the class attempting to make the reference |
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
298 |
*/ |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
299 |
public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class<?> refc) { |
44591
b9bf065070fe
8178387: Reduce memory churn when creating java.lang.invoke entities
redestad
parents:
43712
diff
changeset
|
300 |
if (!isTypeVisible(type.returnType(), refc)) { |
b9bf065070fe
8178387: Reduce memory churn when creating java.lang.invoke entities
redestad
parents:
43712
diff
changeset
|
301 |
return false; |
b9bf065070fe
8178387: Reduce memory churn when creating java.lang.invoke entities
redestad
parents:
43712
diff
changeset
|
302 |
} |
b9bf065070fe
8178387: Reduce memory churn when creating java.lang.invoke entities
redestad
parents:
43712
diff
changeset
|
303 |
for (int n = 0, max = type.parameterCount(); n < max; n++) { |
b9bf065070fe
8178387: Reduce memory churn when creating java.lang.invoke entities
redestad
parents:
43712
diff
changeset
|
304 |
if (!isTypeVisible(type.parameterType(n), refc)) { |
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
305 |
return false; |
44591
b9bf065070fe
8178387: Reduce memory churn when creating java.lang.invoke entities
redestad
parents:
43712
diff
changeset
|
306 |
} |
13423
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
307 |
} |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
308 |
return true; |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
309 |
} |
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
310 |
|
17843fff200d
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
13044
diff
changeset
|
311 |
/** |
36511 | 312 |
* Tests if two classes are in the same module. |
313 |
* @param class1 a class |
|
314 |
* @param class2 another class |
|
315 |
* @return whether they are in the same module |
|
316 |
*/ |
|
317 |
public static boolean isSameModule(Class<?> class1, Class<?> class2) { |
|
318 |
return class1.getModule() == class2.getModule(); |
|
319 |
} |
|
320 |
||
321 |
/** |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
322 |
* Test if two classes have the same class loader and package qualifier. |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
14342
diff
changeset
|
323 |
* @param class1 a class |
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
14342
diff
changeset
|
324 |
* @param class2 another class |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
325 |
* @return whether they are in the same package |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
326 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
327 |
public static boolean isSamePackage(Class<?> class1, Class<?> class2) { |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
328 |
assert(!class1.isArray() && !class2.isArray()); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
329 |
if (class1 == class2) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
330 |
return true; |
13044
8411854afc2b
7165628: Issues with java.lang.invoke.MethodHandles.Lookup
jrose
parents:
9752
diff
changeset
|
331 |
if (class1.getClassLoader() != class2.getClassLoader()) |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
332 |
return false; |
40272
6af4511ee5a4
8163878: Remove unnecessary bridge methods, allocations in java.lang.invoke
redestad
parents:
37585
diff
changeset
|
333 |
return Objects.equals(class1.getPackageName(), class2.getPackageName()); |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
334 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
335 |
|
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
336 |
/** Return the package name for this class. |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
337 |
*/ |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
338 |
public static String getPackageName(Class<?> cls) { |
36511 | 339 |
assert (!cls.isArray()); |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
340 |
String name = cls.getName(); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
341 |
int dot = name.lastIndexOf('.'); |
36511 | 342 |
if (dot < 0) return ""; |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
343 |
return name.substring(0, dot); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
344 |
} |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
345 |
|
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
346 |
/** |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
347 |
* Test if two classes are defined as part of the same package member (top-level class). |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
348 |
* If this is true, they can share private access with each other. |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
14342
diff
changeset
|
349 |
* @param class1 a class |
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
14342
diff
changeset
|
350 |
* @param class2 another class |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
351 |
* @return whether they are identical or nested together |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
352 |
*/ |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
353 |
public static boolean isSamePackageMember(Class<?> class1, Class<?> class2) { |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
354 |
if (class1 == class2) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
355 |
return true; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
356 |
if (!isSamePackage(class1, class2)) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
357 |
return false; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
358 |
if (getOutermostEnclosingClass(class1) != getOutermostEnclosingClass(class2)) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
359 |
return false; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
360 |
return true; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
361 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
362 |
|
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
363 |
private static Class<?> getOutermostEnclosingClass(Class<?> c) { |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
364 |
Class<?> pkgmem = c; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
365 |
for (Class<?> enc = c; (enc = enc.getEnclosingClass()) != null; ) |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
366 |
pkgmem = enc; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
367 |
return pkgmem; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
368 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
369 |
|
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
370 |
private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2, |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
371 |
boolean loader1MustBeParent) { |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
372 |
if (loader1 == loader2 || loader1 == null |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
373 |
|| (loader2 == null && !loader1MustBeParent)) { |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
374 |
return true; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
375 |
} |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
376 |
for (ClassLoader scan2 = loader2; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
377 |
scan2 != null; scan2 = scan2.getParent()) { |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
378 |
if (scan2 == loader1) return true; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
379 |
} |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
380 |
if (loader1MustBeParent) return false; |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
381 |
// see if loader2 is a parent of loader1: |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
382 |
for (ClassLoader scan1 = loader1; |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
383 |
scan1 != null; scan1 = scan1.getParent()) { |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
384 |
if (scan1 == loader2) return true; |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
385 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
386 |
return false; |
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
387 |
} |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
388 |
|
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
389 |
/** |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
390 |
* Is the class loader of parentClass identical to, or an ancestor of, |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
391 |
* the class loader of childClass? |
20535
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
14342
diff
changeset
|
392 |
* @param parentClass a class |
cc85c8626435
8024438: JSR 292 API specification maintenance for JDK 8
jrose
parents:
14342
diff
changeset
|
393 |
* @param childClass another class, which may be a descendent of the first class |
9752
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
394 |
* @return whether parentClass precedes or equals childClass in class loader order |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
395 |
*/ |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
396 |
public static boolean classLoaderIsAncestor(Class<?> parentClass, Class<?> childClass) { |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
397 |
return loadersAreRelated(parentClass.getClassLoader(), childClass.getClassLoader(), true); |
88ab34b6da6d
7032323: code changes for JSR 292 EG adjustments to API, through Public Review
jrose
parents:
8822
diff
changeset
|
398 |
} |
2707
5a17df307cbc
6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff
changeset
|
399 |
} |