1 /* 2 * Copyright (c) 2013, 2021, 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 * 27 * @modules java.base/jdk.internal.org.objectweb.asm:+open java.base/jdk.internal.org.objectweb.asm.util:+open 28 * @library /vmTestbase /test/lib 29 * 30 * @comment build retransform.jar in current dir 31 * @run driver vm.runtime.defmeth.shared.BuildJar 32 * 33 * @run driver jdk.test.lib.FileInstaller . . 34 * @run main/othervm/native 35 * -agentlib:redefineClasses 36 * -javaagent:retransform.jar 37 * vm.runtime.defmeth.MethodResolutionTest 38 */ 39 package vm.runtime.defmeth; 40 41 import java.util.Set; 42 43 import vm.runtime.defmeth.shared.data.*; 44 import vm.runtime.defmeth.shared.data.method.param.*; 45 import vm.runtime.defmeth.shared.DefMethTest; 46 import vm.runtime.defmeth.shared.builder.TestBuilder; 47 48 import static jdk.internal.org.objectweb.asm.Opcodes.*; 49 import static vm.runtime.defmeth.shared.ExecutionMode.*; 50 51 /** 52 * Tests on method resolution in presence of default methods in the hierarchy. 53 * 54 * Because default methods reside in interfaces, and interfaces do not have 55 * the constraint of being single-inheritance, it is possible to inherit 56 * multiple conflicting default methods, or even inherit the same default method 57 * from many different inheritance paths. 58 * 59 * There is an algorithm to select which method to use in the case that a 60 * concrete class does not provide an implementation. Informally, the algorithm 61 * works as follows: 62 * 63 * (1) If there is a adequate implementation in the class itself or in a 64 * superclass (not an interface), then that implementation should be used 65 * (i.e., class methods always "win"). 66 * 67 * (2) Failing that, create the set of methods consisting of all methods in the 68 * type hierarchy which satisfy the slot to be filled, where in this case 69 * 'satisfy' means that the methods have the same name, the same language- 70 * level representation of the parameters, and covariant return values. Both 71 * default methods and abstract methods will be part of this set. 72 * 73 * (3) Remove from this set, any method which has a "more specific" version 74 * anywhere in the hierarchy. That is, if C implements I,J and I extends J, 75 * then if both I and J have a suitable methods, J's method is eliminated 76 * from the set since I is a subtype of J -- there exist a more specific 77 * method than J's method, so that is eliminated. 78 * 79 * (4) If the remaining set contains only a single entry, then that method is 80 * selected. Note that the method may be abstract, in which case an 81 * IncompatibleClassChangeError is thrown when/if the method is called. If there are 82 * multiple entries in the set, or no entries, then this also results in an 83 * IncompatibleClassChangeError when called. 84 */ 85 public class MethodResolutionTest extends DefMethTest { 86 main(String[] args)87 public static void main(String[] args) { 88 DefMethTest.runTest(MethodResolutionTest.class, 89 /* majorVer */ Set.of(MIN_MAJOR_VER, MAX_MAJOR_VER), 90 /* flags */ Set.of(0, ACC_SYNCHRONIZED), 91 /* redefine */ Set.of(false, true), 92 /* execMode */ Set.of(DIRECT, REFLECTION, INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY)); 93 } 94 95 /* 96 * Basic 97 * 98 * interface I { int m(); } 99 * class C implements I { public int m() { return 1; } } 100 * 101 * TEST: C c = new C(); c.m() == 1; 102 * TEST: I i = new C(); i.m() == 1; 103 */ testBasic(TestBuilder b)104 public void testBasic(TestBuilder b) { 105 Interface I = 106 b.intf("I") 107 .abstractMethod("m", "()I").build() 108 .build(); 109 110 ConcreteClass C = 111 b.clazz("C").implement(I) 112 .concreteMethod("m", "()I").returns(1).build() 113 .build(); 114 115 b.test() 116 .callSite(I, C, "m", "()I") 117 .returns(1) 118 .done() 119 .test() 120 .callSite(C, C, "m", "()I") 121 .returns(1) 122 .done(); 123 } 124 125 /* 126 * Basic Default 127 * 128 * interface I { int m() default { return 1; } } 129 * class C implements I {} 130 * 131 * TEST: C c = new C(); c.m() == 1; 132 * TEST: I i = new C(); i.m() == 1; 133 */ testBasicDefault(TestBuilder b)134 public void testBasicDefault(TestBuilder b) { 135 Interface I = 136 b.intf("I") 137 .defaultMethod("m", "()I").returns(1) 138 .build() 139 .build(); 140 141 ConcreteClass C = 142 b.clazz("C").implement(I) 143 .build(); 144 145 b.test() 146 .callSite(I, C, "m", "()I") 147 .returns(1) 148 .done() 149 .test().callSite(C, C, "m", "()I") 150 .returns(1) 151 .done(); 152 } 153 154 /* 155 * Far Default 156 * 157 * interface I { int m() default { return 1; } } 158 * interface J extends I {} 159 * interface K extends J {} 160 * class C implements K {} 161 * 162 * TEST: [I|J|K|C] i = new C(); i.m() == 1; 163 */ testFarDefault(TestBuilder b)164 public void testFarDefault(TestBuilder b) { 165 Interface I = 166 b.intf("I") 167 .defaultMethod("m", "()I").returns(1) 168 .build() 169 .build(); 170 171 Interface J = b.intf("J").extend(I).build(); 172 Interface K = b.intf("K").extend(J).build(); 173 174 ConcreteClass C = 175 b.clazz("C").implement(K) 176 .build(); 177 178 b.test() 179 .callSite(I, C, "m", "()I") 180 .returns(1) 181 .done() 182 .test().callSite(J, C, "m", "()I") 183 .returns(1) 184 .done() 185 .test().callSite(K, C, "m", "()I") 186 .returns(1) 187 .done() 188 .test().callSite(C, C, "m", "()I") 189 .returns(1) 190 .done(); 191 } 192 193 /* 194 * Override Abstract 195 * 196 * interface I { int m(); } 197 * interface J extends I { int m() default { return 1; } } 198 * interface K extends J {} 199 * class C implements K {} 200 * 201 * TEST: C c = new C(); c.m() == 1; 202 * TEST: K k = new C(); k.m() == 1; 203 */ testOverrideAbstract(TestBuilder b)204 public void testOverrideAbstract(TestBuilder b) { 205 Interface I = b.intf("I") 206 .abstractMethod("m", "()I").build() 207 .build(); 208 209 Interface J = b.intf("J").extend(I) 210 .defaultMethod("m", "()I").returns(1).build() 211 .build(); 212 213 Interface K = b.intf("K").extend(J).build(); 214 215 ConcreteClass C = b.clazz("C").implement(K).build(); 216 217 b.test() 218 .callSite(I, C, "m", "()I") 219 .returns(1) 220 .done() 221 .test() 222 .callSite(J, C, "m", "()I") 223 .returns(1) 224 .done() 225 .test() 226 .callSite(K, C, "m", "()I") 227 .returns(1) 228 .done() 229 .test() 230 .callSite(C, C, "m", "()I") 231 .returns(1) 232 .done(); 233 } 234 235 /* 236 * Default vs Concrete 237 * 238 * interface I { int m() default { return 1; } } 239 * class C implements I { public int m() { return 2; } } 240 * 241 * TEST: [C|I] c = new C(); c.m() == 2; 242 */ testDefaultVsConcrete(TestBuilder b)243 public void testDefaultVsConcrete(TestBuilder b) { 244 Interface I = b.intf("I") 245 .defaultMethod("m", "()I").returns(1).build() 246 .build(); 247 248 ConcreteClass C = b.clazz("C").implement(I) 249 .concreteMethod("m", "()I").returns(2).build() 250 .build(); 251 252 b.test() 253 .callSite(I, C, "m", "()I") 254 .returns(2) 255 .done() 256 .test() 257 .callSite(C, C, "m", "()I") 258 .returns(2) 259 .done(); 260 } 261 262 /* 263 * InheritedDefault 264 * 265 * interface I { int m() default { return 1; } } 266 * class B implements I {} 267 * class C extends B {} 268 * 269 * TEST: [I|B|C] v = new C(); v.m() == 1; 270 */ testInheritedDefault(TestBuilder b)271 public void testInheritedDefault(TestBuilder b) { 272 Interface I = b.intf("I") 273 .defaultMethod("m", "()I").returns(1).build() 274 .build(); 275 276 ConcreteClass B = b.clazz("B").implement(I).build(); 277 ConcreteClass C = b.clazz("C").extend(B).build(); 278 279 b.test() 280 .callSite(I, C, "m","()I") 281 .returns(1) 282 .done() 283 .test() 284 .callSite(B, C, "m","()I") 285 .returns(1) 286 .done() 287 .test() 288 .callSite(C, C, "m","()I") 289 .returns(1) 290 .done(); 291 } 292 293 /* 294 * ExistingInherited 295 * 296 * interface I { int m() default { return 1; } } 297 * class B { public int m() { return 2; } } 298 * class C extends B implements I {} 299 * 300 * TEST: [I|B|C] v = new C(); v.m() == 2; 301 */ testExistingInherited(TestBuilder b)302 public void testExistingInherited(TestBuilder b) { 303 Interface I = b.intf("I") 304 .defaultMethod("m", "()I").returns(1).build() 305 .build(); 306 307 ConcreteClass B = b.clazz("B") 308 .concreteMethod("m", "()I").returns(2).build() 309 .build(); 310 311 ConcreteClass C = b.clazz("C").extend(B).implement(I).build(); 312 313 b.test() 314 .callSite(I, C, "m","()I") 315 .returns(2) 316 .done() 317 .test() 318 .callSite(B, C, "m","()I") 319 .returns(2) 320 .done() 321 .test() 322 .callSite(C, C, "m","()I") 323 .returns(2) 324 .done(); 325 } 326 327 /* 328 * ExistingInheritedOverride 329 * 330 * interface I { int m() default { return 1; } } 331 * class B implements I { public int m() { return 2; } } 332 * class C extends B { public int m() { return 3; } } 333 * 334 * TEST: [I|B|D] v = new C(); v.m() == 3; 335 */ testExistingInheritedOverride(TestBuilder b)336 public void testExistingInheritedOverride(TestBuilder b) { 337 Interface I = b.intf("I") 338 .defaultMethod("m", "()I").returns(1).build() 339 .build(); 340 341 ConcreteClass B = b.clazz("B").implement(I) 342 .concreteMethod("m", "()I").returns(2).build() 343 .build(); 344 345 ConcreteClass C = b.clazz("C").extend(B) 346 .concreteMethod("m", "()I").returns(3).build() 347 .build(); 348 349 b.test() 350 .callSite(I, C, "m","()I") 351 .returns(3) 352 .done() 353 .test() 354 .callSite(B, C, "m","()I") 355 .returns(3) 356 .done() 357 .test() 358 .callSite(C, C, "m","()I") 359 .returns(3) 360 .done(); 361 } 362 363 /* 364 * ExistingInheritedPlusDefault 365 * 366 * interface I { int m() default { return 11; } } 367 * interface J { int m() default { return 12; } } 368 * class C implements I { public int m() { return 21; } } 369 * class D extends C { public int m() { return 22; } } 370 * class E extends D implements J {} 371 * 372 * TEST: [I|J|C|D|J] v = new E(); v.m() == 22; 373 */ testExistingInheritedPlusDefault(TestBuilder b)374 public void testExistingInheritedPlusDefault(TestBuilder b) { 375 Interface I = b.intf("I") 376 .defaultMethod("m", "()I").returns(11).build() 377 .build(); 378 379 Interface J = b.intf("J") 380 .defaultMethod("m", "()I").returns(12).build() 381 .build(); 382 383 ConcreteClass C = b.clazz("C").implement(I) 384 .concreteMethod("m","()I").returns(21).build() 385 .build(); 386 387 ConcreteClass D = b.clazz("D").extend(C) 388 .concreteMethod("m", "()I").returns(22).build() 389 .build(); 390 391 ConcreteClass E = b.clazz("E").extend(D).implement(J) 392 .build(); 393 394 b.test() 395 .callSite(I, E, "m","()I") 396 .returns(22) 397 .done() 398 .test() 399 .callSite(J, E, "m","()I") 400 .returns(22) 401 .done() 402 .test() 403 .callSite(C, E, "m","()I") 404 .returns(22) 405 .done() 406 .test() 407 .callSite(D, E, "m","()I") 408 .returns(22) 409 .done() 410 .test() 411 .callSite(E, E, "m","()I") 412 .returns(22) 413 .done(); 414 } 415 416 /* 417 * InheritedWithConcrete 418 * 419 * interface I { int m() default { return 1; } } 420 * class B implements I {} 421 * class C extends B { public int m() { return 2; } } 422 * 423 * TEST: [I|B|C] v = new C(); v.m() == 2; 424 */ testInheritedWithConcrete(TestBuilder b)425 public void testInheritedWithConcrete(TestBuilder b) { 426 Interface I = b.intf("I") 427 .defaultMethod("m", "()I").returns(1).build() 428 .build(); 429 430 ConcreteClass B = b.clazz("B").implement(I).build(); 431 432 ConcreteClass C = b.clazz("C").extend(B) 433 .concreteMethod("m", "()I").returns(2).build() 434 .build(); 435 436 b.test() 437 .callSite(I, C, "m","()I") 438 .returns(2) 439 .done() 440 .test() 441 .callSite(B, C, "m","()I") 442 .returns(2) 443 .done() 444 .test() 445 .callSite(C, C, "m","()I") 446 .returns(2) 447 .done(); 448 } 449 450 /* 451 * InheritedWithConcreteAndImpl 452 * 453 * interface I { int m() default { return 1; } } 454 * class B implements I {} 455 * class C extends B implements I { public int m() { return 2; } } 456 * 457 * TEST: [I|B|C] v = new C(); v.m() == 2; 458 */ testInheritedWithConcreteAndImpl(TestBuilder b)459 public void testInheritedWithConcreteAndImpl(TestBuilder b) { 460 Interface I = b.intf("I") 461 .defaultMethod("m", "()I").returns(1).build() 462 .build(); 463 464 ConcreteClass B = b.clazz("B").implement(I).build(); 465 466 ConcreteClass C = b.clazz("C").extend(B) 467 .concreteMethod("m", "()I").returns(2).build() 468 .build(); 469 470 b.test() 471 .callSite(I, C, "m","()I") 472 .returns(2) 473 .done() 474 .test() 475 .callSite(B, C, "m","()I") 476 .returns(2) 477 .done() 478 .test() 479 .callSite(C, C, "m","()I") 480 .returns(2) 481 .done(); 482 } 483 484 /* 485 * Diamond 486 * 487 * interface I { int m() default { return 1; } } 488 * interface J extends I {} 489 * interface K extends I {} 490 * class C implements J, K {} 491 * 492 * TEST: [I|J|K|C] c = new C(); c.m() == 99 493 */ testDiamond(TestBuilder b)494 public void testDiamond(TestBuilder b) { 495 Interface I = b.intf("I") 496 .defaultMethod("m", "()I").returns(1).build() 497 .build(); 498 499 Interface J = b.intf("J").extend(I).build(); 500 Interface K = b.intf("K").extend(I).build(); 501 502 ConcreteClass C = b.clazz("C").implement(J,K) 503 .build(); 504 505 b.test() 506 .callSite(I, C, "m","()I") 507 .returns(1) 508 .done() 509 .test() 510 .callSite(J, C, "m","()I") 511 .returns(1) 512 .done() 513 .test() 514 .callSite(K, C, "m","()I") 515 .returns(1) 516 .done() 517 .test() 518 .callSite(C, C, "m","()I") 519 .returns(1) 520 .done(); 521 } 522 523 /* 524 * ExpandedDiamond 525 * 526 * interface I { int m() default { return 1; } } 527 * interface J extends I {} 528 * interface K extends I {} 529 * interface L extends I {} 530 * interface M extends I {} 531 * class C implements J, K, L, M {} 532 * 533 * TEST: [I|J|K|L|M|C] c = new C(); c.m() == 1 534 */ testExpandedDiamond(TestBuilder b)535 public void testExpandedDiamond(TestBuilder b) { 536 Interface I = b.intf("I") 537 .defaultMethod("m", "()I").returns(1).build() 538 .build(); 539 540 Interface J = b.intf("J").extend(I).build(); 541 Interface K = b.intf("K").extend(I).build(); 542 Interface L = b.intf("L").extend(I).build(); 543 Interface M = b.intf("M").extend(I).build(); 544 545 ConcreteClass C = b.clazz("C").implement(J,K,L,M) 546 .build(); 547 548 b.test() 549 .callSite(I, C, "m","()I") 550 .returns(1) 551 .done() 552 .test() 553 .callSite(J, C, "m","()I") 554 .returns(1) 555 .done() 556 .test() 557 .callSite(K, C, "m","()I") 558 .returns(1) 559 .done() 560 .test() 561 .callSite(L, C, "m","()I") 562 .returns(1) 563 .done() 564 .test() 565 .callSite(M, C, "m","()I") 566 .returns(1) 567 .done() 568 .test() 569 .callSite(C, C, "m","()I") 570 .returns(1) 571 .done(); 572 } 573 574 /* 575 * SelfFill w/ explicit bridge 576 * 577 * interface I<T> { int m(T t) default { return 1; } } 578 * class C implements I<C> { 579 * public int m(C s) { return 2; } 580 * public int m(Object o) { ... } 581 * } 582 * 583 * TEST: I i = new C(); i.m((Object)null) == 2; 584 * TEST: C c = new C(); c.m((Object)null) == 2; 585 * TEST: C c = new C(); c.m((C)null) == 2; 586 */ testSelfFillWithExplicitBridge(TestBuilder b)587 public void testSelfFillWithExplicitBridge(TestBuilder b) { 588 /* interface I<T> { ... */ 589 Interface I = b.intf("I").sig("<T:Ljava/lang/Object;>Ljava/lang/Object;") 590 /* default int m(T t) { return 1; } */ 591 .defaultMethod("m", "(Ljava/lang/Object;)I") 592 .sig("(TT;)I") 593 .returns(1) 594 .build() 595 .build(); 596 597 /* class C implements I<C> { ... */ 598 ConcreteClass C = b.clazz("C").implement(I) 599 .sig("Ljava/lang/Object;LI<LC;>;") 600 601 /* public int m(I i) { return 2; } */ 602 .concreteMethod("m","(LC;)I").returns(2).build() 603 604 /* bridge method for m(LI;)I */ 605 .concreteMethod("m","(Ljava/lang/Object;)I") 606 .flags(ACC_PUBLIC | ACC_BRIDGE | ACC_SYNTHETIC) 607 .returns(2) 608 .build() 609 .build(); 610 611 // I i = new C(); ... 612 b.test() 613 .callSite(I, C, "m", "(Ljava/lang/Object;)I") 614 .params(new NullParam()) 615 .returns(2) 616 .done() 617 // C c = new C(); ... 618 .test() 619 .callSite(C, C, "m", "(Ljava/lang/Object;)I") 620 .params(new NullParam()) 621 .returns(2) 622 .done() 623 .test() 624 .callSite(C, C, "m", "(LC;)I") 625 .params(new NullParam()) 626 .returns(2) 627 .done(); 628 } 629 630 /* 631 * interface I { int m() default { return 1; } } 632 * class C implements I { int m(int i) { return 2; } } 633 * 634 * TEST: C c = new C(); c.m(0) == 2; 635 * TEST: I i = new C(); i.m() == 1; 636 */ testMixedArity()637 public void testMixedArity() { 638 TestBuilder b = factory.getBuilder(); 639 640 Interface I = 641 b.intf("I") 642 .defaultMethod("m", "()I").returns(1) 643 .build() 644 .build(); 645 646 ConcreteClass C = 647 b.clazz("C").implement(I) 648 .concreteMethod("m", "(I)I").returns(2) 649 .build() 650 .build(); 651 652 b.test().callSite(I, C, "m", "()I") 653 .returns(1) 654 .build(); 655 b.test().callSite(C, C, "m", "(I)I").params(ICONST_0) 656 .returns(2) 657 .build(); 658 } 659 660 /* 661 * interface I { int m() default { return 1; } } 662 * interface J { int m(int i) default { return 2; } } 663 * class C implements I, J {} 664 * 665 * TEST: I i = new C(); i.m() == 1; i.m(0) ==> NSME 666 * TEST: J j = new C(); j.m() ==> NSME; j.m(0) == 2 667 * TEST: C c = new C(); c.m() == 1; c.m(0) == 2 668 */ testConflictingDefaultMixedArity1(TestBuilder b)669 public void testConflictingDefaultMixedArity1(TestBuilder b) { 670 Interface I = b.intf("I") 671 .defaultMethod("m", "()I").returns(1) 672 .build() 673 .build(); 674 675 Interface J = b.intf("J") 676 .defaultMethod("m", "(I)I").returns(2) 677 .build() 678 .build(); 679 680 ConcreteClass C = b.clazz("C").implement(I,J).build(); 681 682 683 // I i = new C(); ... 684 b.test().callSite(I, C, "m", "()I") 685 .returns(1) 686 .build(); 687 b.test().callSite(I, C, "m", "(I)I").params(ICONST_0) 688 .throws_(NoSuchMethodError.class) 689 .build(); 690 691 // J j = new C(); ... 692 b.test().callSite(J, C, "m", "()I") 693 .throws_(NoSuchMethodError.class) 694 .build(); 695 b.test().callSite(J, C, "m", "(I)I").params(ICONST_0) 696 .returns(2) 697 .build(); 698 699 // C c = new C(); ... 700 b.test().callSite(C, C, "m", "()I") 701 .returns(1) 702 .build(); 703 b.test().callSite(C, C, "m", "(I)I").params(ICONST_0) 704 .returns(2) 705 .build(); 706 } 707 708 /* 709 * interface I { int m() default { return 1; } } 710 * interface J { int m() default { return 2; } } 711 * class C implements I, J { 712 * int m(int i) { return 3; } 713 * } 714 * 715 * TEST: I i = new C(); i.m(0) ==> ICCE 716 * TEST: J j = new C(); j.m(0) ==> ICCE 717 * TEST: C c = new C(); c.m() ==> ICCE; c.m(0) == 3 718 */ testConflictingDefaultMixedArity2(TestBuilder b)719 public void testConflictingDefaultMixedArity2(TestBuilder b) { 720 Interface I = b.intf("I") 721 .defaultMethod("m", "()I").returns(1) 722 .build() 723 .build(); 724 725 Interface J = b.intf("J") 726 .defaultMethod("m", "()I").returns(2) 727 .build() 728 .build(); 729 730 ConcreteClass C = b.clazz("C").implement(I, J) 731 .concreteMethod("m", "(I)I").returns(3) 732 .build() 733 .build(); 734 735 // I i = new C(); ... 736 b.test().callSite(I, C, "m", "()I") 737 .throws_(IncompatibleClassChangeError.class) 738 .build(); 739 b.test().callSite(I, C, "m", "(I)I").params(ICONST_0) 740 .throws_(NoSuchMethodError.class) 741 .build(); 742 743 // J j = new C(); ... 744 b.test().callSite(J, C, "m", "()I") 745 .throws_(IncompatibleClassChangeError.class) 746 .build(); 747 b.test().callSite(J, C, "m", "(I)I").params(ICONST_0) 748 .throws_(NoSuchMethodError.class) 749 .build(); 750 751 // C c = new C(); ... 752 b.test().callSite(C, C, "m", "()I") 753 .throws_(IncompatibleClassChangeError.class) 754 .build(); 755 b.test().callSite(C, C, "m", "(I)I").params(ICONST_0) 756 .returns(3) 757 .build(); 758 } 759 760 /* In package1: 761 * package p1; 762 * interface I { 763 * default int m() { return 10; }; 764 * } 765 * public interface J extends I {}; 766 * 767 * In package2: 768 * class A implements p1.J {} 769 * A myA = new A; 770 * myA.m(); // should return 10 except for reflect mode, 771 * // throw IllegalAccessException with reflect mode 772 */ 773 testMethodResolvedInDifferentPackage(TestBuilder b)774 public void testMethodResolvedInDifferentPackage(TestBuilder b) { 775 Interface I = b.intf("p1.I").flags(~ACC_PUBLIC & ACC_PUBLIC) // make it package private 776 .defaultMethod("m", "()I").returns(10) 777 .build() 778 .build(); 779 780 Interface J = b.intf("p1.J").extend(I) 781 .build(); 782 783 ConcreteClass myA = b.clazz("p2.A").implement(J) 784 .build(); 785 if (!factory.getExecutionMode().equals("REFLECTION")) { 786 b.test() 787 .callSite(myA, myA, "m", "()I") 788 .returns(10) 789 .done(); 790 } else { 791 // -mode reflect will fail with IAE as expected 792 b.test() 793 .callSite(myA, myA, "m", "()I") 794 .throws_(IllegalAccessException.class) 795 .done(); 796 } 797 } 798 799 /* In package p1: 800 * package p1; 801 * interface I { 802 * public default int m() { return 12; }; 803 * } 804 * 805 * public class A implements I {} 806 * 807 * In package p2: 808 * package p2; 809 * public interface J { int m(); } 810 * 811 * public class B extends p1.A implements J { 812 * public int m() { return 13; } 813 * } 814 * 815 * Then: 816 * A myA = new B; 817 * myA.m(); // should return 13, not throw IllegalAccessError 818 */ 819 testMethodResolvedInLocalFirst(TestBuilder b)820 public void testMethodResolvedInLocalFirst(TestBuilder b) { 821 Interface I = b.intf("p1.I") 822 .defaultMethod("m", "()I").returns(12) 823 .build() 824 .build(); 825 826 ConcreteClass myA = b.clazz("p1.A").implement(I) 827 .build(); 828 829 Interface J = b.intf("p2.J").abstractMethod("m", "()I") 830 .build() 831 .build(); 832 833 ConcreteClass myB = b.clazz("p2.B").extend(myA).implement(J) 834 .concreteMethod("m", "()I").returns(13) 835 .build() 836 .build(); 837 838 b.test() 839 .callSite(myB, myB, "m", "()I") 840 .returns(13) 841 .done(); 842 } 843 } 844