Skip to content

Commit 11eebe7

Browse files
author
CHENGJin
committed
A MethodHandles API privateLookupIn
The code is to introduce a new API called privateLookupIn to produce a lookup object with private access to the request class. Issue: #41 Signed-off-by: CHENGJin <[email protected]>
1 parent a97640a commit 11eebe7

26 files changed

+695
-88
lines changed

jcl/src/java.base/share/classes/com/ibm/oti/util/ExternalMessages-MasterIndex.properties

+5
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,11 @@ K065O=The parameter types of init doesn't match that of iterator: {0} != {1}
12391239
K065P=The external parameter types of body: {0} doesn't match the external parameter list: {1}
12401240
K065Q=The loop body must be non-null
12411241
K065R=The requested lookup mode: 0x{0} is not one of the existing access modes: 0x{1}
1242+
K065S=Both the requested class and the caller lookup must not be null
1243+
K065T=The target class: {0} must not be a primitive type or an array class
1244+
K065U=The module: {0} containing the old lookup can't read the module: {1}
1245+
K065V=The package: {0} containing the target class is not opened to the module: {1}
1246+
K065W=The access mode: 0x{0} of the caller lookup doesn't have the MODULE mode : 0x{1}
12421247

12431248
#java.lang.StackWalker
12441249
K0639="Stack walker not configured with RETAIN_CLASS_REFERENCE"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*[INCLUDE-IF Sidecar18-SE]*/
2+
package com.ibm.oti.util;
3+
4+
/*******************************************************************************
5+
* Copyright (c) 2017, 2017 IBM Corp. and others
6+
*
7+
* This program and the accompanying materials are made available under
8+
* the terms of the Eclipse Public License 2.0 which accompanies this
9+
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
10+
* or the Apache License, Version 2.0 which accompanies this distribution and
11+
* is available at https://www.apache.org/licenses/LICENSE-2.0.
12+
*
13+
* This Source Code may also be made available under the following
14+
* Secondary Licenses when the conditions for such availability set
15+
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
16+
* General Public License, version 2 with the GNU Classpath
17+
* Exception [1] and GNU General Public License, version 2 with the
18+
* OpenJDK Assembly Exception [2].
19+
*
20+
* [1] https://www.gnu.org/software/classpath/license.html
21+
* [2] http://openjdk.java.net/legal/assembly-exception.html
22+
*
23+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
24+
*******************************************************************************/
25+
26+
import java.lang.reflect.ReflectPermission;
27+
28+
/**
29+
* ReflectPermission objects represent access to reflection
30+
* support.
31+
*
32+
* @author IBM
33+
* @version initial
34+
*/
35+
public class ReflectPermissions {
36+
/**
37+
* ReflectPermission "suppressAccessChecks"
38+
*/
39+
public static final ReflectPermission permissionSuppressAccessChecks = new ReflectPermission("suppressAccessChecks"); //$NON-NLS-1$
40+
}

jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java

+49-7
Original file line numberDiff line numberDiff line change
@@ -1735,22 +1735,64 @@ public static MethodHandles.Lookup publicLookup() {
17351735
return Lookup.PUBLIC_LOOKUP;
17361736
}
17371737

