Skip to content

ClassLoader.defineClass throws incorrect exception (ClassFormatError instead of LinkageError) on duplicate class definition #24152

Description

@Shawn-Patrick-Star

Java -version output

openjdk version "1.8.0_492"
IBM Semeru Runtime Open Edition (build 1.8.0_492-b09)
Eclipse OpenJ9 VM (build 1.8.0_492-b09-openj9-0.59.0, JRE 1.8.0 Linux amd64-64-Bit Compressed References 20260428_1524 (JIT enabled, AOT enabled)
OpenJ9   - c53b6b93f4
OMR      - 6426f03fa
JCL      - 0a800bff02 based on jdk8u492-b09)

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

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();
    }
}

Steps to reproduce

  1. Compile the Test.java.
  2. Run with OpenJ9.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions