-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
11
-
x86_64
-
windows
ADDITIONAL SYSTEM INFORMATION :
ADDITIONAL SYSTEM INFORMATION :
OS:
Operating System Name: Windows 11
Operating System Architecture: amd64
Operating System Version: 10.0
OpenJDK version:
java version "1.8.0_441"
Java(TM) SE Runtime Environment (build 1.8.0_441-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.441-b07, mixed mode)
java version "11.0.26" 2025-01-21 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.26+7-LTS-187)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.26+7-LTS-187, mixed mode)
A DESCRIPTION OF THE PROBLEM :
Given a test case, we found that the execution results of this test case on different versions are different, the simplified test case can be found below. In summary, Hotspot(1.8.0_441) threw IncompatibleClassChangeError while the other threw AbstractMethodError.
REGRESSION : Last worked in version 11
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The following code can be used to generate the test cases(.class file) that reproduces the above process:
```java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class BytecodeUtil {
public static void main(String args[]) {
// create package
String baseDir = "./your_dir"; // your base dir
String packageName = "P0";
File folder = new File(baseDir + "/" + packageName);
folder.mkdirs();
String P0_I0_bytecodeInStr = "CAFEBABE00000034000F01000550302F49300700010100106A6176612F6C616E672F4F626A6563740700030100016D01001528294C6A6176612F6C616E672F496E74656765723B0100116A6176612F6C616E672F496E746567657207000703000000000100063C696E69743E010004284929560C000A000B0A0008000C010004436F64650601000200040000000000010001000500060001000E00000016000300010000000ABB0008591209B7000DB0000000000000" ;
String P0_C1_bytecodeInStr = "CAFEBABE00000034000E01000550302F43310700010100106A6176612F6C616E672F4F626A65637407000301000550302F493007000501000550302F49320700070100063C696E69743E0100032829560C0009000A0A0004000B010004436F64650021000200040002000600080000000100010009000A0001000D0000001100010001000000052AB7000CB1000000000000" ;
String P0_Helper_bytecodeInStr = "CAFEBABE00000034001901000950302F48656C7065720700010100106A6176612F6C616E672F4F626A6563740700030100063C696E69743E0100032829560C000500060A00040007010005676574433101000928294C50302F43313B01000550302F433107000B0A000C0007010005676574433301000928294C50302F43333B01000550302F43330700100A00110007010005676574433401000928294C50302F43343B01000550302F43340700150A00160007010004436F6465002100020004000000000004000100050006000100180000001100010001000000052AB70008B10000000000090009000A0001001800000016000200010000000ABB000C59B7000D4B2AB0000000000009000E000F0001001800000016000200010000000ABB001159B700124B2AB0000000000009001300140001001800000016000200010000000ABB001659B700174B2AB0000000000000" ;
String P0_I2_bytecodeInStr = "CAFEBABE00000034000F01000550302F49320700010100106A6176612F6C616E672F4F626A6563740700030100016D01001528294C6A6176612F6C616E672F496E74656765723B0100116A6176612F6C616E672F496E746567657207000703000000020100063C696E69743E010004284929560C000A000B0A0008000C010004436F64650601000200040000000000010001000500060001000E00000016000300010000000ABB0008591209B7000DB0000000000000" ;
String P0_C3_bytecodeInStr = "CAFEBABE00000034002D01000550302F43330700010100106A6176612F6C616E672F4F626A65637407000301000550302F49300700050100063C696E69743E0100032829560C000700080A000400090100047465737401001528294C6A6176612F6C616E672F496E74656765723B01000950302F48656C70657207000D010005676574433401000928294C50302F43343B0C000F00100A000E00110100016D0C0013000C0B000600140100046D61696E010016285B4C6A6176612F6C616E672F537472696E673B29560C000B000C0A000200180100106A6176612F6C616E672F53797374656D07001A0100036F75740100154C6A6176612F696F2F5072696E7453747265616D3B0C001C001D09001B001E01000E52657475726E2076616C75653A200800200100136A6176612F696F2F5072696E7453747265616D0700220100057072696E74010015284C6A6176612F6C616E672F537472696E673B29560C002400250A002300260100077072696E746C6E010015284C6A6176612F6C616E672F4F626A6563743B29560C002800290A0023002A010004436F646500210002000400010006000000030001000700080001002C0000001100010001000000052AB7000AB1000000000009000B000C0001002C00000017000100010000000BB800124B2AB900150100B0000000000009001600170001002C0000001E0003000200000012B800194CB2001F591221B600272BB6002BB1000000000000" ;
String P0_C4_bytecodeInStr = "CAFEBABE00000034000E01000550302F43340700010100106A6176612F6C616E672F4F626A65637407000301000550302F493007000501000550302F49350700070100063C696E69743E0100032829560C0009000A0A0004000B010004436F64650021000200040002000600080000000100010009000A0001000D0000001100010001000000052AB7000CB1000000000000" ;
String P0_I5_bytecodeInStr = "CAFEBABE00000034000F01000550302F49350700010100106A6176612F6C616E672F4F626A6563740700030100016D01001528294C6A6176612F6C616E672F496E74656765723B0100116A6176612F6C616E672F496E746567657207000703000000050100063C696E69743E010004284929560C000A000B0A0008000C010004436F64650601000200040000000000010001000500060001000E00000016000300010000000ABB0008591209B7000DB0000000000000" ;
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "I0.class")) {
byte[] P0_I0_bytecode = hexStringToByteArray(P0_I0_bytecodeInStr);
fos.write(P0_I0_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "C1.class")) {
byte[] P0_I0_bytecode = hexStringToByteArray(P0_C1_bytecodeInStr);
fos.write(P0_I0_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "Helper.class")) {
byte[] P0_Helper_bytecode = hexStringToByteArray(P0_Helper_bytecodeInStr);
fos.write(P0_Helper_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "I2.class")) {
byte[] P0_I2_bytecode = hexStringToByteArray(P0_I2_bytecodeInStr);
fos.write(P0_I2_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "C3.class")) {
byte[] P0_C3_bytecode = hexStringToByteArray(P0_C3_bytecodeInStr);
fos.write(P0_C3_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "C4.class")) {
byte[] P0_C4_bytecode = hexStringToByteArray(P0_C4_bytecodeInStr);
fos.write(P0_C4_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "I5.class")) {
byte[] P0_I5_bytecode = hexStringToByteArray(P0_I5_bytecodeInStr);
fos.write(P0_I5_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
}
public static byte[] hexStringToByteArray(String hexString) {
int length = hexString.length();
byte[] byteArray = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
int byteValue = Integer.parseInt(hexString.substring(i, i + 2), 16);
byteArray[i / 2] = (byte) byteValue;
}
return byteArray;
}
}
```
Note: modify the paths according to your needs.
Repoduce:
>>> path_to_jdk/Hotspot_1.8.0_441/bin/java -cp . P0.C3
>>> path_to_jdk/Hotspot_11.0.26/bin/java -cp . P0.C3
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
According to this interesting result, we first decompiled P0.C3 using javap. The results are as follows:
```java
Classfile /D:/Lab/TestJDoc/JSmith-main/your_dir/P0/C3.class
Last modified May 12, 2025; size 539 bytes
MD5 checksum a0ff4ab4a79276d3a778adc7888a35bf
public class P0.C3 implements P0.I0
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Utf8 P0/C3
#2 = Class #1 // P0/C3
#3 = Utf8 java/lang/Object
#4 = Class #3 // java/lang/Object
#5 = Utf8 P0/I0
#6 = Class #5 // P0/I0
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = NameAndType #7:#8 // "<init>":()V
#10 = Methodref #4.#9 // java/lang/Object."<init>":()V
#11 = Utf8 test
#12 = Utf8 ()Ljava/lang/Integer;
#13 = Utf8 P0/Helper
#14 = Class #13 // P0/Helper
#15 = Utf8 getC4
#16 = Utf8 ()LP0/C4;
#17 = NameAndType #15:#16 // getC4:()LP0/C4;
#18 = Methodref #14.#17 // P0/Helper.getC4:()LP0/C4;
#19 = Utf8 m
#20 = NameAndType #19:#12 // m:()Ljava/lang/Integer;
#21 = InterfaceMethodref #6.#20 // P0/I0.m:()Ljava/lang/Integer;
#22 = Utf8 main
#23 = Utf8 ([Ljava/lang/String;)V
#24 = NameAndType #11:#12 // test:()Ljava/lang/Integer;
#25 = Methodref #2.#24 // P0/C3.test:()Ljava/lang/Integer;
#26 = Utf8 java/lang/System
#27 = Class #26 // java/lang/System
#28 = Utf8 out
#29 = Utf8 Ljava/io/PrintStream;
#30 = NameAndType #28:#29 // out:Ljava/io/PrintStream;
#31 = Fieldref #27.#30 // java/lang/System.out:Ljava/io/PrintStream;
#32 = Utf8 Return value:
#33 = String #32 // Return value:
#34 = Utf8 java/io/PrintStream
#35 = Class #34 // java/io/PrintStream
#36 = Utf8 print
#37 = Utf8 (Ljava/lang/String;)V
#38 = NameAndType #36:#37 // print:(Ljava/lang/String;)V
#39 = Methodref #35.#38 // java/io/PrintStream.print:(Ljava/lang/String;)V
#40 = Utf8 println
#41 = Utf8 (Ljava/lang/Object;)V
#42 = NameAndType #40:#41 // println:(Ljava/lang/Object;)V
#43 = Methodref #35.#42 // java/io/PrintStream.println:(Ljava/lang/Object;)V
#44 = Utf8 Code
{
public P0.C3();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: return
public static java.lang.Integer test();
descriptor: ()Ljava/lang/Integer;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=0
0: invokestatic #18 // Method P0/Helper.getC4:()LP0/C4;
3: astore_0
4: aload_0
5: invokeinterface #21, 1 // InterfaceMethod P0/I0.m:()Ljava/lang/Integer;
10: areturn
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=1
0: invokestatic #25 // Method test:()Ljava/lang/Integer;
3: astore_1
4: getstatic #31 // Field java/lang/System.out:Ljava/io/PrintStream;
7: dup
8: ldc #33 // String Return value:
10: invokevirtual #39 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
13: aload_1
14: invokevirtual #43 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
17: return
}
```
We observed that the call to `var0.m()` in `P0\C3.test()` uses `invokeinterface`. As a result, we reviewed the relevant sections on `invokeinterface` in both JVM SE8 and SE11.
In SE11, the [Method Selection](https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.4.6) rule states, "Otherwise, the maximally-specific superinterface methods of C are determined ([§5.4.3.3](https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.4.3.3)). If exactly one matches the method's name and descriptor and is not abstract, then it is the selected method." Therefore, the selected method should be `null` because two superinterface methods were found (`P0\I0.m()` and `P0\I5.m()`). According to the [SE11 `invokeinterface` specification](https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html#jvms-6.5.invokeinterface), "Otherwise, if no method is selected, and there are multiple maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not abstract, `invokeinterface` throws an `IncompatibleClassChangeError`." Therefore, the expected behavior in Hotspot (11.0.26) should be an `IncompatibleClassChangeError` rather than an `AbstractMethodError`.
ACTUAL -
The output is as follows:
Hotspot(1.8.0_441):
```
Exception in thread "main" java.lang.IncompatibleClassChangeError: Conflicting default methods: P0/I0.m P0/I5.m
at P0.C4.m(Unknown Source)
at P0.C3.test(Unknown Source)
at P0.C3.main(Unknown Source)
```
Hotspot(11.0.26):
```
Exception in thread "main" java.lang.AbstractMethodError: Receiver class P0.C4 does not define or inherit an implementation of the resolved method 'java.lang.Integer m()' of interface P0.I0.
at P0.C3.test(Unknown Source)
at P0.C3.main(Unknown Source)
```
---------- BEGIN SOURCE ----------
After obtaining the test cases, you can derive the following test cases through decompilation:
```java
package P0;
import java.io.PrintStream;
public class C3 implements I0 {
public C3() {
}
public static Integer test() {
C4 var0 = Helper.getC4();
return var0.m();
}
public static void main(String[] var0) {
Integer var1 = test();
PrintStream var10000 = System.out;
var10000.print("Return value: ");
var10000.println(var1);
}
}
```
```java
package P0;
public class C4 implements I0, I5 {
public C4() {
}
}
```
```java
package P0;
public interface I0 {
default Integer m() {
return new Integer(0);
}
}
```
```java
package P0;
public interface I5 {
default Integer m() {
return new Integer(5);
}
}
```
---------- END SOURCE ----------
ADDITIONAL SYSTEM INFORMATION :
OS:
Operating System Name: Windows 11
Operating System Architecture: amd64
Operating System Version: 10.0
OpenJDK version:
java version "1.8.0_441"
Java(TM) SE Runtime Environment (build 1.8.0_441-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.441-b07, mixed mode)
java version "11.0.26" 2025-01-21 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.26+7-LTS-187)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.26+7-LTS-187, mixed mode)
A DESCRIPTION OF THE PROBLEM :
Given a test case, we found that the execution results of this test case on different versions are different, the simplified test case can be found below. In summary, Hotspot(1.8.0_441) threw IncompatibleClassChangeError while the other threw AbstractMethodError.
REGRESSION : Last worked in version 11
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The following code can be used to generate the test cases(.class file) that reproduces the above process:
```java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class BytecodeUtil {
public static void main(String args[]) {
// create package
String baseDir = "./your_dir"; // your base dir
String packageName = "P0";
File folder = new File(baseDir + "/" + packageName);
folder.mkdirs();
String P0_I0_bytecodeInStr = "CAFEBABE00000034000F01000550302F49300700010100106A6176612F6C616E672F4F626A6563740700030100016D01001528294C6A6176612F6C616E672F496E74656765723B0100116A6176612F6C616E672F496E746567657207000703000000000100063C696E69743E010004284929560C000A000B0A0008000C010004436F64650601000200040000000000010001000500060001000E00000016000300010000000ABB0008591209B7000DB0000000000000" ;
String P0_C1_bytecodeInStr = "CAFEBABE00000034000E01000550302F43310700010100106A6176612F6C616E672F4F626A65637407000301000550302F493007000501000550302F49320700070100063C696E69743E0100032829560C0009000A0A0004000B010004436F64650021000200040002000600080000000100010009000A0001000D0000001100010001000000052AB7000CB1000000000000" ;
String P0_Helper_bytecodeInStr = "CAFEBABE00000034001901000950302F48656C7065720700010100106A6176612F6C616E672F4F626A6563740700030100063C696E69743E0100032829560C000500060A00040007010005676574433101000928294C50302F43313B01000550302F433107000B0A000C0007010005676574433301000928294C50302F43333B01000550302F43330700100A00110007010005676574433401000928294C50302F43343B01000550302F43340700150A00160007010004436F6465002100020004000000000004000100050006000100180000001100010001000000052AB70008B10000000000090009000A0001001800000016000200010000000ABB000C59B7000D4B2AB0000000000009000E000F0001001800000016000200010000000ABB001159B700124B2AB0000000000009001300140001001800000016000200010000000ABB001659B700174B2AB0000000000000" ;
String P0_I2_bytecodeInStr = "CAFEBABE00000034000F01000550302F49320700010100106A6176612F6C616E672F4F626A6563740700030100016D01001528294C6A6176612F6C616E672F496E74656765723B0100116A6176612F6C616E672F496E746567657207000703000000020100063C696E69743E010004284929560C000A000B0A0008000C010004436F64650601000200040000000000010001000500060001000E00000016000300010000000ABB0008591209B7000DB0000000000000" ;
String P0_C3_bytecodeInStr = "CAFEBABE00000034002D01000550302F43330700010100106A6176612F6C616E672F4F626A65637407000301000550302F49300700050100063C696E69743E0100032829560C000700080A000400090100047465737401001528294C6A6176612F6C616E672F496E74656765723B01000950302F48656C70657207000D010005676574433401000928294C50302F43343B0C000F00100A000E00110100016D0C0013000C0B000600140100046D61696E010016285B4C6A6176612F6C616E672F537472696E673B29560C000B000C0A000200180100106A6176612F6C616E672F53797374656D07001A0100036F75740100154C6A6176612F696F2F5072696E7453747265616D3B0C001C001D09001B001E01000E52657475726E2076616C75653A200800200100136A6176612F696F2F5072696E7453747265616D0700220100057072696E74010015284C6A6176612F6C616E672F537472696E673B29560C002400250A002300260100077072696E746C6E010015284C6A6176612F6C616E672F4F626A6563743B29560C002800290A0023002A010004436F646500210002000400010006000000030001000700080001002C0000001100010001000000052AB7000AB1000000000009000B000C0001002C00000017000100010000000BB800124B2AB900150100B0000000000009001600170001002C0000001E0003000200000012B800194CB2001F591221B600272BB6002BB1000000000000" ;
String P0_C4_bytecodeInStr = "CAFEBABE00000034000E01000550302F43340700010100106A6176612F6C616E672F4F626A65637407000301000550302F493007000501000550302F49350700070100063C696E69743E0100032829560C0009000A0A0004000B010004436F64650021000200040002000600080000000100010009000A0001000D0000001100010001000000052AB7000CB1000000000000" ;
String P0_I5_bytecodeInStr = "CAFEBABE00000034000F01000550302F49350700010100106A6176612F6C616E672F4F626A6563740700030100016D01001528294C6A6176612F6C616E672F496E74656765723B0100116A6176612F6C616E672F496E746567657207000703000000050100063C696E69743E010004284929560C000A000B0A0008000C010004436F64650601000200040000000000010001000500060001000E00000016000300010000000ABB0008591209B7000DB0000000000000" ;
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "I0.class")) {
byte[] P0_I0_bytecode = hexStringToByteArray(P0_I0_bytecodeInStr);
fos.write(P0_I0_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "C1.class")) {
byte[] P0_I0_bytecode = hexStringToByteArray(P0_C1_bytecodeInStr);
fos.write(P0_I0_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "Helper.class")) {
byte[] P0_Helper_bytecode = hexStringToByteArray(P0_Helper_bytecodeInStr);
fos.write(P0_Helper_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "I2.class")) {
byte[] P0_I2_bytecode = hexStringToByteArray(P0_I2_bytecodeInStr);
fos.write(P0_I2_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "C3.class")) {
byte[] P0_C3_bytecode = hexStringToByteArray(P0_C3_bytecodeInStr);
fos.write(P0_C3_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "C4.class")) {
byte[] P0_C4_bytecode = hexStringToByteArray(P0_C4_bytecodeInStr);
fos.write(P0_C4_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
try (FileOutputStream fos = new FileOutputStream(folder.getAbsolutePath() + "/" + "I5.class")) {
byte[] P0_I5_bytecode = hexStringToByteArray(P0_I5_bytecodeInStr);
fos.write(P0_I5_bytecode);
} catch (IOException e) {
e.printStackTrace();
}
}
public static byte[] hexStringToByteArray(String hexString) {
int length = hexString.length();
byte[] byteArray = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
int byteValue = Integer.parseInt(hexString.substring(i, i + 2), 16);
byteArray[i / 2] = (byte) byteValue;
}
return byteArray;
}
}
```
Note: modify the paths according to your needs.
Repoduce:
>>> path_to_jdk/Hotspot_1.8.0_441/bin/java -cp . P0.C3
>>> path_to_jdk/Hotspot_11.0.26/bin/java -cp . P0.C3
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
According to this interesting result, we first decompiled P0.C3 using javap. The results are as follows:
```java
Classfile /D:/Lab/TestJDoc/JSmith-main/your_dir/P0/C3.class
Last modified May 12, 2025; size 539 bytes
MD5 checksum a0ff4ab4a79276d3a778adc7888a35bf
public class P0.C3 implements P0.I0
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Utf8 P0/C3
#2 = Class #1 // P0/C3
#3 = Utf8 java/lang/Object
#4 = Class #3 // java/lang/Object
#5 = Utf8 P0/I0
#6 = Class #5 // P0/I0
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = NameAndType #7:#8 // "<init>":()V
#10 = Methodref #4.#9 // java/lang/Object."<init>":()V
#11 = Utf8 test
#12 = Utf8 ()Ljava/lang/Integer;
#13 = Utf8 P0/Helper
#14 = Class #13 // P0/Helper
#15 = Utf8 getC4
#16 = Utf8 ()LP0/C4;
#17 = NameAndType #15:#16 // getC4:()LP0/C4;
#18 = Methodref #14.#17 // P0/Helper.getC4:()LP0/C4;
#19 = Utf8 m
#20 = NameAndType #19:#12 // m:()Ljava/lang/Integer;
#21 = InterfaceMethodref #6.#20 // P0/I0.m:()Ljava/lang/Integer;
#22 = Utf8 main
#23 = Utf8 ([Ljava/lang/String;)V
#24 = NameAndType #11:#12 // test:()Ljava/lang/Integer;
#25 = Methodref #2.#24 // P0/C3.test:()Ljava/lang/Integer;
#26 = Utf8 java/lang/System
#27 = Class #26 // java/lang/System
#28 = Utf8 out
#29 = Utf8 Ljava/io/PrintStream;
#30 = NameAndType #28:#29 // out:Ljava/io/PrintStream;
#31 = Fieldref #27.#30 // java/lang/System.out:Ljava/io/PrintStream;
#32 = Utf8 Return value:
#33 = String #32 // Return value:
#34 = Utf8 java/io/PrintStream
#35 = Class #34 // java/io/PrintStream
#36 = Utf8 print
#37 = Utf8 (Ljava/lang/String;)V
#38 = NameAndType #36:#37 // print:(Ljava/lang/String;)V
#39 = Methodref #35.#38 // java/io/PrintStream.print:(Ljava/lang/String;)V
#40 = Utf8 println
#41 = Utf8 (Ljava/lang/Object;)V
#42 = NameAndType #40:#41 // println:(Ljava/lang/Object;)V
#43 = Methodref #35.#42 // java/io/PrintStream.println:(Ljava/lang/Object;)V
#44 = Utf8 Code
{
public P0.C3();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: return
public static java.lang.Integer test();
descriptor: ()Ljava/lang/Integer;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=0
0: invokestatic #18 // Method P0/Helper.getC4:()LP0/C4;
3: astore_0
4: aload_0
5: invokeinterface #21, 1 // InterfaceMethod P0/I0.m:()Ljava/lang/Integer;
10: areturn
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=1
0: invokestatic #25 // Method test:()Ljava/lang/Integer;
3: astore_1
4: getstatic #31 // Field java/lang/System.out:Ljava/io/PrintStream;
7: dup
8: ldc #33 // String Return value:
10: invokevirtual #39 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
13: aload_1
14: invokevirtual #43 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
17: return
}
```
We observed that the call to `var0.m()` in `P0\C3.test()` uses `invokeinterface`. As a result, we reviewed the relevant sections on `invokeinterface` in both JVM SE8 and SE11.
In SE11, the [Method Selection](https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.4.6) rule states, "Otherwise, the maximally-specific superinterface methods of C are determined ([§5.4.3.3](https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.4.3.3)). If exactly one matches the method's name and descriptor and is not abstract, then it is the selected method." Therefore, the selected method should be `null` because two superinterface methods were found (`P0\I0.m()` and `P0\I5.m()`). According to the [SE11 `invokeinterface` specification](https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html#jvms-6.5.invokeinterface), "Otherwise, if no method is selected, and there are multiple maximally-specific superinterface methods of C that match the resolved method's name and descriptor and are not abstract, `invokeinterface` throws an `IncompatibleClassChangeError`." Therefore, the expected behavior in Hotspot (11.0.26) should be an `IncompatibleClassChangeError` rather than an `AbstractMethodError`.
ACTUAL -
The output is as follows:
Hotspot(1.8.0_441):
```
Exception in thread "main" java.lang.IncompatibleClassChangeError: Conflicting default methods: P0/I0.m P0/I5.m
at P0.C4.m(Unknown Source)
at P0.C3.test(Unknown Source)
at P0.C3.main(Unknown Source)
```
Hotspot(11.0.26):
```
Exception in thread "main" java.lang.AbstractMethodError: Receiver class P0.C4 does not define or inherit an implementation of the resolved method 'java.lang.Integer m()' of interface P0.I0.
at P0.C3.test(Unknown Source)
at P0.C3.main(Unknown Source)
```
---------- BEGIN SOURCE ----------
After obtaining the test cases, you can derive the following test cases through decompilation:
```java
package P0;
import java.io.PrintStream;
public class C3 implements I0 {
public C3() {
}
public static Integer test() {
C4 var0 = Helper.getC4();
return var0.m();
}
public static void main(String[] var0) {
Integer var1 = test();
PrintStream var10000 = System.out;
var10000.print("Return value: ");
var10000.println(var1);
}
}
```
```java
package P0;
public class C4 implements I0, I5 {
public C4() {
}
}
```
```java
package P0;
public interface I0 {
default Integer m() {
return new Integer(0);
}
}
```
```java
package P0;
public interface I5 {
default Integer m() {
return new Integer(5);
}
}
```
---------- END SOURCE ----------
- relates to
-
JDK-8356941 IllegalAccessError in HotSpot Due to Incorrect Handling of Private Method
-
- Closed
-