JDK-8148854 : Class names "SomeClass" and "LSomeClass;" treated by JVM as an equivalent
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 8u65,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2015-12-31
  • Updated: 2021-04-09
  • Resolved: 2016-08-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9 Other
8u281Fixed 9 b137Fixed openjdk8u272Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8249970 :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)


FULL OS VERSION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
Constant pool entries of type "class" with class name "LClassName;"  (without quotes) are interpreted by JVM as a reference to the class "ClassName".

Here is an excerpt from constant pool as reported by javap:

  #15 = Utf8               LBadHelloWorld;
  #16 = Class              #15            // "LBadHelloWorld;"

The bytecode instruction

         0: new           #16                 // class "LBadHelloWorld;"

will actually instantiate class with name "BadHelloWorld".

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Yes

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run generator class that will generate problematic *.class file. 
See "Source code for an executable test case" field below for generator source.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected:
 - Some kind of verification and/or runtime error, probably "NoClassDefFoundError".

Actual:
 - Generated sample class file run without any visible problems.
REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
//
// !!! The ASM 5.x (http://asm.ow2.org/) library MUST be available in class path to compile and run the following code!
//

import java.util.*;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.objectweb.asm.*;

public class HelloWorldGen implements Opcodes {

    public static String GENERATED_CLASS_NAME = "BadHelloWorld";

	public static byte[] dump () throws Exception {

		ClassWriter cw = new ClassWriter(0);
		FieldVisitor fv;
		MethodVisitor mv;
		AnnotationVisitor av0;

		cw.visit(52, ACC_PUBLIC + ACC_SUPER, GENERATED_CLASS_NAME, null, "java/lang/Object", null);

		{
			mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
			mv.visitCode();
			mv.visitVarInsn(ALOAD, 0);
			mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
			mv.visitInsn(RETURN);
			mv.visitMaxs(1, 1);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
			mv.visitCode();
			mv.visitLdcInsn("Hello, world!");
			mv.visitInsn(ARETURN);
			mv.visitMaxs(1, 1);
			mv.visitEnd();
		}
		{
			mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC + ACC_VARARGS, "main", "([Ljava/lang/String;)V", null, null);
			mv.visitCode();
			mv.visitTypeInsn(NEW, "L" + GENERATED_CLASS_NAME + ";");
			mv.visitInsn(DUP);
			mv.visitMethodInsn(INVOKESPECIAL, "L" + GENERATED_CLASS_NAME + ";", "<init>", "()V", false);
			mv.visitVarInsn(ASTORE, 1);
			mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
			mv.visitVarInsn(ALOAD, 1);
			mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false);
			mv.visitInsn(RETURN);
			mv.visitMaxs(2, 2);
			mv.visitEnd();
		}
		cw.visitEnd();

		return cw.toByteArray();
	}

    public static void main(String... args) throws Exception {
        try (OutputStream out = Files.newOutputStream(Paths.get(GENERATED_CLASS_NAME + ".class"));) {
            out.write(dump());
        }
    }

}

---------- END SOURCE ----------


Comments
Approving this request for OpenJDK 8u and leaving it up to the developer to push it in 8u272 timeframe or 8u282 developement cycle.
05-08-2020

Fix Request (8u) I would like to backport this patch to 8u for parity with Oracle 8u281. The original patch does not apply cleanly. Code review: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2020-July/012282.html (Reviewed)
03-08-2020

Tested this issue on windows 7 and could reproduce the issue as reported by the submitter. Test Result: ########## OS: Windows 7 64-bit JDK: 8uXX Output: ###### c:\Abhijit\tools>javap -p -s -v BadHelloWorld.class Classfile /c:/Abhijit/tools/BadHelloWorld.class Last modified Feb 2, 2016; size 441 bytes MD5 checksum 15a00bf33fdff71fd649e9d909d17c11 public class BadHelloWorld minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Utf8 BadHelloWorld #2 = Class #1 // BadHelloWorld #3 = Utf8 java/lang/Object #4 = Class #3 // java/lang/Object #5 = Utf8 <init> #6 = Utf8 ()V #7 = NameAndType #5:#6 // "<init>":()V #8 = Methodref #4.#7 // java/lang/Object."<init>":()V #9 = Utf8 toString #10 = Utf8 ()Ljava/lang/String; #11 = Utf8 Hello, world! #12 = String #11 // Hello, world! #13 = Utf8 main #14 = Utf8 ([Ljava/lang/String;)V #15 = Utf8 LBadHelloWorld; #16 = Class #15 // "LBadHelloWorld;" #17 = Methodref #16.#7 // "LBadHelloWorld;"."<init>":()V #18 = Utf8 java/lang/System #19 = Class #18 // java/lang/System #20 = Utf8 out #21 = Utf8 Ljava/io/PrintStream; #22 = NameAndType #20:#21 // out:Ljava/io/PrintStream; #23 = Fieldref #19.#22 // java/lang/System.out:Ljava/io/PrintStream; #24 = Utf8 java/io/PrintStream #25 = Class #24 // java/io/PrintStream #26 = Utf8 println #27 = Utf8 (Ljava/lang/Object;)V #28 = NameAndType #26:#27 // println:(Ljava/lang/Object;)V #29 = Methodref #25.#28 // java/io/PrintStream.println:(Ljava/lang/Object;)V #30 = Utf8 Code { public BadHelloWorld(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return public java.lang.String toString(); descriptor: ()Ljava/lang/String; flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: ldc #12 // String Hello, world! 2: areturn public static void main(java.lang.String...); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS Code: stack=2, locals=2, args_size=1 0: new #16 // class "LBadHelloWorld;" 3: dup 4: invokespecial #17 // Method "LBadHelloWorld;"."<init>":()V 7: astore_1 8: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream; 11: aload_1 12: invokevirtual #29 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 15: return } c:\Abhijit\tools>
26-09-2016

If the trailing ";" is removed from constant pool entry 15 then the expected ClassNotFoundException is thrown for LBadHelloWorldHDS.
09-05-2016