1 /*
  2  * Copyright (c) 2015, 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 ModuleSetAccessibleTest
 27  * @modules java.base/java.lang:open
 28  *          java.base/jdk.internal.misc:+open
 29  * @run testng/othervm ModuleSetAccessibleTest
 30  * @summary Test java.lang.reflect.AccessibleObject with modules
 31  */
 32 
 33 import java.lang.reflect.AccessibleObject;
 34 import java.lang.reflect.Constructor;
 35 import java.lang.reflect.Field;
 36 import java.lang.reflect.InaccessibleObjectException;
 37 import java.lang.reflect.InvocationTargetException;
 38 import java.lang.reflect.Method;
 39 import java.security.ProtectionDomain;
 40 
 41 import jdk.internal.misc.Unsafe;
 42 
 43 import org.testng.annotations.Test;
 44 import static org.testng.Assert.*;
 45 
 46 @Test
 47 public class ModuleSetAccessibleTest {
 48 
 49     /**
 50      * Invoke a private constructor on a public class in an exported package
 51      */
 52     public void testPrivateConstructorInExportedPackage() throws Exception {
 53         Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
 54 
 55         try {
 56             ctor.newInstance();
 57             assertTrue(false);
 58         } catch (IllegalAccessException expected) { }
 59 
 60         ctor.setAccessible(true);
 61         Unsafe unsafe = (Unsafe) ctor.newInstance();
 62     }
 63 
 64 
 65     /**
 66      * Invoke a private method on a public class in an exported package
 67      */
 68     public void testPrivateMethodInExportedPackage() throws Exception {
 69         Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
 70         try {
 71             m.invoke(null);
 72             assertTrue(false);
 73         } catch (IllegalAccessException expected) { }
 74 
 75         m.setAccessible(true);
 76         try {
 77             m.invoke(null);
 78             assertTrue(false);
 79         } catch (InvocationTargetException e) {
 80             // thrown by throwIllegalAccessError
 81             assertTrue(e.getCause() instanceof IllegalAccessError);
 82         }
 83     }
 84 
 85 
 86     /**
 87      * Access a private field in a public class that is an exported package
 88      */
 89     public void testPrivateFieldInExportedPackage() throws Exception {
 90         Field f = Unsafe.class.getDeclaredField("theUnsafe");
 91 
 92         try {
 93             f.get(null);
 94             assertTrue(false);
 95         } catch (IllegalAccessException expected) { }
 96 
 97         f.setAccessible(true);
 98         Unsafe unsafe = (Unsafe) f.get(null);
 99     }
100 
101 
102     /**
103      * Invoke a public constructor on a public class in a non-exported package
104      */
105     public void testPublicConstructorInNonExportedPackage() throws Exception {
106         Class<?> clazz = Class.forName("sun.security.x509.X500Name");
107         Constructor<?> ctor = clazz.getConstructor(String.class);
108 
109         try {
110             ctor.newInstance("cn=duke");
111             assertTrue(false);
112         } catch (IllegalAccessException expected) { }
113 
114         try {
115             ctor.setAccessible(true);
116             assertTrue(false);
117         } catch (InaccessibleObjectException expected) { }
118 
119         ctor.setAccessible(false); // should succeed
120     }
121 
122 
123     /**
124      * Access a public field in a public class that in a non-exported package
125      */
126     public void testPublicFieldInNonExportedPackage() throws Exception {
127         Class<?> clazz = Class.forName("sun.security.x509.X500Name");
128         Field f = clazz.getField("SERIALNUMBER_OID");
129 
130         try {
131             f.get(null);
132             assertTrue(false);
133         } catch (IllegalAccessException expected) { }
134 
135         try {
136             f.setAccessible(true);
137             assertTrue(false);
138         } catch (InaccessibleObjectException expected) { }
139 
140         f.setAccessible(false); // should succeed
141     }
142 
143 
144     /**
145      * Test that the Class constructor cannot be make accessible.
146      */
147     public void testJavaLangClass() throws Exception {
148 
149         // non-public constructor
150         Constructor<?> ctor
151             = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, char.class,
152                                                  ProtectionDomain.class, boolean.class, boolean.class, char.class);
153         AccessibleObject[] ctors = { ctor };
154 
155         try {
156             ctor.setAccessible(true);
157             assertTrue(false);
158         } catch (SecurityException expected) { }
159 
160         try {
161             AccessibleObject.setAccessible(ctors, true);
162             assertTrue(false);
163         } catch (SecurityException expected) { }
164 
165         // should succeed
166         ctor.setAccessible(false);
167         AccessibleObject.setAccessible(ctors, false);
168 
169     }
170 
171 }