Got: IllegalArgumentException: Could not resolve class
-
liangchenblue at gmail.com
Mon Apr 29 13:37:37 UTC 2024
Since ClassHierarchyResolver is not a sealed interface, you can make your
own ClassHierarchy class non-utility and implement CHR and return the
correct ClassHierarchyInfo or throw IAE.
On Mon, Apr 29, 2024 at 8:23 AM Øystein Myhre Andersen <o.myhre at gmail.com>
wrote:
> 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/0ef4697f/attachment-0001.htm>
More information about the classfile-api-dev
mailing list