< prev index next >
test/jdk/java/lang/invoke/VarHandles/accessibility/TestFieldLookupAccessibility.java
Print this page
*** 20,30 ****
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
! * @bug 8152645
* @summary test field lookup accessibility of MethodHandles and VarHandles
* @compile TestFieldLookupAccessibility.java
* pkg/A.java pkg/B_extends_A.java pkg/C.java
* pkg/subpkg/B_extends_A.java pkg/subpkg/C.java
* @run testng/othervm TestFieldLookupAccessibility
--- 20,30 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
! * @bug 8152645 8216558
* @summary test field lookup accessibility of MethodHandles and VarHandles
* @compile TestFieldLookupAccessibility.java
* pkg/A.java pkg/B_extends_A.java pkg/C.java
* pkg/subpkg/B_extends_A.java pkg/subpkg/C.java
* @run testng/othervm TestFieldLookupAccessibility
*** 94,117 ****
},
MH_UNREFLECT_GETTER_ACCESSIBLE() {
Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
return l.unreflectGetter(cloneAndSetAccessible(f));
}
},
MH_UNREFLECT_SETTER() {
Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
return l.unreflectSetter(f);
}
boolean isAccessible(Field f) {
! return f.isAccessible() || !Modifier.isFinal(f.getModifiers());
}
},
MH_UNREFLECT_SETTER_ACCESSIBLE() {
Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
return l.unreflectSetter(cloneAndSetAccessible(f));
}
},
VH() {
Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
return l.findVarHandle(f.getDeclaringClass(), f.getName(), f.getType());
}
--- 94,137 ----
},
MH_UNREFLECT_GETTER_ACCESSIBLE() {
Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
return l.unreflectGetter(cloneAndSetAccessible(f));
}
+
+ // Setting the accessibility bit of a Field grants access under
+ // all conditions for MethodHandle getters.
+ Set<String> inaccessibleFields(Set<String> inaccessibleFields) {
+ return new HashSet<>();
+ }
},
MH_UNREFLECT_SETTER() {
Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
return l.unreflectSetter(f);
}
boolean isAccessible(Field f) {
! return f.isAccessible() && !Modifier.isStatic(f.getModifiers()) || !Modifier.isFinal(f.getModifiers());
}
},
MH_UNREFLECT_SETTER_ACCESSIBLE() {
Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
return l.unreflectSetter(cloneAndSetAccessible(f));
}
+
+ boolean isAccessible(Field f) {
+ return !(Modifier.isStatic(f.getModifiers()) && Modifier.isFinal(f.getModifiers()));
+ }
+
+ // Setting the accessibility bit of a Field grants access to non-static
+ // final fields for MethodHandle setters.
+ Set<String> inaccessibleFields(Set<String>inaccessibleFields) {
+ Set<String> result = new HashSet<>();
+ inaccessibleFields.stream()
+ .filter(f -> (f.contains("static") && f.contains("final")))
+ .forEach(result::add);
+ return result;
+ }
},
VH() {
Object lookup(MethodHandles.Lookup l, Field f) throws Exception {
return l.findVarHandle(f.getDeclaringClass(), f.getName(), f.getType());
}
*** 140,149 ****
--- 160,173 ----
boolean isAccessible(Field f) {
return true;
}
+ Set<String> inaccessibleFields(Set<String> inaccessibleFields) {
+ return new HashSet<>(inaccessibleFields);
+ }
+
static Field cloneAndSetAccessible(Field f) throws Exception {
// Clone to avoid mutating source field
f = f.getDeclaringClass().getDeclaredField(f.getName());
f.setAccessible(true);
return f;
*** 178,188 ****
}
@Test(dataProvider = "lookupProvider")
public void test(FieldLookup fl, Class<?> src, MethodHandles.Lookup l, Set<String> inaccessibleFields) {
// Add to the expected failures all inaccessible fields due to accessibility modifiers
! Set<String> expected = new HashSet<>(inaccessibleFields);
Map<Field, Throwable> actual = new HashMap<>();
for (Field f : fields(src)) {
// Add to the expected failures all inaccessible fields due to static/final modifiers
if (!fl.isAccessible(f)) {
--- 202,212 ----
}
@Test(dataProvider = "lookupProvider")
public void test(FieldLookup fl, Class<?> src, MethodHandles.Lookup l, Set<String> inaccessibleFields) {
// Add to the expected failures all inaccessible fields due to accessibility modifiers
! Set<String> expected = fl.inaccessibleFields(inaccessibleFields);
Map<Field, Throwable> actual = new HashMap<>();
for (Field f : fields(src)) {
// Add to the expected failures all inaccessible fields due to static/final modifiers
if (!fl.isAccessible(f)) {
*** 201,216 ****
Set<String> actualFieldNames = actual.keySet().stream().map(Field::getName).
collect(Collectors.toSet());
if (!actualFieldNames.equals(expected)) {
if (actualFieldNames.isEmpty()) {
// Setting the accessibility bit of a Field grants access under
! // all conditions for MethodHander getters and setters
! if (fl != FieldLookup.MH_UNREFLECT_GETTER_ACCESSIBLE &&
! fl != FieldLookup.MH_UNREFLECT_SETTER_ACCESSIBLE) {
Assert.assertEquals(actualFieldNames, expected, "No accessibility failures:");
}
- }
else {
Assert.assertEquals(actualFieldNames, expected, "Accessibility failures differ:");
}
}
else {
--- 225,237 ----
Set<String> actualFieldNames = actual.keySet().stream().map(Field::getName).
collect(Collectors.toSet());
if (!actualFieldNames.equals(expected)) {
if (actualFieldNames.isEmpty()) {
// Setting the accessibility bit of a Field grants access under
! // all conditions for MethodHandle getters
Assert.assertEquals(actualFieldNames, expected, "No accessibility failures:");
}
else {
Assert.assertEquals(actualFieldNames, expected, "Accessibility failures differ:");
}
}
else {
< prev index next >