1738-
/*[IF Sidecar19-SE]*/
1738+
/*[IF Sidecar19-SE-B175]*/
17391739
/**
1740-
* Return a MethodHandles.Lookup object that is only able to access <code>private</code> members.
1740+
* Return a MethodHandles.Lookup object with full capabilities including the access
1741+
* to the <code>private</code> members in the requested class
17411742
*
17421743
* @param targetClass - the requested class containing private members
17431744
* @param callerLookup - a Lookup object specific to the caller
17441745
* @return a MethodHandles.Lookup object with private access to the requested class
1746+
* @throws NullPointerException - if targetClass or callerLookup is null
17451747
* @throws IllegalArgumentException - if the requested Class is a primitive type or an array class
1746-
* @throws NullPointerException - if any of the arguments are null
17471748
* @throws IllegalAccessException - if access checking fails
17481749
* @throws SecurityException - if the SecurityManager prevents access
17491750
*/
1750-
public static MethodHandles.Lookup privateLookupIn(Class<?> targetClass, MethodHandles.Lookup callerLookup) throws IllegalArgumentException, NullPointerException, IllegalAccessException, SecurityException {
1751-
throw new UnsupportedOperationException("The method has not yet been implemented for now"); //$NON-NLS-1$
1751+
public static MethodHandles.Lookup privateLookupIn(Class<?> targetClass, MethodHandles.Lookup callerLookup) throws NullPointerException, IllegalArgumentException, IllegalAccessException, SecurityException {
1752+
if (Objects.isNull(targetClass) || Objects.isNull(callerLookup)) {
1753+
/*[MSG "K065S", "Both the requested class and the caller lookup must not be null"]*/
1754+
throw new NullPointerException(com.ibm.oti.util.Msg.getString("K065S")); //$NON-NLS-1$
1755+
}
1756+
1757+
if (targetClass.isPrimitive() || targetClass.isArray()) {
1758+
/*[MSG "K065T", "The target class: {0} must not be a primitive type or an array class"]*/
1759+
throw new IllegalArgumentException(com.ibm.oti.util.Msg.getString("K065T", targetClass.getCanonicalName())); //$NON-NLS-1$
1760+
}
1761+
1762+
Module targetClassModule = targetClass.getModule();
1763+
String targetClassPackageName = targetClass.getPackageName();
1764+
Module accessClassModule = callerLookup.accessClass.getModule();
1765+
1766+
/* Check whether the named module containing the old lookup can read the module containing the target class.
1767+
* Note: an unnamed module can read any module.
1768+
*/
1769+
if (!accessClassModule.canRead(targetClassModule)) {
1770+
/*[MSG "K065U", "The module: {0} containing the old lookup can't read the module: {1}"]*/
1771+
throw new IllegalAccessException(com.ibm.oti.util.Msg.getString("K065U", accessClassModule.getName(), targetClassModule.getName())); //$NON-NLS-1$
1772+
}
1773+
1774+
/* Check whether the module has the package (containing the target class) opened to
1775+
* the module containing the old lookup.
1776+
*/
1777+
if (!targetClassModule.isOpen(targetClassPackageName, accessClassModule)) {
1778+
/*[MSG "K065V", "The package: {0} containing the target class is not opened to the module: {1}"]*/
1779+
throw new IllegalAccessException(com.ibm.oti.util.Msg.getString("K065V", targetClassPackageName, accessClassModule.getName())); //$NON-NLS-1$
1780+
}
1781+
1782+
int callerLookupMode = callerLookup.lookupModes();
1783+
if (Lookup.MODULE != (Lookup.MODULE & callerLookupMode)) {
1784+
/*[MSG "K065W", "The access mode: 0x{0} of the caller lookup doesn't have the MODULE mode : 0x{1}"]*/
1785+
throw new IllegalAccessException(com.ibm.oti.util.Msg.getString("K065W", Integer.toHexString(callerLookupMode), Integer.toHexString(Lookup.MODULE))); //$NON-NLS-1$
1786+
}
1787+
1788+
SecurityManager secmgr = System.getSecurityManager();
1789+
if (null != secmgr) {
1790+
secmgr.checkPermission(com.ibm.oti.util.ReflectPermissions.permissionSuppressAccessChecks);
1791+
}
1792+
1793+
return new Lookup(targetClass);
17521794
}
1753-
/*[ENDIF]*/
1795+
/*[ENDIF] Sidecar19-SE-B175*/
17541796

17551797
/**
17561798
* Gets the underlying Member of the provided <code>target</code> MethodHandle. This is done through an unchecked crack of the MethodHandle.
@@ -1773,7 +1815,7 @@ public static <T extends Member> T reflectAs(Class<T> expected, MethodHandle tar
17731815
}
17741816
SecurityManager secmgr = System.getSecurityManager();
17751817
if (null != secmgr) {
1776-
secmgr.checkPermission(new ReflectPermission("suppressAccessChecks")); //$NON-NLS-1$
1818+
secmgr.checkPermission(com.ibm.oti.util.ReflectPermissions.permissionSuppressAccessChecks);
17771819
}
17781820
MethodHandleInfo mhi = Lookup.IMPL_LOOKUP.revealDirect(target);
17791821
T result = mhi.reflectAs(expected, Lookup.IMPL_LOOKUP);

test/OpenJ9_Jsr_292_API/build.xml

+102-13
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@
22
<!--
33
Copyright (c) 2017, 2017 IBM Corp. and others
44
5-
This program and the accompanying materials are made available under
6-
the terms of the Eclipse Public License 2.0 which accompanies this
7-
distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8-
or the Apache License, Version 2.0 which accompanies this distribution and
9-
is available at https://www.apache.org/licenses/LICENSE-2.0.
5+
This program and the accompanying materials are made available under
6+
the terms of the Eclipse Public License 2.0 which accompanies this
7+
distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8+
or the Apache License, Version 2.0 which accompanies this distribution and
9+
is available at https://www.apache.org/licenses/LICENSE-2.0.
1010
11-
This Source Code is also Distributed under one or more Secondary Licenses,
12-
as those terms are defined by the Eclipse Public License, v. 2.0: GNU
13-
General Public License, version 2 with the GNU Classpath Exception [1]
14-
and GNU General Public License, version 2 with the OpenJDK Assembly
15-
Exception [2].
11+
This Source Code may also be made available under the following
12+
Secondary Licenses when the conditions for such availability set
13+
forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14+
General Public License, version 2 with the GNU Classpath
15+
Exception [1] and GNU General Public License, version 2 with the
16+
OpenJDK Assembly Exception [2].
1617
17-
[1] https://www.gnu.org/software/classpath/license.html
18-
[2] http://openjdk.java.net/legal/assembly-exception.html
18+
[1] https://www.gnu.org/software/classpath/license.html
19+
[2] http://openjdk.java.net/legal/assembly-exception.html
20+
21+
SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
1922
-->
2023
<project name="OpenJ9 JSR 292 API Tests" default="build" basedir=".">
2124
<taskdef resource='net/sf/antcontrib/antlib.xml'/>
@@ -31,12 +34,93 @@
3134
<property name="build" location="./bin"/>
3235
<property name="transformerListener" location="../Utils/src"/>
3336

37+
<property name="mods_name" value="mods"/>
38+
<property name="modulea_name" value="mods.modulea"/>
39+
<property name="moduleb_name" value="mods.moduleb"/>
40+
<property name="modulec_name" value="mods.modulec"/>
41+
42+
<property name="modulea_src" location="./modules/mods.modulea"/>
43+
<property name="moduleb_src" location="./modules/mods.moduleb"/>
44+
<property name="modulec_src" location="./modules/mods.modulec"/>
45+
46+
<property name="mods_dir" location="./mods"/>
47+
<property name="modulea_bin" location="./mods/mods.modulea"/>
48+
<property name="moduleb_bin" location="./mods/mods.moduleb"/>
49+
<property name="modulec_bin" location="./mods/mods.modulec"/>
50+
3451
<target name="init">
3552
<mkdir dir="${DEST}"/>
3653
<mkdir dir="${build}"/>
54+
<mkdir dir="${mods_dir}"/>
55+
<mkdir dir="${modulea_bin}"/>
56+
<mkdir dir="${moduleb_bin}"/>
57+
<mkdir dir="${modulec_bin}"/>
3758
</target>
3859

39-
<target name="compile_tests" depends="init" description="compile the test source code" >
60+
<target name="compile_modulec" depends="init" description="Compile the module files in mods.modulec">
61+
<echo>Compiling the module files in mods.modulec</echo>
62+
<echo>Ant version is ${ant.version}</echo>
63+
<property name="compiler.javac" value="${JAVA_BIN}/javac" />
64+
<echo>============COMPILER SETTINGS============</echo>
65+
<echo>===fork: yes</echo>
66+
<echo>===executable: ${compiler.javac}</echo>
67+
<echo>===debug: on</echo>
68+
<echo>===destdir: ${DEST}</echo>
69+
<if>
70+
<equals arg1="${JAVA_VERSION}" arg2="SE90"/>
71+
<then>
72+
<property name="modulec_path" value="--module-path ${mods_dir} -d ${modulec_bin}" />
73+
<javac srcdir="${modulec_src}" destdir="${modulec_bin}" debug="true" fork="true" executable="${compiler.javac}" includeAntRuntime="false" encoding="ISO-8859-1">
74+
<src path="${modulec_src}"/>
75+
<compilerarg line='${modulec_path}' />
76+
</javac>
77+
</then>
78+
</if>
79+
</target>
80+
81+
<target name="compile_moduleb" depends="init" description="Compile the module files in mods.moduleb">
82+
<echo>Compiling the module files in mods.moduleb</echo>
83+
<echo>Ant version is ${ant.version}</echo>
84+
<property name="compiler.javac" value="${JAVA_BIN}/javac" />
85+
<echo>============COMPILER SETTINGS============</echo>
86+
<echo>===fork: yes</echo>
87+
<echo>===executable: ${compiler.javac}</echo>
88+
<echo>===debug: on</echo>
89+
<echo>===destdir: ${DEST}</echo>
90+
<if>
91+
<equals arg1="${JAVA_VERSION}" arg2="SE90"/>
92+
<then>
93+
<property name="moduleb_path" value="--module-path ${mods_dir} -d ${moduleb_bin}" />
94+
<javac srcdir="${moduleb_src}" destdir="${moduleb_bin}" debug="true" fork="true" executable="${compiler.javac}" includeAntRuntime="false" encoding="ISO-8859-1">
95+
<src path="${moduleb_src}"/>
96+
<compilerarg line='${moduleb_path}' />
97+
</javac>
98+
</then>
99+
</if>
100+
</target>
101+
102+
<target name="compile_modulea" depends="init,compile_moduleb,compile_modulec" description="Compile the module files in mods.modulea">
103+
<echo>Compiling the module files in mods.modulea</echo>
104+
<echo>Ant version is ${ant.version}</echo>
105+
<property name="compiler.javac" value="${JAVA_BIN}/javac" />
106+
<echo>============COMPILER SETTINGS============</echo>
107+
<echo>===fork: yes</echo>
108+
<echo>===executable: ${compiler.javac}</echo>
109+
<echo>===debug: on</echo>
110+
<echo>===destdir: ${DEST}</echo>
111+
<if>
112+
<equals arg1="${JAVA_VERSION}" arg2="SE90"/>
113+
<then>
114+
<property name="modulea_path" value="--module-path ${mods_dir} -d ${modulea_bin}" />
115+
<javac srcdir="${modulea_src}" destdir="${modulea_bin}" debug="true" fork="true" executable="${compiler.javac}" includeAntRuntime="false" encoding="ISO-8859-1">
116+
<src path="${modulea_src}"/>
117+
<compilerarg line='${modulea_path}' />
118+
</javac>
119+
</then>
120+
</if>
121+
</target>
122+
123+
<target name="compile_tests" depends="init,compile_modulea,compile_moduleb,compile_modulec" description="compile the test source code" >
40124
<echo>Compiling the test source code</echo>
41125
<echo>Ant version is ${ant.version}</echo>
42126
<echo>============COMPILER SETTINGS============</echo>
@@ -47,9 +131,11 @@
47131
<if>
48132
<equals arg1="${JAVA_VERSION}" arg2="SE90"/>
49133
<then>
134+
<property name="addModules" value="--add-modules ${modulea_name},${moduleb_name},${modulec_name} --module-path ${mods_dir}" />
50135
<javac srcdir="${src}" destdir="${build}" debug="true" fork="true" executable="${compiler.javac}" includeAntRuntime="false" encoding="ISO-8859-1">
51136
<src path="${src}"/>
52137
<src path="${transformerListener}" />
138+
<compilerarg line='${addModules}' />
53139
<classpath>
54140
<pathelement location="../TestConfig/lib/asm-all.jar" />
55141
<pathelement location="../TestConfig/lib/testng.jar"/>
@@ -64,6 +150,9 @@
64150
<copy todir="${DEST}">
65151
<fileset dir="${src}/../" includes="*.mk,*.xml" />
66152
</copy>
153+
<copy todir="${DEST}/${mods_name}">
154+
<fileset dir="${mods_dir}"/>
155+
</copy>
67156
<jar jarfile="${DEST}/openj9_jsr292test.jar" filesonly="true">
68157
<fileset dir="${build}"/>
69158
</jar>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017, 2017 IBM Corp. and others
3+
*
4+
* This program and the accompanying materials are made available under
5+
* the terms of the Eclipse Public License 2.0 which accompanies this
6+
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7+
* or the Apache License, Version 2.0 which accompanies this distribution and
8+
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9+
*
10+
* This Source Code may also be made available under the following
11+
* Secondary Licenses when the conditions for such availability set
12+
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13+
* General Public License, version 2 with the GNU Classpath
14+
* Exception [1] and GNU General Public License, version 2 with the
15+
* OpenJDK Assembly Exception [2].
16+
*
17+
* [1] https://www.gnu.org/software/classpath/license.html
18+
* [2] http://openjdk.java.net/legal/assembly-exception.html
19+
*
20+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
21+
*******************************************************************************/
22+
package mods.modulea.package1;
23+
24+
import java.lang.invoke.MethodHandles;
25+
import java.lang.invoke.MethodHandles.Lookup;
26+
27+
public class AnotherModuleExample {
28+
public static Lookup getLookup() {
29+
return MethodHandles.lookup();
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017, 2017 IBM Corp. and others
3+
*
4+
* This program and the accompanying materials are made available under
5+
* the terms of the Eclipse Public License 2.0 which accompanies this
6+
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7+
* or the Apache License, Version 2.0 which accompanies this distribution and
8+
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9+
*
10+
* This Source Code may also be made available under the following
11+
* Secondary Licenses when the conditions for such availability set
12+
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13+
* General Public License, version 2 with the GNU Classpath
14+
* Exception [1] and GNU General Public License, version 2 with the
15+
* OpenJDK Assembly Exception [2].
16+
*
17+
* [1] https://www.gnu.org/software/classpath/license.html
18+
* [2] http://openjdk.java.net/legal/assembly-exception.html
19+
*
20+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
21+
*******************************************************************************/
22+
package mods.modulea.package1;
23+
24+
import java.lang.invoke.MethodHandles;
25+
import java.lang.invoke.MethodHandles.Lookup;
26+
27+
public class ModuleExample {
28+
public static Lookup getLookup() {
29+
return MethodHandles.lookup();
30+
}
31+
32+
public static Lookup getPublicLookup() {
33+
return MethodHandles.publicLookup();
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017, 2017 IBM Corp. and others
3+
*
4+
* This program and the accompanying materials are made available under
5+
* the terms of the Eclipse Public License 2.0 which accompanies this
6+
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7+
* or the Apache License, Version 2.0 which accompanies this distribution and
8+
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9+
*
10+
* This Source Code may also be made available under the following
11+
* Secondary Licenses when the conditions for such availability set
12+
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13+
* General Public License, version 2 with the GNU Classpath
14+
* Exception [1] and GNU General Public License, version 2 with the
15+
* OpenJDK Assembly Exception [2].
16+
*
17+
* [1] https://www.gnu.org/software/classpath/license.html
18+
* [2] http://openjdk.java.net/legal/assembly-exception.html
19+
*
20+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
21+
*******************************************************************************/
22+
package mods.modulea.package2;
23+
24+
import java.lang.invoke.MethodHandles;
25+
import java.lang.invoke.MethodHandles.Lookup;
26+
27+
public class SameModuleExample {
28+
public static Lookup getLookup() {
29+
return MethodHandles.lookup();
30+
}
31+
}

0 commit comments

Comments
 (0)