< prev index next > test/jdk/java/lang/invoke/callerSensitive/CallerSensitiveAccess.java
Print this page
/*
! * Copyright (c) 2018, 2021, 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.
/*
! * Copyright (c) 2018, 2024, 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.
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
! * @bug 8196830 8235351 8257874
* @modules java.base/jdk.internal.reflect
* @run testng/othervm CallerSensitiveAccess
* @summary Check Lookup findVirtual, findStatic and unreflect behavior with
* caller sensitive methods with focus on AccessibleObject.setAccessible
*/
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
! * @bug 8196830 8235351 8257874 8327639
* @modules java.base/jdk.internal.reflect
* @run testng/othervm CallerSensitiveAccess
* @summary Check Lookup findVirtual, findStatic and unreflect behavior with
* caller sensitive methods with focus on AccessibleObject.setAccessible
*/
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.reflect.CallerSensitive;
import org.testng.annotations.DataProvider;
import org.testng.annotations.NoInjection;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class CallerSensitiveAccess {
/**
* Caller sensitive methods in APIs exported by java.base.
*/
@DataProvider(name = "callerSensitiveMethods")
static Object[][] callerSensitiveMethods() {
! try (Stream<Method> stream = callerSensitiveMethods(Object.class.getModule())) {
! return stream.map(m -> new Object[]{m, shortDescription(m)})
! .toArray(Object[][]::new);
- }
}
/**
* Using publicLookup, attempt to use findVirtual or findStatic to obtain a
* method handle to a caller sensitive method.
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.reflect.CallerSensitive;
+ import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.NoInjection;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class CallerSensitiveAccess {
+ // Cache the list of Caller Sensitive Methods
+ private static List<Method> CALLER_SENSITIVE_METHODS;
+
+ @BeforeClass
+ private void setupCallerSensitiveMethods() {
+ CALLER_SENSITIVE_METHODS = callerSensitiveMethods(Object.class.getModule());
+ }
/**
* Caller sensitive methods in APIs exported by java.base.
*/
@DataProvider(name = "callerSensitiveMethods")
static Object[][] callerSensitiveMethods() {
! return CALLER_SENSITIVE_METHODS.stream()
! .map(m -> new Object[]{m, shortDescription(m)})
! .toArray(Object[][]::new);
}
/**
* Using publicLookup, attempt to use findVirtual or findStatic to obtain a
* method handle to a caller sensitive method.
/**
* public accessible caller sensitive methods in APIs exported by java.base.
*/
@DataProvider(name = "accessibleCallerSensitiveMethods")
static Object[][] accessibleCallerSensitiveMethods() {
! try (Stream<Method> stream = callerSensitiveMethods(Object.class.getModule())) {
- return stream
.filter(m -> Modifier.isPublic(m.getModifiers()))
.map(m -> { m.setAccessible(true); return m; })
.map(m -> new Object[] { m, shortDescription(m) })
.toArray(Object[][]::new);
- }
}
/**
* Using publicLookup, attempt to use unreflect to obtain a method handle to a
* caller sensitive method.
/**
* public accessible caller sensitive methods in APIs exported by java.base.
*/
@DataProvider(name = "accessibleCallerSensitiveMethods")
static Object[][] accessibleCallerSensitiveMethods() {
! return CALLER_SENSITIVE_METHODS.stream()
.filter(m -> Modifier.isPublic(m.getModifiers()))
.map(m -> { m.setAccessible(true); return m; })
.map(m -> new Object[] { m, shortDescription(m) })
.toArray(Object[][]::new);
}
/**
* Using publicLookup, attempt to use unreflect to obtain a method handle to a
* caller sensitive method.
}
// -- supporting methods --
/**
! * Returns a stream of all caller sensitive methods on public classes in packages
* exported by a named module.
*/
! static Stream<Method> callerSensitiveMethods(Module module) {
assert module.isNamed();
ModuleReference mref = module.getLayer().configuration()
.findModule(module.getName())
.orElseThrow(() -> new RuntimeException())
.reference();
}
// -- supporting methods --
/**
! * Returns a List of all caller sensitive methods on public classes in packages
* exported by a named module.
+ * Returns a List instead of a stream so the ModuleReader can be closed before returning.
*/
! static List<Method> callerSensitiveMethods(Module module) {
assert module.isNamed();
ModuleReference mref = module.getLayer().configuration()
.findModule(module.getName())
.orElseThrow(() -> new RuntimeException())
.reference();
.filter(cn -> module.isExported(packageName(cn)))
.map(cn -> Class.forName(module, cn))
.filter(refc -> refc != null
&& Modifier.isPublic(refc.getModifiers()))
.map(refc -> callerSensitiveMethods(refc))
! .flatMap(List::stream);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
.filter(cn -> module.isExported(packageName(cn)))
.map(cn -> Class.forName(module, cn))
.filter(refc -> refc != null
&& Modifier.isPublic(refc.getModifiers()))
.map(refc -> callerSensitiveMethods(refc))
! .flatMap(List::stream).toList();
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
< prev index next >