1 /*
2 * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /**
25 * @test
26 * @build TrySetAccessibleTest
27 * @modules java.base/java.lang:open
28 * java.base/jdk.internal.module
29 * java.base/jdk.internal.perf
30 * java.base/jdk.internal.misc:+open
31 * @run testng/othervm TrySetAccessibleTest
32 * @summary Test AccessibleObject::trySetAccessible method
33 */
34
35 import java.lang.reflect.AccessibleObject;
36 import java.lang.reflect.Constructor;
37 import java.lang.reflect.Field;
38 import java.lang.reflect.InvocationTargetException;
39 import java.lang.reflect.Method;
40
41 import jdk.internal.misc.Unsafe;
42 import jdk.internal.module.ModulePath;
43 import jdk.internal.perf.Perf;
44 import java.security.ProtectionDomain;
45
46 import org.testng.annotations.Test;
47 import static org.testng.Assert.*;
48
49 @Test
50 public class TrySetAccessibleTest {
51 /**
52 * Invoke a private constructor on a public class in an exported package
53 */
54 public void testPrivateConstructorInExportedPackage() throws Exception {
55 Constructor<?> ctor = Perf.class.getDeclaredConstructor();
56
57 try {
58 ctor.newInstance();
59 assertTrue(false);
60 } catch (IllegalAccessException expected) { }
61
62 assertFalse(ctor.trySetAccessible());
63 assertFalse(ctor.canAccess(null));
64 }
65
66 /**
67 * Invoke a private constructor on a public class in an open package
68 */
69 public void testPrivateConstructorInOpenedPackage() throws Exception {
70 Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
71
72 try {
73 ctor.newInstance();
74 assertTrue(false);
75 } catch (IllegalAccessException expected) { }
76
77 assertTrue(ctor.trySetAccessible());
78 assertTrue(ctor.canAccess(null));
79 Unsafe unsafe = (Unsafe) ctor.newInstance();
80 }
81
82 /**
83 * Invoke a private method on a public class in an exported package
84 */
85 public void testPrivateMethodInExportedPackage() throws Exception {
86 Method m = ModulePath.class.getDeclaredMethod("packageName", String.class);
87 try {
88 m.invoke(null);
89 assertTrue(false);
90 } catch (IllegalAccessException expected) { }
91
92 assertFalse(m.trySetAccessible());
93 assertFalse(m.canAccess(null));
94 }
95
96
97 /**
98 * Invoke a private method on a public class in an open package
99 */
100 public void testPrivateMethodInOpenedPackage() throws Exception {
101 Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
102 assertFalse(m.canAccess(null));
103
104 try {
105 m.invoke(null);
106 assertTrue(false);
107 } catch (IllegalAccessException expected) { }
108
109 assertTrue(m.trySetAccessible());
110 assertTrue(m.canAccess(null));
111 try {
112 m.invoke(null);
113 assertTrue(false);
114 } catch (InvocationTargetException e) {
115 // thrown by throwIllegalAccessError
116 assertTrue(e.getCause() instanceof IllegalAccessError);
117 }
118 }
119
120 /**
121 * Invoke a private method on a public class in an exported package
122 */
123 public void testPrivateFieldInExportedPackage() throws Exception {
124 Field f = Perf.class.getDeclaredField("instance");
125 try {
126 f.get(null);
127 assertTrue(false);
128 } catch (IllegalAccessException expected) { }
129
130 assertFalse(f.trySetAccessible());
131 assertFalse(f.canAccess(null));
132 try {
133 f.get(null);
134 assertTrue(false);
135 } catch (IllegalAccessException expected) {}
136 }
137
138 /**
139 * Access a private field in a public class that is an exported package
140 */
141 public void testPrivateFieldInOpenedPackage() throws Exception {
142 Field f = Unsafe.class.getDeclaredField("theUnsafe");
143
144 try {
145 f.get(null);
146 assertTrue(false);
147 } catch (IllegalAccessException expected) { }
148
149 assertTrue(f.trySetAccessible());
150 assertTrue(f.canAccess(null));
151 Unsafe unsafe = (Unsafe) f.get(null);
152 }
153
154
155 /**
156 * Invoke a public constructor on a public class in a non-exported package
157 */
158 public void testPublicConstructorInNonExportedPackage() throws Exception {
159 Class<?> clazz = Class.forName("sun.security.x509.X500Name");
160 Constructor<?> ctor = clazz.getConstructor(String.class);
161
162 try {
163 ctor.newInstance("cn=duke");
164 assertTrue(false);
165 } catch (IllegalAccessException expected) { }
166
167 assertFalse(ctor.trySetAccessible());
168 assertFalse(ctor.canAccess(null));
169 assertTrue(ctor.trySetAccessible() == ctor.isAccessible());
170 }
171
172
173 /**
174 * Access a public field in a public class that in a non-exported package
175 */
176 public void testPublicFieldInNonExportedPackage() throws Exception {
177 Class<?> clazz = Class.forName("sun.security.x509.X500Name");
178 Field f = clazz.getField("SERIALNUMBER_OID");
179
180 try {
181 f.get(null);
182 assertTrue(false);
183 } catch (IllegalAccessException expected) { }
184
185 assertFalse(f.trySetAccessible());
186 assertFalse(f.canAccess(null));
187 }
188
189
190 /**
191 * Test that the Class constructor cannot be make accessible.
192 */
193 public void testJavaLangClass() throws Exception {
194
195 // non-public constructor
196 Constructor<?> ctor
197 = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, char.class,
198 ProtectionDomain.class, boolean.class, boolean.class, char.class);
199 AccessibleObject[] ctors = { ctor };
200
201 assertFalse(ctor.trySetAccessible());
202 assertFalse(ctor.canAccess(null));
203 }
204
205 }