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 the various rules for nest members and nest-hosts 28 * @compile TestNestmateMembership.java 29 * PackagedNestHost.java 30 * PackagedNestHost2.java 31 * 32 * @compile TargetNoHost.jcod 33 * CallerNoHost.jcod 34 * TargetMissingHost.jcod 35 * CallerMissingHost.jcod 36 * CallerNotInstanceHost.jcod 37 * TargetNotInstanceHost.jcod 38 * CallerNotOurHost.jcod 39 * TargetNotOurHost.jcod 40 * PackagedNestHost.jcod 41 * PackagedNestHost2Member.jcod 42 * PackagedNestHostMember.jcod 43 * 44 * @run main/othervm TestNestmateMembership 45 */ 46 47 // We test all the "illegal" relationships between a nest member and its nest-host 48 // except for the case where the name of the nest-member matches the name listed 49 // in the nest-host, but resolves to a different class. There doesn't seem to 50 // be a way to construct that scenario. 51 // For each nested class below there is a corresponding .jcod file which breaks one 52 // of the rules regarding nest membership. For the package related tests we have 53 // additional PackageNestHost*.java sources. 54 // Note that all the .java files must be compiled in the same step, while all 55 // .jcod files must be compiled in a later step. 56 57 // As access checking requires resolution and validation of the nest-host of 58 // both the caller class and the target class, we must check that all 59 // combinations of good/bad caller/target are checked for each of the 60 // possible errors: 61 // - no nest-host attribute 62 // - nest-host class can not be found 63 // - nest-host class is not an instance class 64 // - class is not a member of nest-host's nest 65 // - class and nest-host are in different packages 66 67 public class TestNestmateMembership { 68 69 static class Caller { 70 private static void m() { 71 System.out.println("Caller.m()"); 72 } 73 public static void invokeTarget() { 74 Target.m(); 75 } 76 public static void invokeTargetNoHost() { 77 TargetNoHost.m(); 78 } 79 public static void invokeTargetMissingHost() { 80 TargetMissingHost.m(); 81 } 82 public static void invokeTargetNotInstanceHost() { 83 TargetNotInstanceHost.m(); 84 } 85 public static void invokeTargetNotOurHost() { 86 TargetNotOurHost.m(); 87 } 88 } 89 90 static class CallerNoHost { 91 private static void m() { 92 System.out.println("CallerNoHost.m() - java version"); 93 } 94 public static void invokeTarget() { 95 Target.m(); 96 } 97 public static void invokeTargetNoHost() { 98 TargetNoHost.m(); 99 } 100 } 101 102 static class CallerMissingHost { 103 String msg = "NoCallerMissingHost"; // for cp entry 104 private static void m() { 105 System.out.println("CallerMissingHost.m() - java version"); 106 } 107 public static void invokeTarget() { 108 Target.m(); 109 } 110 public static void invokeTargetMissingHost() { 111 TargetMissingHost.m(); 112 } 113 } 114 115 static class CallerNotInstanceHost { 116 Object[] oa; // create CP entry to use in jcod change 117 private static void m() { 118 System.out.println("CallerNotInstanceHost.m() - java version"); 119 } 120 public static void invokeTarget() { 121 Target.m(); 122 } 123 public static void invokeTargetNotInstanceHost() { 124 TargetNotInstanceHost.m(); 125 } 126 } 127 128 static class CallerNotOurHost { 129 private static void m() { 130 System.out.println("CallerNotOurHost.m() - java version"); 131 } 132 public static void invokeTarget() { 133 Target.m(); 134 } 135 public static void invokeTargetNotOurHost() { 136 TargetNotOurHost.m(); 137 } 138 } 139 140 static class Target { 141 private static void m() { 142 System.out.println("Target.m()"); 143 } 144 } 145 146 static class TargetNoHost { 147 private static void m() { 148 System.out.println("TargetNoHost.m() - java version"); 149 } 150 } 151 152 static class TargetMissingHost { 153 String msg = "NoTargetMissingHost"; // for cp entry 154 private static void m() { 155 System.out.println("TargetMissingHost.m() - java version"); 156 } 157 } 158 159 static class TargetNotInstanceHost { 160 Object[] oa; // create CP entry to use in jcod change 161 private static void m() { 162 System.out.println("TargetNotInstanceHost.m() - java version"); 163 } 164 } 165 166 static class TargetNotOurHost { 167 private static void m() { 168 System.out.println("TargetNotOurHost.m() - java version"); 169 } 170 } 171 172 public static void main(String[] args) throws Throwable { 173 test_GoodCalls(); 174 test_NoHost(); 175 test_MissingHost(); 176 test_NotInstanceHost(); 177 test_NotOurHost(); 178 test_WrongPackageHost(); 179 } 180 181 static void test_GoodCalls(){ 182 try { 183 Caller.invokeTarget(); 184 } 185 catch (Exception e) { 186 throw new Error("Unexpected exception on good calls: " + e); 187 } 188 } 189 190 static void test_NoHost() throws Throwable { 191 System.out.println("Testing for missing nest-host attribute"); 192 String msg = "tried to access method " + 193 "TestNestmateMembership$TargetNoHost.m()V from class " + 194 "TestNestmateMembership$Caller"; 195 try { 196 Caller.invokeTargetNoHost(); 197 throw new Error("Missing IllegalAccessError: " + msg); 198 } 199 catch (IllegalAccessError expected) { 200 check_expected(expected, msg); 201 } 202 msg = "tried to access method TestNestmateMembership$Target.m()V" + 203 " from class TestNestmateMembership$CallerNoHost"; 204 try { 205 CallerNoHost.invokeTarget(); 206 throw new Error("Missing IllegalAccessError: " + msg); 207 } 208 catch (IllegalAccessError expected) { 209 check_expected(expected, msg); 210 } 211 msg = "tried to access method TestNestmateMembership$TargetNoHost.m()V" + 212 " from class TestNestmateMembership$CallerNoHost"; 213 try { 214 CallerNoHost.invokeTargetNoHost(); 215 throw new Error("Missing IllegalAccessError: " + msg); 216 } 217 catch (IllegalAccessError expected) { 218 check_expected(expected, msg); 219 } 220 } 221 222 static void test_MissingHost() throws Throwable { 223 System.out.println("Testing for nest-host class that does not exist"); 224 String msg = "Unable to load nest-host class of " + 225 "TestNestmateMembership$TargetMissingHost"; 226 String cause_msg = "NoTargetMissingHost"; 227 try { 228 Caller.invokeTargetMissingHost(); 229 throw new Error("Missing NoClassDefFoundError: " + msg); 230 } 231 catch (NoClassDefFoundError expected) { 232 check_expected(expected, msg); 233 Throwable cause = expected.getCause(); 234 if (cause instanceof NoClassDefFoundError) { 235 check_expected(cause, cause_msg); 236 } 237 else throw new Error("Unexpected NoClassDefFoundError", expected); 238 } 239 msg = "Unable to load nest-host class of " + 240 "TestNestmateMembership$CallerMissingHost"; 241 cause_msg = "NoCallerMissingHost"; 242 try { 243 CallerMissingHost.invokeTarget(); 244 throw new Error("Missing NoClassDefFoundError: " + msg); 245 } 246 catch (NoClassDefFoundError expected) { 247 check_expected(expected, msg); 248 Throwable cause = expected.getCause(); 249 if (cause instanceof NoClassDefFoundError) { 250 check_expected(cause, cause_msg); 251 } 252 else throw new Error("Unexpected NoClassDefFoundError", expected); 253 } 254 msg = "Unable to load nest-host class of "+ 255 "TestNestmateMembership$CallerMissingHost"; 256 cause_msg = "NoCallerMissingHost"; 257 try { 258 CallerMissingHost.invokeTargetMissingHost(); 259 throw new Error("Missing NoClassDefFoundError: " + msg); 260 } 261 catch (NoClassDefFoundError expected) { 262 check_expected(expected, msg); 263 Throwable cause = expected.getCause(); 264 if (cause instanceof NoClassDefFoundError) { 265 check_expected(cause, cause_msg); 266 } 267 else throw new Error("Unexpected NoClassDefFoundError", expected); 268 } 269 } 270 271 static void test_NotInstanceHost() throws Throwable { 272 System.out.println("Testing for nest-host class that is not an instance class"); 273 String msg = "Type TestNestmateMembership$TargetNotInstanceHost is not a "+ 274 "nest member of [Ljava.lang.Object;: nest-host is not an instance class"; 275 try { 276 Caller.invokeTargetNotInstanceHost(); 277 throw new Error("Missing IllegalAccessError: " + msg); 278 } 279 catch (IllegalAccessError expected) { 280 check_expected(expected, msg); 281 } 282 msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ 283 "nest member of [Ljava.lang.Object;: nest-host is not an instance class"; 284 try { 285 CallerNotInstanceHost.invokeTarget(); 286 throw new Error("Missing IllegalAccessError: " + msg); 287 } 288 catch (IllegalAccessError expected) { 289 check_expected(expected, msg); 290 } 291 msg = "Type TestNestmateMembership$CallerNotInstanceHost is not a "+ 292 "nest member of [Ljava.lang.Object;: nest-host is not an instance class"; 293 try { 294 CallerNotInstanceHost.invokeTargetNotInstanceHost(); 295 throw new Error("Missing IllegalAccessError: " + msg); 296 } 297 catch (IllegalAccessError expected) { 298 check_expected(expected, msg); 299 } 300 } 301 302 static void test_NotOurHost() throws Throwable { 303 System.out.println("Testing for nest-host class that does not list us in its nest"); 304 String msg = "Type TestNestmateMembership$TargetNotOurHost is not a nest member" + 305 " of java.lang.Object: current type is not listed as a nest member"; 306 try { 307 Caller.invokeTargetNotOurHost(); 308 throw new Error("Missing IllegalAccessError: " + msg); 309 } 310 catch (IllegalAccessError expected) { 311 check_expected(expected, msg); 312 } 313 msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + 314 " of java.lang.Object: current type is not listed as a nest member"; 315 try { 316 CallerNotOurHost.invokeTarget(); 317 throw new Error("Missing IllegalAccessError: " + msg); 318 } 319 catch (IllegalAccessError expected) { 320 check_expected(expected, msg); 321 } 322 msg = "Type TestNestmateMembership$CallerNotOurHost is not a nest member" + 323 " of java.lang.Object: current type is not listed as a nest member"; 324 try { 325 CallerNotOurHost.invokeTargetNotOurHost(); 326 throw new Error("Missing IllegalAccessError: " + msg); 327 } 328 catch (IllegalAccessError expected) { 329 check_expected(expected, msg); 330 } 331 } 332 333 static void test_WrongPackageHost() { 334 System.out.println("Testing for nest-host and nest-member in different packages"); 335 String msg = "Type P2.PackagedNestHost2$Member is not a nest member of " + 336 "P1.PackagedNestHost: types are in different packages"; 337 try { 338 P1.PackagedNestHost.doAccess(); 339 throw new Error("Missing IllegalAccessError: " + msg); 340 } 341 catch (IllegalAccessError expected) { 342 check_expected(expected, msg); 343 } 344 try { 345 P2.PackagedNestHost2.Member.doAccess(); 346 throw new Error("Missing IllegalAccessError: " + msg); 347 } 348 catch (IllegalAccessError expected) { 349 check_expected(expected, msg); 350 } 351 } 352 353 static void check_expected(Throwable expected, String msg) { 354 if (!expected.getMessage().contains(msg)) 355 throw new Error("Wrong " + expected.getClass().getSimpleName() +": \"" + 356 expected.getMessage() + "\" does not contain \"" + 357 msg + "\""); 358 System.out.println("OK - got expected exception: " + expected); 359 } 360 }