Got: IllegalArgumentException: Could not resolve class

Øystein Myhre Andersen o.myhre at gmail.com
Mon Apr 29 13:23:24 UTC 2024


Proposal:

I defined a utility class:

public abstract class ClassHierarchy {

private static Map<ClassDesc, ClassDesc> classToSuperClass = new
HashMap<ClassDesc, ClassDesc>();

private static Collection<ClassDesc> interfaces = new Vector<ClassDesc>();


public static ClassHierarchyResolver getResolver() {

ClassHierarchyResolver res = ClassHierarchyResolver.defaultResolver()

.orElse(ClassHierarchyResolver.of(interfaces, classToSuperClass));

return res;

}


public static void addClassToSuperClass(ClassDesc cld, ClassDesc sup) {

classToSuperClass.put(cld, sup);

}

}


 And built my class files with a method like:

public byte[] buildClassFile() {

ClassDesc CD_ThisClass = ...

ClassDesc CD_SuperClass = ...

ClassHierarchy.addClassToSuperClass(CD_ThisClass, CD_SuperClass);

byte[] bytes = ClassFile.of(ClassFile.ClassHierarchyResolverOption

.of(ClassHierarchy.getResolver())).build(CD_ThisClass,

classBuilder -> {

classBuilder

.withSuperclass(CD_SuperClass);

... ...



This could perhaps have been done internally  by letting   .withSuperclass(
CD_SuperClass);
make a call ala  ClassHierarchy.addClassToSuperClass(CD_ThisClass,
CD_SuperClass);

On Mon, Apr 29, 2024 at 2:39 PM Øystein Myhre Andersen <o.myhre at gmail.com>
wrote:

> I solved my problem by using:
> `ClassHierarchyResolver.defaultResolver().orElse(ClassHierarchyResolver.
>
> of(Collection<ClassDesc> interfaces, Map<ClassDesc, ClassDesc>
> classToSuperClass))`
>
> However; since I do not have any interfaces I got an error with interfaces
> == null. And the javadoc could state which ClassDesc argument to  Map<ClassDesc,
> ClassDesc> classToSuperClass) is the super.
>
> On Mon, Apr 29, 2024 at 1:57 PM - <liangchenblue at gmail.com> wrote:
>
>> I think a compiler should avoid the use of defaultResolver() in the
>> resolver chain, as it adds a dependency on the compiler's runtime, while
>> the program may target another set of standard libraries (such as for an
>> older Java release). The dynamic direct implementation usually is the most
>> flexible if you may have unanticipated inputs, as ClassHierarchyResolver
>> implementations throw exceptions when they receive erroneous input class
>> descs.
>>
>> On Mon, Apr 29, 2024 at 2:54 AM Adam Sotona <adam.sotona at oracle.com>
>> wrote:
>>
>>> Your compiler reached the complexity where you reference generated
>>> classes from other generated classes.
>>>
>>> Class-File API in certain circumstances needs to know some information
>>> about the classes referenced from the generated bytecode.
>>>
>>> Such information is provided in ClassHierarchyInfo
>>> <https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/classfile/ClassHierarchyResolver.ClassHierarchyInfo.html>
>>> using functional interface ClassHierarchyResolver
>>> <https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/classfile/ClassHierarchyResolver.html>
>>> .
>>>
>>>
>>>
>>> By default
>>> <https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/classfile/ClassHierarchyResolver.html#defaultResolver()>
>>> is the information obtained from system class loader. However, the classes
>>> you generate are probably not yet known to the system class loader.
>>>
>>> You should specify a custom ClassHierarchyResolver
>>> <https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/classfile/ClassHierarchyResolver.html>
>>> for your compiler as a Class-File API option
>>> `ClassFile.of(ClassFile.ClassHierarchyResolverOption.of(...))`.
>>>
>>>
>>>
>>> Here you have multiple options how to provide the missing information
>>> using combinations of ClassHierarchyResolver factory methods and custom
>>> code:
>>>
>>>
>>>
>>> For example, if the required classes have been already generated and you
>>> can provide a physical access to them, you can compose the
>>> ClassHierarchyResolver this way:
>>>
>>> `ClassHierarchyResolver.defaultResolver().orElse(ClassHierarchyResolver. ofResourceParsing(Function<ClassDesc,
>>> InputStream>).cached())`
>>>
>>>
>>>
>>> Or if you know all the generated classes in advance, you can provide the
>>> missing info about the generated classes in a set and map form:
>>>
>>> `ClassHierarchyResolver.defaultResolver().orElse(ClassHierarchyResolver. of(Collection<ClassDesc>
>>> interfaces, Map<ClassDesc, ClassDesc> classToSuperClass))`
>>>
>>>
>>>
>>> Or in a form of dynamic direct implementation of the
>>> ClassHierarchyResolver:
>>>
>>> `ClassHierarchyResolver.defaultResolver().orElse(classDesc ->
>>> isInterface ? : ClassHierarchyInfo.ofInterface() :
>>> ClassHierarchyInfo.ofClass(ClassDesc superClass))`
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> *From: *classfile-api-dev <classfile-api-dev-retn at openjdk.org> on
>>> behalf of Øystein Myhre Andersen <o.myhre at gmail.com>
>>> *Date: *Sunday, 28 April 2024 at 12:53
>>> *To: *classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
>>> *Subject: *Got: IllegalArgumentException: Could not resolve class
>>>
>>> I'm writing a compiler for Simula (the very first oo language).
>>> Simula is block-oriented with nested blocks and each block is compiled
>>> into a classFile.
>>> At a certain level in the hierarchy I get an exception at the end of the
>>> classfile building.
>>>
>>>
>>>
>>> Exception in thread "main" java.lang.IllegalArgumentException:
>>>              Could not resolve class
>>> adHoc000_adHoc000_PBLK39_Floor_activateIdleLift
>>>
>>> at
>>> java.base/jdk.internal.classfile.impl.ClassHierarchyImpl.resolve(ClassHierarchyImpl.java:75)
>>> at
>>> java.base/jdk.internal.classfile.impl.ClassHierarchyImpl.isInterface(ClassHierarchyImpl.java:85)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator$Type.mergeReferenceFrom(StackMapGenerator.java:1363)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator$Type.mergeFrom(StackMapGenerator.java:1331)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator$Frame.merge(StackMapGenerator.java:1193)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator$Frame.checkAssignableTo(StackMapGenerator.java:1135)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator.checkJumpTarget(StackMapGenerator.java:280)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator.processExceptionHandlerTargets(StackMapGenerator.java:678)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator.processBlock(StackMapGenerator.java:667)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator.processMethod(StackMapGenerator.java:440)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator.generate(StackMapGenerator.java:317)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator.<init>(StackMapGenerator.java:243)
>>> at
>>> java.base/jdk.internal.classfile.impl.StackMapGenerator.of(StackMapGenerator.java:156)
>>> at
>>> java.base/jdk.internal.classfile.impl.DirectCodeBuilder$4.generateStackMaps(DirectCodeBuilder.java:331)
>>> at
>>> java.base/jdk.internal.classfile.impl.DirectCodeBuilder$4.tryGenerateStackMaps(DirectCodeBuilder.java:340)
>>> at
>>> java.base/jdk.internal.classfile.impl.DirectCodeBuilder$4.writeBody(DirectCodeBuilder.java:382)
>>> at
>>> java.base/jdk.internal.classfile.impl.UnboundAttribute$AdHocAttribute.writeTo(UnboundAttribute.java:914)
>>> at
>>> java.base/jdk.internal.classfile.impl.AttributeHolder.writeTo(AttributeHolder.java:56)
>>> at
>>> java.base/jdk.internal.classfile.impl.DirectMethodBuilder.writeTo(DirectMethodBuilder.java:156)
>>> at
>>> java.base/jdk.internal.classfile.impl.BufWriterImpl.writeList(BufWriterImpl.java:207)
>>> at
>>> java.base/jdk.internal.classfile.impl.DirectClassBuilder.build(DirectClassBuilder.java:181)
>>> at
>>> java.base/jdk.internal.classfile.impl.ClassFileImpl.build(ClassFileImpl.java:114)
>>>
>>> ... ...
>>>
>>>
>>> Is this a known problem?
>>>
>>> What am I doing wrong?
>>>
>>>
>>>
>>> I am attaching a file with an edited trace leading up to the exception.
>>>
>>>
>>>
>>> - Øystein Myhre Andersen
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20240429/b86c28d0/attachment-0001.htm>


More information about the classfile-api-dev mailing list