1 /* 2 * Copyright (c) 2017, 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 * @bug 8046171 27 * @summary Test access to private constructors between nestmates and nest-host 28 * using different flavours of named nested types using method handles 29 * @run main TestMethodHandles 30 */ 31 32 import java.lang.invoke.*; 33 import static java.lang.invoke.MethodHandles.*; 34 import static java.lang.invoke.MethodType.*; 35 36 public class TestMethodHandles { 37 38 static final MethodType NOARG_T = MethodType.methodType(void.class); 39 static final MethodType INNER_T = MethodType.methodType(void.class, TestMethodHandles.class); 40 41 // All constructors are private to ensure nestmate access checks apply 42 43 // All doConstruct methods are public so they don't involve invoke_special 44 45 private TestMethodHandles() {} 46 47 // The various nestmates 48 49 // Note: No constructor on interfaces so no StaticIface variants 50 51 static interface StaticIface { 52 53 // Methods that will access private constructors of nestmates. 54 // The arg is a dummy for overloading purposes 55 56 default void doConstruct(TestMethodHandles o) throws Throwable { 57 MethodHandle mh = 58 lookup().findConstructor(TestMethodHandles.class, NOARG_T); 59 TestMethodHandles obj = (TestMethodHandles) mh.invoke(); 60 obj = (TestMethodHandles) mh.invokeExact(); 61 } 62 default void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable { 63 MethodHandle mh = 64 lookup().findConstructor(InnerNested.class, INNER_T); 65 InnerNested obj = (InnerNested) mh.invoke(outer); 66 obj = (InnerNested) mh.invokeExact(outer); 67 } 68 default void doConstruct(StaticNested o) throws Throwable { 69 MethodHandle mh = 70 lookup().findConstructor(StaticNested.class, NOARG_T); 71 StaticNested obj = (StaticNested) mh.invoke(); 72 obj = (StaticNested) mh.invokeExact(); 73 } 74 } 75 76 static class StaticNested { 77 78 private StaticNested() {} 79 80 // Methods that will access private constructors of nestmates. 81 // The arg is a dummy for overloading purposes 82 83 public void doConstruct(TestMethodHandles o) throws Throwable { 84 MethodHandle mh = 85 lookup().findConstructor(TestMethodHandles.class, NOARG_T); 86 TestMethodHandles obj = (TestMethodHandles) mh.invoke(); 87 obj = (TestMethodHandles) mh.invokeExact(); 88 } 89 public void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable { 90 MethodHandle mh = 91 lookup().findConstructor(InnerNested.class, INNER_T); 92 InnerNested obj = (InnerNested) mh.invoke(outer); 93 obj = (InnerNested) mh.invokeExact(outer); 94 } 95 public void doConstruct(StaticNested o) throws Throwable { 96 MethodHandle mh = 97 lookup().findConstructor(StaticNested.class, NOARG_T); 98 StaticNested obj = (StaticNested) mh.invoke(); 99 obj = (StaticNested) mh.invokeExact(); 100 } 101 } 102 103 class InnerNested { 104 105 private InnerNested() {} 106 107 // Methods that will access private constructors of nestmates. 108 // The arg is a dummy for overloading purposes 109 110 public void doConstruct(TestMethodHandles o) throws Throwable { 111 MethodHandle mh = 112 lookup().findConstructor(TestMethodHandles.class, NOARG_T); 113 TestMethodHandles obj = (TestMethodHandles) mh.invoke(); 114 obj = (TestMethodHandles) mh.invokeExact(); 115 } 116 public void doConstruct(TestMethodHandles outer, InnerNested o) throws Throwable { 117 MethodHandle mh = 118 lookup().findConstructor(InnerNested.class, INNER_T); 119 InnerNested obj = (InnerNested) mh.invoke(outer); 120 obj = (InnerNested) mh.invokeExact(outer); 121 } 122 public void doConstruct(StaticNested o) throws Throwable { 123 MethodHandle mh = 124 lookup().findConstructor(StaticNested.class, NOARG_T); 125 StaticNested obj = (StaticNested) mh.invoke(); 126 obj = (StaticNested) mh.invokeExact(); 127 } 128 } 129 130 public static void main(String[] args) throws Throwable { 131 // These initial constructions test nest-host access 132 MethodHandle mh = 133 lookup().findConstructor(TestMethodHandles.class, NOARG_T); 134 TestMethodHandles o = (TestMethodHandles) mh.invoke(); 135 o = (TestMethodHandles) mh.invokeExact(); 136 137 mh = lookup().findConstructor(StaticNested.class, NOARG_T); 138 StaticNested s = (StaticNested) mh.invoke(); 139 s = (StaticNested) mh.invokeExact(); 140 141 mh = lookup().findConstructor(InnerNested.class, INNER_T); 142 InnerNested i = (InnerNested) mh.invoke(o); 143 i = (InnerNested) mh.invokeExact(o); 144 145 StaticIface intf = new StaticIface() {}; 146 147 s.doConstruct(o); 148 s.doConstruct(o, i); 149 s.doConstruct(s); 150 151 i.doConstruct(o); 152 i.doConstruct(o, i); 153 i.doConstruct(s); 154 155 intf.doConstruct(o); 156 intf.doConstruct(o, i); 157 intf.doConstruct(s); 158 } 159 }