1 /* 2 * Copyright (c) 2013, 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 package vm.runtime.defmeth; 25 26 import nsk.share.TestFailure; 27 import nsk.share.test.TestBase; 28 import vm.runtime.defmeth.shared.MemoryClassLoader; 29 import vm.runtime.defmeth.shared.annotation.KnownFailure; 30 import vm.runtime.defmeth.shared.annotation.NotApplicableFor; 31 import vm.runtime.defmeth.shared.builder.TestBuilder; 32 import vm.runtime.defmeth.shared.data.*; 33 import static jdk.internal.org.objectweb.asm.Opcodes.*; 34 import vm.runtime.defmeth.shared.DefMethTest; 35 36 import java.util.Map; 37 38 import static vm.runtime.defmeth.shared.ExecutionMode.*; 39 40 /** 41 * Basic tests on some of the assertions from JVMS. 42 */ 43 public class BasicTest extends DefMethTest { 44 45 public static void main(String[] args) { 46 TestBase.runTest(new BasicTest(), args); 47 } 48 49 /* 50 * JVMS 6.5 invokevirtual 51 * 52 * ... 53 * 54 * Runtime Exceptions 55 * 56 * Otherwise, if the resolved method is not signature polymorphic: 57 * 58 */ 59 60 /* 61 * ... 62 * 63 * If the resolved method is declared in an interface and the class of 64 * objectref does not implement the resolved interface, invokevirtual throws 65 * an IncompatibleClassChangeError. 66 */ 67 @KnownFailure(modes = { 68 REFLECTION, // throws IAE 69 INVOKE_GENERIC, INVOKE_WITH_ARGS}) // throws ClassCastException 70 public void testInterfaceNotImplemented() { 71 TestBuilder b = factory.getBuilder(); 72 73 Interface I = b.intf("I") 74 .defaultMethod("m", "()V").emptyBody().build() 75 .build(); 76 77 ConcreteClass C = b.clazz("C").build(); 78 79 Class expectedClass; 80 if (factory.getExecutionMode().equals("REFLECTION")) { 81 expectedClass = IllegalArgumentException.class; 82 } else if (factory.getExecutionMode().equals("INVOKE_WITH_ARGS")) { 83 // Notes from JDK-8029926 which details reasons behind CCE. 84 // The code below demonstrates the use of a MethodHandle 85 // of kind REF_invokeInterface pointing to method I.m. 86 // Because 'invoke' is called, this MethodHandle is effectively 87 // wrapped in the type adaptations necessary to accept a C 88 // as the first argument. ***Before we even get to the point 89 // of the invokeinterface call to I.m***, the adaptation 90 // code must run, and that is where the ClassCastException occurs. 91 // This exception can be thrown from code that is cleanly 92 // compiled and does no bytecode generation, so an ICCE would 93 // be inappropriate since no classes are changed. 94 expectedClass = ClassCastException.class; 95 } else { 96 expectedClass = IncompatibleClassChangeError.class; 97 } 98 99 b.test().callSite(I, C, "m", "()V").throws_(expectedClass).done() 100 101 .run(); 102 } 103 104 /* 105 * ... 106 * 107 * Otherwise, if no method matching the resolved name and descriptor is 108 * selected, invokevirtual throws an NoSuchMethodError. 109 * 110 * ... 111 */ 112 @KnownFailure(modes = { 113 DIRECT, REFLECTION, INVOKE_WITH_ARGS, // NSME, instead of AME 114 INVOKE_EXACT, INVOKE_GENERIC, INDY}) // IncompatibleClassChangeError, instead of AME 115 public void testNoMatch() { 116 TestBuilder b = factory.getBuilder(); 117 118 Interface I = b.intf("I") 119 .defaultMethod("m", "(Ljava/lang/Object;)V").emptyBody().build() 120 .build(); 121 122 ConcreteClass C = b.clazz("C").implement(I).build(); 123 124 b.test().callSite(C, C, "m", "()I").throws_(NoSuchMethodError.class).done() 125 .test().callSite(C, C, "m1", "()V").throws_(NoSuchMethodError.class).done() 126 .test().callSite(C, C, "m", "(I)V").throws_(NoSuchMethodError.class).done() 127 128 .run(); 129 } 130 131 /* 132 * ... 133 * 134 * 8025604: Updated specification text for both 5.4.3.3 and 5.4.4.4 135 * "Otherwise, if any superinterface of C declares a method with the name and 136 * descriptor specified by the method reference that has set neither 137 * its ACC_PRIVATE flag nor its ACC_STATIC flag, one of these is arbitrarily 138 * chosen and method lookup succeeds." 139 * If method lookup fails, method resolution throws a NoSuchMethodError 140 * 141 * ... 142 */ 143 public void testNonPublic() { 144 TestBuilder b = factory.getBuilder(); 145 146 Interface I = b.intf("I") 147 .defaultMethod("m1", "()V").private_().emptyBody().build() 148 .defaultMethod("m2", "()I").private_().returns(1).build() 149 .build(); 150 151 ConcreteClass C = b.clazz("C").implement(I).build(); 152 153 b.test().callSite(C, C, "m1", "()V").throws_(NoSuchMethodError.class).done() 154 .test().callSite(C, C, "m2", "()I").throws_(NoSuchMethodError.class).done() 155 156 .run(); 157 } 158 159 /* 160 * Default method override w/ non-public concrete method 161 * 162 * interface I { void m() default {} } 163 * class C implements I { 164 * [private/package-private/protected] 165 * void m() {} 166 * } 167 * 168 */ 169 @KnownFailure(modes = {INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY}) // NPE, instead of IAE 170 public void testNonPublicOverride() { 171 TestBuilder b = factory.getBuilder(); 172 173 Interface I = b.intf("I") 174 .defaultMethod("m","()V").emptyBody().build() 175 .build(); 176 177 ConcreteClass C = b.clazz("C").implement(I) 178 .concreteMethod("m", "()V").private_().emptyBody().build() 179 .build(); 180 181 ConcreteClass D = b.clazz("D").implement(I) 182 .concreteMethod("m", "()V").protected_().emptyBody().build() 183 .build(); 184 185 ConcreteClass E = b.clazz("E").implement(I) 186 .concreteMethod("m", "()V").package_private().emptyBody().build() 187 .build(); 188 189 b.test().callSite(I, C, "m", "()V").throws_(IllegalAccessError.class).done() 190 .test().callSite(I, D, "m", "()V").throws_(IllegalAccessError.class).done() 191 .test().callSite(I, E, "m", "()V").throws_(IllegalAccessError.class).done() 192 193 .run(); 194 } 195 196 197 /** 198 * interface I { 199 * static { throw new RE()} 200 * public default void m() {} 201 * } 202 * 203 * class C implements I {} 204 * 205 * TEST: C c = new C(); ==> LinkageError 206 * Static initialization of class C will trigger 207 * I's static initialization due to I's default method. 208 */ 209 public void testStaticInit() throws ClassNotFoundException { 210 TestBuilder b = factory.getBuilder(); 211 212 Interface I = b.intf("I") 213 .defaultMethod("<clinit>", "()V") 214 .flags(ACC_STATIC) 215 .throw_(RuntimeException.class) 216 .build() 217 218 .defaultMethod("m", "()V") 219 .emptyBody().build() 220 .build(); 221 222 ConcreteClass C = b.clazz("C").implement(I).build(); 223 224 b.test().callSite(I, C, "m", "()V").throws_(LinkageError.class).done() 225 226 .run(); 227 } 228 229 /** 230 * interface I { 231 * static { throw new RE()} 232 * private default void m() {} 233 * } 234 * 235 * class C implements I {} 236 * 237 * TEST: C c = new C(); ==> LinkageError 238 * Static initialization of class C will trigger 239 * I's static initialization due to I's private concrete method. 240 */ 241 public void testStaticInitPrivate() throws ClassNotFoundException { 242 TestBuilder b = factory.getBuilder(); 243 244 Interface I = b.intf("I") 245 .defaultMethod("<clinit>", "()V") 246 .flags(ACC_STATIC) 247 .throw_(RuntimeException.class) 248 .build() 249 250 .defaultMethod("m", "()V") 251 .flags(ACC_PRIVATE) 252 .emptyBody().build() 253 .build(); 254 255 ConcreteClass C = b.clazz("C").implement(I).build(); 256 257 Class expectedClass; 258 if (factory.getExecutionMode().equals("REFLECTION")) { 259 expectedClass = NoSuchMethodException.class; 260 } else { 261 expectedClass = LinkageError.class; 262 } 263 b.test().callSite(I, C, "m", "()V").throws_(expectedClass).done() 264 265 .run(); 266 } 267 268 /** 269 * interface I { 270 * static { throw new RE()} 271 * } 272 * interface J { 273 * public default int m() { return 1} 274 * 275 * class C implements I,J {} 276 * 277 * TEST: C c = new C() 278 * c.m() returns 1 279 * Static initialization of class C will not trigger 280 * I's static initialization since I has no concrete methods. 281 */ 282 public void testNotStaticInitNoDefault() throws ClassNotFoundException { 283 TestBuilder b = factory.getBuilder(); 284 285 Interface I = b.intf("I") 286 .defaultMethod("<clinit>", "()V") 287 .flags(ACC_STATIC) 288 .throw_(RuntimeException.class) 289 .build() 290 .build(); 291 292 Interface J = b.intf("J") 293 .defaultMethod("m", "()I") 294 .returns(1).build() 295 .build(); 296 297 ConcreteClass C = b.clazz("C").implement(I,J).build(); 298 299 b.test().callSite(C, C, "m", "()I").returns(1).done() 300 301 .run(); 302 } 303 304 /* 305 * Example A.10 306 * 307 * Let L1 and L2 be class loaders with different interpretations of the type "A". 308 * 309 * Loaded by L1: 310 * public interface I { public default A m() { return null; } } 311 * 312 * Loaded by L2: 313 * public class C implements I {} 314 * 315 * TEST: I o = new C(); o.m() ==> LinkageError; 316 * TEST: C o = new C(); o.m() ==> LinkageError; 317 */ 318 // disabling this test for REFLECTION and INVOKE for now until 319 // loader constraint issue associated with those modes has been resolved 320 @NotApplicableFor(modes = { REFLECTION, INVOKE_WITH_ARGS, INVOKE_EXACT, INVOKE_GENERIC, INDY }) 321 public void testLoaderConstraint() throws Exception{ 322 TestBuilder b = factory.getBuilder(); 323 324 ConcreteClass A = b.clazz("A").build(); 325 326 Interface I = b.intf("I") 327 .defaultMethod("m", "()LA;").returnsNewInstance(A).build() 328 .build(); 329 330 ConcreteClass C = b.clazz("C").implement(I).build(); 331 332 b.test().callSite(I, C, "m", "()LA;").throws_(LinkageError.class).done() 333 .test().callSite(C, C, "m", "()LA;").throws_(LinkageError.class).done() 334 335 .prepare(new TestBuilder.LoaderConstructor() { 336 @Override 337 public MemoryClassLoader construct(Map<String, byte[]> classFiles) { 338 final byte[] cfI = classFiles.get("I"); 339 final byte[] cfC = classFiles.get("C"); 340 final byte[] cfA = classFiles.get("A"); 341 final byte[] cfT1 = classFiles.get("Test1_I_C_m"); 342 final byte[] cfT2 = classFiles.get("Test2_C_C_m"); 343 344 final ClassLoader l1 = new ClassLoader() { 345 @Override 346 protected Class<?> findClass(String name) throws ClassNotFoundException { 347 switch (name) { 348 case "I": 349 return defineClass(name, cfI, 0, cfI.length); 350 case "A": 351 return defineClass(name, cfA, 0, cfA.length); 352 default: 353 throw new ClassNotFoundException(name); 354 } 355 } 356 }; 357 358 final MemoryClassLoader l2 = new MemoryClassLoader(classFiles) { 359 @Override 360 public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 361 if ("I".equals(name)) { 362 return l1.loadClass(name); 363 } else { 364 return super.loadClass(name, resolve); 365 } 366 } 367 }; 368 369 try { 370 // Need to preload classes, otherwise A will be resolved in the same loader 371 l1.loadClass("A"); l1.loadClass("I"); 372 l2.loadClass("A"); l2.loadClass("C"); 373 } catch (ClassNotFoundException e) { 374 throw new TestFailure(e); 375 } 376 377 return l2; 378 } 379 }).run(); 380 } 381 }