1 /*
2 * Copyright (c) 2017, 2026, 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 junit/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 static org.junit.jupiter.api.Assertions.*;
47 import org.junit.jupiter.api.Test;
48
49 public class TrySetAccessibleTest {
50 /**
51 * Invoke a private constructor on a public class in an exported package
52 */
53 @Test
54 public void testPrivateConstructorInExportedPackage() throws Exception {
55 Constructor<?> ctor = Perf.class.getDeclaredConstructor();
56
57 assertThrows(IllegalAccessException.class, () -> ctor.newInstance());
58
59 assertFalse(ctor.trySetAccessible());
60 assertFalse(ctor.canAccess(null));
61 }
62
63 /**
64 * Invoke a private constructor on a public class in an open package
65 */
66 @Test
67 public void testPrivateConstructorInOpenedPackage() throws Exception {
68 Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
69
70 assertThrows(IllegalAccessException.class, () -> ctor.newInstance());
71
72 assertTrue(ctor.trySetAccessible());
73 assertTrue(ctor.canAccess(null));
74 Unsafe unsafe = (Unsafe) ctor.newInstance();
75 }
76
77 /**
78 * Invoke a private method on a public class in an exported package
79 */
80 @Test
81 public void testPrivateMethodInExportedPackage() throws Exception {
82 Method m = ModulePath.class.getDeclaredMethod("packageName", String.class);
83 assertThrows(IllegalAccessException.class, () -> m.invoke(null));
84
85 assertFalse(m.trySetAccessible());
86 assertFalse(m.canAccess(null));
87 }
88
89
90 /**
91 * Invoke a private method on a public class in an open package
92 */
93 @Test
94 public void testPrivateMethodInOpenedPackage() throws Exception {
95 Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
96 assertFalse(m.canAccess(null));
97
98 assertThrows(IllegalAccessException.class, () -> m.invoke(null));
99
100 assertTrue(m.trySetAccessible());
101 assertTrue(m.canAccess(null));
102
103 InvocationTargetException e = assertThrows(InvocationTargetException.class, () ->
104 m.invoke(null));
105 assertInstanceOf(IllegalAccessError.class, e.getCause());
106 }
107
108 /**
109 * Invoke a private method on a public class in an exported package
110 */
111 @Test
112 public void testPrivateFieldInExportedPackage() throws Exception {
113 Field f = Perf.class.getDeclaredField("instance");
114 assertThrows(IllegalAccessException.class, () -> f.get(null));
115
116 assertFalse(f.trySetAccessible());
117 assertFalse(f.canAccess(null));
118 assertThrows(IllegalAccessException.class, () -> f.get(null));
119 }
120
121 /**
122 * Access a private field in a public class that is an exported package
123 */
124 @Test
125 public void testPrivateFieldInOpenedPackage() throws Exception {
126 Field f = Unsafe.class.getDeclaredField("theUnsafe");
127
128 assertThrows(IllegalAccessException.class, () -> f.get(null));
129
130 assertTrue(f.trySetAccessible());
131 assertTrue(f.canAccess(null));
132 Unsafe unsafe = (Unsafe) f.get(null);
133 }
134
135
136 /**
137 * Invoke a public constructor on a public class in a non-exported package
138 */
139 @Test
140 public void testPublicConstructorInNonExportedPackage() throws Exception {
141 Class<?> clazz = Class.forName("sun.security.x509.X500Name");
142 Constructor<?> ctor = clazz.getConstructor(String.class);
143
144 assertThrows(IllegalAccessException.class, () -> ctor.newInstance("cn=duke"));
145
146 assertFalse(ctor.trySetAccessible());
147 assertFalse(ctor.canAccess(null));
148 assertFalse(ctor.trySetAccessible());
149 assertFalse(ctor.isAccessible()); // should match trySetAccessible
150 }
151
152
153 /**
154 * Access a public field in a public class that in a non-exported package
155 */
156 @Test
157 public void testPublicFieldInNonExportedPackage() throws Exception {
158 Class<?> clazz = Class.forName("sun.security.x509.X500Name");
159 Field f = clazz.getField("SERIALNUMBER_OID");
160
161 assertThrows(IllegalAccessException.class, () -> f.get(null));
162
163 assertFalse(f.trySetAccessible());
164 assertFalse(f.canAccess(null));
165 }
166
167
168 /**
169 * Test that the Class constructor cannot be make accessible.
170 */
171 @Test
172 public void testJavaLangClass() throws Exception {
173
174 // non-public constructor
175 Constructor<?> ctor
176 = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, char.class,
177 ProtectionDomain.class, boolean.class, boolean.class, char.class);
178 AccessibleObject[] ctors = { ctor };
179
180 assertFalse(ctor.trySetAccessible());
181 assertFalse(ctor.canAccess(null));
182 }
183
184 }