Questions regarding JDK-8350938 (ResourceParsingClassHierarchyResolver)
Chen Liang
chen.l.liang at oracle.com
Thu Nov 6 05:01:25 UTC 2025
Hi Trevor, I think ClassFile.of is good for this particular purpose. There is nothing in the header parsing that the default class file handling options is not suitable for.
-Chen
________________________________
From: core-libs-dev <core-libs-dev-retn at openjdk.org> on behalf of Trevor Bond <trevorkbond at gmail.com>
Sent: Wednesday, November 5, 2025 9:56 PM
To: core-libs-dev at openjdk.org <core-libs-dev at openjdk.org>
Subject: Questions regarding JDK-8350938 (ResourceParsingClassHierarchyResolver)
Hi all,
I'm new to contributing to OpenJDK and have been working with Dan Smith as a mentor. I've been looking at JDK-8350938, which suggests refactoring ResourceParsingClassHierarchyResolver to avoid inflating all UTF8 constant pool entries by using ClassReaderImpl. ClassReaderImpl stores constant pool offsets and later lazily reads/inflates UTF8 entries as needed, so it seems to make sense to use here as a performance enhancement.
I have an initial prototype that removes manual parsing in getClassInfo() and instead constructs a ClassReaderImpl and uses its helper methods to return the needed class information.
One question before I try to move forward with contributing:
- ClassReaderImpl takes a ClassFile context. I used ClassFile.of() (a ClassFile context with default options). Is this the correct usage here, or should the resolver provide a more specific context?
I am also open to and would appreciate any other ideas or feedback on this implementation.
I’ve included the small patch below for reference.
Thanks for your help,
Trevor
diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java
index 5be14f42baa..463845ce612 100644
--- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java
+++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassHierarchyImpl.java
@@ -30,7 +30,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
+import java.lang.classfile.ClassFile;
import java.lang.classfile.ClassHierarchyResolver;
+import java.lang.classfile.ClassReader;
+import java.lang.classfile.constantpool.ClassEntry;
import java.lang.constant.ClassDesc;
import java.util.Collection;
import java.util.HashMap;
@@ -164,31 +167,12 @@ public ResourceParsingClassHierarchyResolver(Function<ClassDesc, InputStream> cl
public ClassHierarchyResolver.ClassHierarchyInfo getClassInfo(ClassDesc classDesc) {
var ci = streamProvider.apply(classDesc);
if (ci == null) return null;
- try (var in = new DataInputStream(new BufferedInputStream(ci))) {
- in.skipBytes(8);
- int cpLength = in.readUnsignedShort();
- String[] cpStrings = new String[cpLength];
- int[] cpClasses = new int[cpLength];
- for (int i = 1; i < cpLength; i++) {
- int tag;
- switch (tag = in.readUnsignedByte()) {
- case TAG_UTF8 -> cpStrings[i] = in.readUTF();
- case TAG_CLASS -> cpClasses[i] = in.readUnsignedShort();
- case TAG_STRING, TAG_METHOD_TYPE, TAG_MODULE, TAG_PACKAGE -> in.skipBytes(2);
- case TAG_METHOD_HANDLE -> in.skipBytes(3);
- case TAG_INTEGER, TAG_FLOAT, TAG_FIELDREF, TAG_METHODREF, TAG_INTERFACE_METHODREF,
- TAG_NAME_AND_TYPE, TAG_DYNAMIC, TAG_INVOKE_DYNAMIC -> in.skipBytes(4);
- case TAG_LONG, TAG_DOUBLE -> {
- in.skipBytes(8);
- i++;
- }
- default -> throw new IllegalStateException("Bad tag (" + tag + ") at index (" + i + ")");
- }
- }
- boolean isInterface = (in.readUnsignedShort() & ACC_INTERFACE) != 0;
- in.skipBytes(2);
- int superIndex = in.readUnsignedShort();
- var superClass = superIndex > 0 ? ClassDesc.ofInternalName(cpStrings[cpClasses[superIndex]]) : null;
+ try (ci) {
+ ClassReader reader = new ClassReaderImpl(ci.readAllBytes(), (ClassFileImpl) ClassFile.of());
+ boolean isInterface = (reader.flags() & ACC_INTERFACE) != 0;
+ ClassDesc superClass = reader.superclassEntry()
+ .map(ClassEntry::asSymbol)
+ .orElse(null);
return new ClassHierarchyInfoImpl(superClass, isInterface);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20251106/770accea/attachment.htm>
More information about the core-libs-dev
mailing list