diff --git a/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java b/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java
index 0f36ba48d33..bf842bf33d7 100644
--- a/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java
+++ b/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java
@@ -95,6 +95,13 @@ public class BytecodeDescriptor {
}
/**
+ * Parse a single type in a descriptor. Results can be:
+ *
+ * - A {@code Class} for successful parsing
+ *
- {@code null} for malformed descriptor format
+ *
- Throwing a {@link TypeNotPresentException} for valid class name,
+ * but class cannot be discovered
+ *
* @param loader the class loader in which to look up the types (null means
* bootstrap class loader)
*/
@@ -117,7 +124,8 @@ public class BytecodeDescriptor {
t = t.arrayType();
return t;
} else {
- return Wrapper.forBasicType(c).primitiveType();
+ var w = Wrapper.forPrimitiveTypeOrNull(c);
+ return w == null ? null : w.primitiveType();
}
}
diff --git a/src/java.base/share/classes/sun/invoke/util/Wrapper.java b/src/java.base/share/classes/sun/invoke/util/Wrapper.java
index 4e8beaabb34..361b35abfd8 100644
--- a/src/java.base/share/classes/sun/invoke/util/Wrapper.java
+++ b/src/java.base/share/classes/sun/invoke/util/Wrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -352,6 +352,19 @@ public enum Wrapper {
throw basicTypeError(type);
}
+ /**
+ * Return the primitive wrapper for the given char. Does not return
+ * {@code OBJECT}. Returns {@code null} to allow flexible error messages.
+ * Dedicated for {@link BytecodeDescriptor}.
+ */
+ static Wrapper forPrimitiveTypeOrNull(char type) {
+ Wrapper w = FROM_CHAR[(type + (type >> 1)) & 0xf];
+ if (w != null && w != OBJECT && w.basicTypeChar == type) {
+ return w;
+ }
+ return null;
+ }
+
@DontInline
private static RuntimeException basicTypeError(char type) {
for (Wrapper x : values()) {
diff --git a/test/jdk/java/lang/annotation/MalformedAnnotationTest.java b/test/jdk/java/lang/annotation/MalformedAnnotationTest.java
index 1276cb774ac..7047c125688 100644
--- a/test/jdk/java/lang/annotation/MalformedAnnotationTest.java
+++ b/test/jdk/java/lang/annotation/MalformedAnnotationTest.java
@@ -67,8 +67,8 @@ class MalformedAnnotationTest {
AnnotationElement.of("value", AnnotationValue.ofClass(clb
.constantPool().utf8Entry(badDescString))))
)));
- var cl = ByteCodeLoader.load("Test", bytes);
+ var cl = new ByteCodeLoader("Test", bytes, MalformedAnnotationTest.class.getClassLoader()).loadClass("Test");
var ex = assertThrows(GenericSignatureFormatError.class, () -> cl.getDeclaredAnnotation(ClassCarrier.class));
- assertTrue(ex.getMessage().contains(badDescString));
+ assertTrue(ex.getMessage().contains(badDescString), () -> "Uninformative error: " + ex);
}
}