1 /* 2 * Copyright (c) 2018, 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 JNI access to private methods between nestmates and nest-host 28 * using different flavours of named nested types 29 * @compile ../NestmatesJNI.java 30 * @run main/othervm/native TestJNI 31 * @run main/othervm/native -Xcheck:jni TestJNI 32 */ 33 public class TestJNI { 34 35 // Unlike reflection, the calling context is not relevant to JNI 36 // calls, but we keep the same structure as the reflection tests. 37 38 static final String METHOD = "priv_invoke"; 39 40 // Private method of nest-host for nestmates to access 41 private void priv_invoke() { 42 System.out.println("TestJNI::priv_invoke"); 43 } 44 45 // public constructor so we aren't relying on private access 46 public TestJNI() {} 47 48 // Methods that will access private methods of nestmates 49 50 void access_priv(TestJNI o) { 51 doCall(o, o.getClass(), METHOD, true); 52 doCall(o, o.getClass(), METHOD, false); 53 } 54 void access_priv(InnerNested o) { 55 doCall(o, o.getClass(), METHOD, true); 56 doCall(o, o.getClass(), METHOD, false); 57 } 58 void access_priv(StaticNested o) { 59 doCall(o, o.getClass(), METHOD, true); 60 doCall(o, o.getClass(), METHOD, false); 61 } 62 void access_priv(StaticIface o) { 63 // Can't use o.getClass() as the method is not in that class 64 doCall(o, StaticIface.class, METHOD, true); 65 doCall(o, StaticIface.class, METHOD, false); 66 } 67 68 // The various nestmates 69 70 static interface StaticIface { 71 72 private void priv_invoke() { 73 System.out.println("StaticIface::priv_invoke"); 74 } 75 76 // Methods that will access private methods of nestmates 77 78 default void access_priv(TestJNI o) { 79 doCall(o, o.getClass(), METHOD, true); 80 doCall(o, o.getClass(), METHOD, false); 81 } 82 default void access_priv(InnerNested o) { 83 doCall(o, o.getClass(), METHOD, true); 84 doCall(o, o.getClass(), METHOD, false); 85 } 86 default void access_priv(StaticNested o) { 87 doCall(o, o.getClass(), METHOD, true); 88 doCall(o, o.getClass(), METHOD, false); 89 } 90 default void access_priv(StaticIface o) { 91 // Can't use o.getClass() as the method is not in that class 92 doCall(o, StaticIface.class, METHOD, true); 93 doCall(o, StaticIface.class, METHOD, false); 94 } 95 } 96 97 static class StaticNested { 98 99 private void priv_invoke() { 100 System.out.println("StaticNested::priv_invoke"); 101 } 102 103 // public constructor so we aren't relying on private access 104 public StaticNested() {} 105 106 // Methods that will access private methods of nestmates 107 108 void access_priv(TestJNI o) { 109 doCall(o, o.getClass(), METHOD, true); 110 doCall(o, o.getClass(), METHOD, false); 111 } 112 void access_priv(InnerNested o) { 113 doCall(o, o.getClass(), METHOD, true); 114 doCall(o, o.getClass(), METHOD, false); 115 } 116 void access_priv(StaticNested o) { 117 doCall(o, o.getClass(), METHOD, true); 118 doCall(o, o.getClass(), METHOD, false); 119 } 120 void access_priv(StaticIface o) { 121 // Can't use o.getClass() as the method is not in that class 122 doCall(o, StaticIface.class, METHOD, true); 123 doCall(o, StaticIface.class, METHOD, false); 124 } 125 } 126 127 class InnerNested { 128 129 private void priv_invoke() { 130 System.out.println("InnerNested::priv_invoke"); 131 } 132 133 // public constructor so we aren't relying on private access 134 public InnerNested() {} 135 136 void access_priv(TestJNI o) { 137 doCall(o, o.getClass(), METHOD, true); 138 doCall(o, o.getClass(), METHOD, false); 139 } 140 void access_priv(InnerNested o) { 141 doCall(o, o.getClass(), METHOD, true); 142 doCall(o, o.getClass(), METHOD, false); 143 } 144 void access_priv(StaticNested o) { 145 doCall(o, o.getClass(), METHOD, true); 146 doCall(o, o.getClass(), METHOD, false); 147 } 148 void access_priv(StaticIface o) { 149 // Can't use o.getClass() as the method is not in that class 150 doCall(o, StaticIface.class, METHOD, true); 151 doCall(o, StaticIface.class, METHOD, false); 152 } 153 } 154 155 public static void main(String[] args) { 156 TestJNI o = new TestJNI(); 157 StaticNested s = new StaticNested(); 158 InnerNested i = o.new InnerNested(); 159 StaticIface intf = new StaticIface() {}; 160 161 o.access_priv(new TestJNI()); 162 o.access_priv(i); 163 o.access_priv(s); 164 o.access_priv(intf); 165 166 s.access_priv(o); 167 s.access_priv(i); 168 s.access_priv(new StaticNested()); 169 s.access_priv(intf); 170 171 i.access_priv(o); 172 i.access_priv(o.new InnerNested()); 173 i.access_priv(s); 174 i.access_priv(intf); 175 176 intf.access_priv(o); 177 intf.access_priv(i); 178 intf.access_priv(s); 179 intf.access_priv(new StaticIface(){}); 180 } 181 182 183 static void doCall(Object target, Class<?> klass, String method, 184 boolean virtual) { 185 String definingClass = klass.getName(); 186 String desc = (virtual ? "Virtual" : "Nonvirtual") + " Invocation of " + 187 definingClass + "." + method + " on instance of class " + 188 target.getClass().getName(); 189 try { 190 NestmatesJNI.callVoidVoid(target, definingClass, method, virtual); 191 System.out.println(desc + " - passed"); 192 } 193 catch (Throwable t) { 194 throw new Error(desc + ": Unexpected exception: " + t, t); 195 } 196 } 197 }