<div dir="ltr">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.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Apr 29, 2024 at 8:23 AM Øystein Myhre Andersen <<a href="mailto:o.myhre@gmail.com">o.myhre@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Proposal:<div><br></div><div>I defined a utility class:</div><div><br></div><div><div style="padding:0px 0px 0px 2px"><div style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><p style="margin:0px"><span style="color:rgb(127,0,85);font-weight:bold">public</span> <span style="color:rgb(127,0,85);font-weight:bold">abstract</span> <span style="color:rgb(127,0,85);font-weight:bold">class</span> ClassHierarchy {</p><p style="margin:0px">        <span style="color:rgb(127,0,85);font-weight:bold">private</span> <span style="color:rgb(127,0,85);font-weight:bold">static</span> Map<ClassDesc, ClassDesc> <span style="color:rgb(0,0,192);font-style:italic">classToSuperClass</span> = <span style="color:rgb(127,0,85);font-weight:bold">new</span> HashMap<ClassDesc, ClassDesc>();</p><p style="margin:0px">   <span style="color:rgb(127,0,85);font-weight:bold">private</span> <span style="color:rgb(127,0,85);font-weight:bold">static</span> Collection<ClassDesc> <span style="color:rgb(0,0,192);font-style:italic">interfaces</span> = <span style="color:rgb(127,0,85);font-weight:bold">new</span> Vector<ClassDesc>();</p><p style="margin:0px"><br></p><p style="margin:0px">        <span style="color:rgb(127,0,85);font-weight:bold">public</span> <span style="color:rgb(127,0,85);font-weight:bold">static</span> ClassHierarchyResolver getResolver() {</p><p style="margin:0px">            ClassHierarchyResolver <span style="color:rgb(106,62,62)">res</span> = ClassHierarchyResolver.<span style="font-style:italic">defaultResolver</span>()</p><p style="margin:0px">                              .orElse(ClassHierarchyResolver.<span style="font-style:italic">of</span>(<span style="color:rgb(0,0,192);font-style:italic">interfaces</span>, <span style="color:rgb(0,0,192);font-style:italic">classToSuperClass</span>));</p><p style="margin:0px">         <span style="color:rgb(127,0,85);font-weight:bold">return</span> <span style="color:rgb(106,62,62)">res</span>;</p><p style="margin:0px">     }</p><p style="margin:0px"><br></p><p style="margin:0px">     <span style="color:rgb(127,0,85);font-weight:bold">public</span> <span style="color:rgb(127,0,85);font-weight:bold">static</span> <span style="color:rgb(127,0,85);font-weight:bold">void</span> addClassToSuperClass(ClassDesc <span style="color:rgb(106,62,62)">cld</span>, ClassDesc <span style="color:rgb(106,62,62)">sup</span>) {</p><p style="margin:0px">         <span style="color:rgb(0,0,192);font-style:italic">classToSuperClass</span>.put(<span style="color:rgb(106,62,62)">cld</span>, <span style="color:rgb(106,62,62)">sup</span>);</p><p style="margin:0px">        }</p><p style="margin:0px">}</p><p style="margin:0px"></p></div></div></div><div><br></div><div> And built my class files with a method like:</div><div><br></div><div><div style="padding:0px 0px 0px 2px"><div style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><p style="margin:0px">    <span style="color:rgb(127,0,85);font-weight:bold">public</span> <span style="color:rgb(127,0,85);font-weight:bold">byte</span>[] buildClassFile() {</p><p style="margin:0px">                ClassDesc <span style="color:rgb(106,62,62)">CD_ThisClass</span> = ...</p><p style="margin:0px">            ClassDesc <span style="color:rgb(106,62,62)">CD_SuperClass</span> = ...</p><p style="margin:0px"><span style="font-size:10pt">              ClassHierarchy.</span><span style="font-size:10pt;font-style:italic">addClassToSuperClass</span><span style="font-size:10pt">(</span><span style="font-size:10pt;color:rgb(106,62,62)">CD_ThisClass</span><span style="font-size:10pt">, </span><span style="color:rgb(106,62,62)">CD_SuperClass</span><span style="font-size:10pt">);</span><br></p><p style="margin:0px">               </p><p style="margin:0px">                <span style="color:rgb(127,0,85);font-weight:bold">byte</span>[] <span style="color:rgb(106,62,62)">bytes</span> = ClassFile.<span style="font-style:italic">of</span>(ClassFile.ClassHierarchyResolverOption</p><p style="margin:0px">                                        .<span style="font-style:italic">of</span>(ClassHierarchy.<span style="font-style:italic">getResolver</span>())).build(<span style="color:rgb(106,62,62)">CD_ThisClass</span>,</p><p style="margin:0px">                         <span style="color:rgb(106,62,62)">classBuilder</span> -> {</p><p style="margin:0px">                                    <span style="color:rgb(106,62,62)">classBuilder</span></p><p style="margin:0px"><span style="font-size:10pt">                                               .withSuperclass(</span><span style="color:rgb(106,62,62)">CD_SuperClass</span><span style="font-size:10pt">);</span><br></p><p style="margin:0px"><span style="font-size:10pt">                                                ... ...</span></p><p style="margin:0px"></p></div></div></div><div><br></div><div><br></div><div>This could perhaps have been done internally  by letting   <span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap">.withSuperclass(</span><span style="font-family:Consolas;font-size:13.3333px;white-space:pre-wrap;color:rgb(106,62,62)">CD_SuperClass</span><span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap">);</span> </div><div>make a call ala  <span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap">ClassHierarchy.</span><span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap;font-style:italic">addClassToSuperClass</span><span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap">(</span><span style="font-family:Consolas;font-size:10pt;white-space:pre-wrap;color:rgb(106,62,62)">CD_ThisClass</span><span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap">, </span><span style="font-family:Consolas;font-size:13.3333px;white-space:pre-wrap;color:rgb(106,62,62)">CD_SuperClass</span><span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap">);</span><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Apr 29, 2024 at 2:39 PM Øystein Myhre Andersen <<a href="mailto:o.myhre@gmail.com" target="_blank">o.myhre@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I solved my problem by using: <span style="color:rgb(63,95,191);font-family:Consolas;font-size:10pt;white-space:pre-wrap">`ClassHierarchyResolver.defaultResolver().orElse(ClassHierarchyResolver.</span><div style="padding:0px 0px 0px 2px"><div style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><p style="margin:0px"><span style="color:rgb(63,95,191)"> of(Collection</span><span style="color:rgb(127,127,159)"><ClassDesc></span><span style="color:rgb(63,95,191)"> interfaces, Map<ClassDesc, ClassDesc> classToSuperClass))`</span></p><p style="margin:0px"><span style="color:rgb(34,34,34);font-family:Arial,Helvetica,sans-serif;font-size:small;white-space:normal">However; since I do not have any interfaces I got an error with interfaces == null. And the javadoc could state which ClassDesc argument to  </span><span style="color:rgb(63,95,191);font-size:10pt">Map<ClassDesc, ClassDesc> classToSuperClass)</span><span style="color:rgb(34,34,34);font-family:Arial,Helvetica,sans-serif;font-size:small;white-space:normal"> is the super.</span></p>
</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Apr 29, 2024 at 1:57 PM - <<a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">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.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Apr 29, 2024 at 2:54 AM Adam Sotona <<a href="mailto:adam.sotona@oracle.com" target="_blank">adam.sotona@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>





<div lang="EN-US">
<div>
<p class="MsoNormal"><span style="font-size:11pt">Your compiler reached the complexity where you reference generated classes from other generated classes.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">Class-File API in certain circumstances needs to know some information about the classes referenced from the generated bytecode.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">Such information is provided in
<a href="https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/classfile/ClassHierarchyResolver.ClassHierarchyInfo.html" target="_blank">
ClassHierarchyInfo</a> using functional interface <a href="https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/classfile/ClassHierarchyResolver.html" target="_blank">
ClassHierarchyResolver</a>.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">By <a href="https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/classfile/ClassHierarchyResolver.html#defaultResolver()" target="_blank">
default</a> is the information obtained from system class loader. However, the classes you generate are probably not yet known to the system class loader.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">You should specify a custom <a href="https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/classfile/ClassHierarchyResolver.html" target="_blank">
ClassHierarchyResolver</a> for your compiler as a Class-File API option `ClassFile.of(ClassFile.ClassHierarchyResolverOption.of(...))`.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">Here you have multiple options how to provide the missing information using combinations of ClassHierarchyResolver factory methods and custom code:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">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:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">`ClassHierarchyResolver.defaultResolver().orElse(ClassHierarchyResolver.</span>
<span style="font-size:11pt">ofResourceParsing(Function<ClassDesc, InputStream>).cached())`<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">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:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">`ClassHierarchyResolver.defaultResolver().orElse(ClassHierarchyResolver.</span>
<span style="font-size:11pt">of(Collection<ClassDesc> interfaces, Map<ClassDesc, ClassDesc> classToSuperClass))`
<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">Or in a form of dynamic direct implementation of the ClassHierarchyResolver:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt">`ClassHierarchyResolver.defaultResolver().orElse(classDesc -> isInterface ? : ClassHierarchyInfo.ofInterface() : ClassHierarchyInfo.ofClass(ClassDesc superClass))`<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p>
<div id="m_-8124310123631038959m_-6022737954452480330m_-2821755067456243317m_3427014741105261579mail-editor-reference-message-container">
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(181,196,223);padding:3pt 0in 0in">
<p class="MsoNormal" style="margin-bottom:12pt"><b><span style="color:black">From:
</span></b><span style="color:black">classfile-api-dev <<a href="mailto:classfile-api-dev-retn@openjdk.org" target="_blank">classfile-api-dev-retn@openjdk.org</a>> on behalf of Øystein Myhre Andersen <<a href="mailto:o.myhre@gmail.com" target="_blank">o.myhre@gmail.com</a>><br>
<b>Date: </b>Sunday, 28 April 2024 at 12:53<br>
<b>To: </b><a href="mailto:classfile-api-dev@openjdk.org" target="_blank">classfile-api-dev@openjdk.org</a> <<a href="mailto:classfile-api-dev@openjdk.org" target="_blank">classfile-api-dev@openjdk.org</a>><br>
<b>Subject: </b>Got: IllegalArgumentException: Could not resolve class<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal">I'm writing a compiler for Simula (the very first oo language).<br>
Simula is block-oriented with nested blocks and each block is compiled into a classFile.<br>
At a certain level in the hierarchy I get an exception at the end of the classfile building.<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Exception in thread "main" java.lang.IllegalArgumentException:<br>
             Could not resolve class adHoc000_adHoc000_PBLK39_Floor_activateIdleLift<br>
<br>
at java.base/jdk.internal.classfile.impl.ClassHierarchyImpl.resolve(ClassHierarchyImpl.java:75)<br>
at java.base/jdk.internal.classfile.impl.ClassHierarchyImpl.isInterface(ClassHierarchyImpl.java:85)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator$Type.mergeReferenceFrom(StackMapGenerator.java:1363)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator$Type.mergeFrom(StackMapGenerator.java:1331)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator$Frame.merge(StackMapGenerator.java:1193)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator$Frame.checkAssignableTo(StackMapGenerator.java:1135)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator.checkJumpTarget(StackMapGenerator.java:280)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator.processExceptionHandlerTargets(StackMapGenerator.java:678)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator.processBlock(StackMapGenerator.java:667)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator.processMethod(StackMapGenerator.java:440)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator.generate(StackMapGenerator.java:317)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator.<init>(StackMapGenerator.java:243)<br>
at java.base/jdk.internal.classfile.impl.StackMapGenerator.of(StackMapGenerator.java:156)<br>
at java.base/jdk.internal.classfile.impl.DirectCodeBuilder$4.generateStackMaps(DirectCodeBuilder.java:331)<br>
at java.base/jdk.internal.classfile.impl.DirectCodeBuilder$4.tryGenerateStackMaps(DirectCodeBuilder.java:340)<br>
at java.base/jdk.internal.classfile.impl.DirectCodeBuilder$4.writeBody(DirectCodeBuilder.java:382)<br>
at java.base/jdk.internal.classfile.impl.UnboundAttribute$AdHocAttribute.writeTo(UnboundAttribute.java:914)<br>
at java.base/jdk.internal.classfile.impl.AttributeHolder.writeTo(AttributeHolder.java:56)<br>
at java.base/jdk.internal.classfile.impl.DirectMethodBuilder.writeTo(DirectMethodBuilder.java:156)<br>
at java.base/jdk.internal.classfile.impl.BufWriterImpl.writeList(BufWriterImpl.java:207)<br>
at java.base/jdk.internal.classfile.impl.DirectClassBuilder.build(DirectClassBuilder.java:181)<br>
at java.base/jdk.internal.classfile.impl.ClassFileImpl.build(ClassFileImpl.java:114)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">... ...<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><br>
Is this a known problem?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">What am I doing wrong?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I am attaching a file with an edited trace leading up to the exception.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">- Øystein Myhre Andersen<u></u><u></u></p>
</div>
</div>
</div>
</div>
</div>
</div>

</div></blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>