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