According to the Java Virtual Machine Specification (JVMS §5.3.5), attempting to define a class with the same name twice using the same ClassLoader instance must result in a LinkageError.
When dynamically loading a valid class bytecode twice via the same ClassLoader instance, HotSpot strictly follows the specification and throws a LinkageError, whereas OpenJ9 incorrectly throws a ClassFormatError.
public class Test extends ClassLoader {
private static int[] DATA = new int[] {
-54, -2, -70, -66, 0, 0, 0, 52, 0, 13,
10, 0, 3, 0, 10, 7, 0, 11, 7, 0,
12, 1, 0, 6, 60, 105, 110, 105, 116, 62,
1, 0, 3, 40, 41, 86, 1, 0, 4, 67,
111, 100, 101, 1, 0, 15, 76, 105, 110, 101,
78, 117, 109, 98, 101, 114, 84, 97, 98, 108,
101, 1, 0, 10, 83, 111, 117, 114, 99, 101,
70, 105, 108, 101, 1, 0, 18, 84, 101, 115,
116, 67, 97, 115, 101, 48, 48, 48, 48, 48,
46, 106, 97, 118, 97, 12, 0, 4, 0, 5,
1, 0, 13, 84, 101, 115, 116, 67, 97, 115,
101, 48, 48, 48, 48, 48, 1, 0, 16, 106,
97, 118, 97, 47, 108, 97, 110, 103, 47, 79,
98, 106, 101, 99, 116, 0, 32, 0, 2, 0,
3, 0, 0, 0, 0, 0, 1, 0, 0, 0,
4, 0, 5, 0, 1, 0, 6, 0, 0, 0,
29, 0, 1, 0, 1, 0, 0, 0, 5, 42,
-73, 0, 1, -79, 0, 0, 0, 1, 0, 7,
0, 0, 0, 6, 0, 1, 0, 0, 0, 1,
0, 1, 0, 8, 0, 0, 0, 2, 0, 9
};
public Test() {}
public void load() {
byte[] bytes = new byte[DATA.length];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) DATA[i];
}
defineClass(bytes, 0, bytes.length);
}
public static void main(String[] args) {
Test test = new Test();
test.load();
test.load();
}
}
Java -version output
Summary of problem
According to the Java Virtual Machine Specification (JVMS §5.3.5), attempting to define a class with the same name twice using the same ClassLoader instance must result in a LinkageError.
When dynamically loading a valid class bytecode twice via the same ClassLoader instance, HotSpot strictly follows the specification and throws a LinkageError, whereas OpenJ9 incorrectly throws a ClassFormatError.
Source Code
Steps to reproduce