<div dir="ltr"><div style="padding:0px 0px 0px 2px"><div style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre"><p style="margin:0px">It was possible to implement a re-try loop solution.</p><p style="margin:0px">But it did not turn out very pretty.</p><p style="margin:0px"><br></p><div style="padding:0px 0px 0px 2px"><div style="font-size:10pt"><p style="margin:0px">I would prefer a solution with implementing or instantiation of 'ClassHierarchyInfo'.</p><p style="margin:0px"><br></p><p style="margin:0px">Here is the snippet code:</p></div></div><p style="margin:0px"><br></p></div></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"><p style="margin:0px"><span style="color:rgb(127,0,85);font-weight:bold">int</span> <span style="color:rgb(106,62,62)">count</span> = 5;</p><p style="margin:0px"><span style="color:rgb(127,0,85);font-weight:bold">while</span>((<span style="color:rgb(106,62,62)">count</span>--) > 0) {</p><p style="margin:0px">     <span style="color:rgb(127,0,85);font-weight:bold">try</span> {</p><p style="margin:0px"><span style="font-size:10pt">              </span><span style="font-size:10pt;color:rgb(127,0,85);font-weight:bold">byte</span><span style="font-size:10pt">[] </span><span style="font-size:10pt;color:rgb(106,62,62)">bytes</span><span style="font-size:10pt"> = ClassFile.</span><span style="font-size:10pt;font-style:italic">of</span><span style="font-size:10pt">(ClassFile.ClassHierarchyResolverOption</span></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="font-size:10pt">               </span>... ... ...<span style="font-size:10pt">                           </span></p><p style="margin:0px"><span style="font-size:10pt">              );</span></p><p style="margin:0px"><span style="font-size:10pt">            </span><span style="font-size:10pt;color:rgb(127,0,85);font-weight:bold">return</span><span style="font-size:10pt">(</span><span style="font-size:10pt;color:rgb(106,62,62)">bytes</span><span style="font-size:10pt">);</span></p><p style="margin:0px">   } <span style="color:rgb(127,0,85);font-weight:bold">catch</span>(IllegalArgumentException <span style="color:rgb(106,62,62)">e</span>) {</p><p style="margin:0px"><span style="font-size:10pt">              </span><span style="font-size:10pt;color:rgb(127,0,85);font-weight:bold">boolean</span><span style="font-size:10pt"> </span><span style="font-size:10pt;color:rgb(106,62,62);background-color:rgb(240,216,168)">feasibleToReTry</span><span style="font-size:10pt"> = </span><span style="font-size:10pt;color:rgb(127,0,85);font-weight:bold">false</span><span style="font-size:10pt">;</span></p><p style="margin:0px">              String <span style="color:rgb(106,62,62)">msg</span> = <span style="color:rgb(106,62,62)">e</span>.getMessage();</p><p style="margin:0px"><span style="font-size:10pt">               </span><span style="font-size:10pt;color:rgb(127,0,85);font-weight:bold">if</span><span style="font-size:10pt">(</span><span style="font-size:10pt;color:rgb(106,62,62)">msg</span><span style="font-size:10pt">.startsWith(</span><span style="font-size:10pt;color:rgb(42,0,255)">"Could not resolve class"</span><span style="font-size:10pt">)) {</span></p><p style="margin:0px">                        String <span style="color:rgb(106,62,62)">classID</span> = <span style="color:rgb(106,62,62)">msg</span>.substring(24);</p><p style="margin:0px"><span style="font-size:10pt">                        ClassDesc </span><span style="font-size:10pt;color:rgb(106,62,62)">CD</span><span style="font-size:10pt"> = ClassHierarchy.</span><span style="font-size:10pt;font-style:italic">getClassDesc</span><span style="font-size:10pt">(</span><span style="font-size:10pt;color:rgb(106,62,62)">classID</span><span style="font-size:10pt">);</span></p><p style="margin:0px">                       <span style="color:rgb(127,0,85);font-weight:bold">if</span>(<span style="color:rgb(106,62,62)">CD</span> != <span style="color:rgb(127,0,85);font-weight:bold">null</span>) {</p><p style="margin:0px"><span style="font-size:10pt">                           ClassHierarchyResolver </span><span style="font-size:10pt;color:rgb(106,62,62)">resolver</span><span style="font-size:10pt"> = ClassHierarchy.</span><span style="font-size:10pt;font-style:italic">getResolver</span><span style="font-size:10pt">();</span></p><p style="margin:0px">                             ClassHierarchyInfo <span style="color:rgb(106,62,62)">classInfo</span> = <span style="color:rgb(106,62,62)">resolver</span>.getClassInfo(<span style="color:rgb(106,62,62)">CD</span>);</p><p style="margin:0px"><span style="font-size:10pt">                          </span><span style="font-size:10pt;color:rgb(106,62,62);background-color:rgb(240,216,168)">feasibleToReTry</span><span style="font-size:10pt"> = </span><span style="font-size:10pt;color:rgb(106,62,62)">classInfo</span><span style="font-size:10pt"> != </span><span style="font-size:10pt;color:rgb(127,0,85);font-weight:bold">null</span><span style="font-size:10pt">;</span></p><p style="margin:0px">                  }</p><p style="margin:0px"><span style="font-size:10pt">          }</span></p><p style="margin:0px"><span style="font-size:10pt">             </span><span style="font-size:10pt;color:rgb(127,0,85);font-weight:bold">if</span><span style="font-size:10pt">(</span><span style="font-size:10pt;color:rgb(106,62,62)">count</span><span style="font-size:10pt"> <= 0 || !</span><span style="font-size:10pt;color:rgb(106,62,62);background-color:rgb(212,212,212)">feasibleToReTry</span><span style="font-size:10pt">) </span><span style="font-size:10pt;color:rgb(127,0,85);font-weight:bold">throw</span><span style="font-size:10pt"> </span><span style="font-size:10pt;color:rgb(106,62,62)">e</span><span style="font-size:10pt">;</span></p><p style="margin:0px">      }</p><p style="margin:0px"><br></p><p style="margin:0px"></p></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Oct 19, 2024 at 8:16 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">But, it wasn't that simple !<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Oct 19, 2024 at 8:04 AM Ø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 think I can solve the problem with a 're-try loop'.<br><div>Something like this:<br></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">boolean</span> <span style="color:rgb(106,62,62)">done</span> = <span style="color:rgb(127,0,85);font-weight:bold">false</span>;</p><p style="margin:0px">   <span style="color:rgb(127,0,85);font-weight:bold">while</span>(! <span style="color:rgb(106,62,62)">done</span>) {</p><p style="margin:0px"></p></div></div><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px">               try {<br></p><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px">                       byte[] bytes = ClassFile.of(ClassFile.ClassHierarchyResolverOption.of(ClassHierarchy.getResolver())).build(CD_ThisClass,</p><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px"><br></p><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px">                  ...</p><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px">                   </p><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px">                        done = true;</p><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px">                        return(bytes);</p><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px">                } catch(Throwable e) {}</p><p style="color:rgb(0,0,0);font-family:Consolas;font-size:13.3333px;margin:0px">       }</p></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Oct 19, 2024 at 7:44 AM Ø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"><span style="padding:0px 0px 0px 2px"><span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap">I tried to implement 'ClassHierarchyInfo' but I got "Sealed type ClassHierarchyInfo cannot be super type</span></span><div><span style="padding:0px 0px 0px 2px"><span style="color:rgb(0,0,0);font-family:Consolas;font-size:10pt;white-space:pre-wrap"> of MyClassHierarchyInfo as it is from a different package or split package or module"</span></span><br></div><div><span style="padding:0px 0px 0px 2px"><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="font-size:10pt"> </span><br></p><p style="margin:0px">I misses a method to instantiate 'ClassHierarchyInfo' to deliver the result from 'getClassInfo' </p><p style="margin:0px"><br></p><p style="margin:0px">May be you should add a method like:</p><p style="margin:0px"><br></p><p style="margin:0px">     'static ClassHierarchyInfo of(ClassDesc subClass, ClassDesc superClass, boolean isInterface)'</p><p style="margin:0px"><br></p><p style="margin:0px">to the 'ClassHierarchyInfo'</p><p style="margin:0px"><br></p><p style="margin:0px">- <span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">Øystein</span></p></div></div></span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Oct 18, 2024 at 3:46 PM Chen Liang <<a href="mailto:chen.l.liang@oracle.com" target="_blank">chen.l.liang@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 dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Thanks for sharing Oystein. The problem is that ClassHierarchyResolver.of(Collection, Map) takes the immediate values in the argument and ignores subsequent updates, which is how most ClassFile APIs work, unfortunately. (The same thing happens if you try to
 do so for AnnotationValue.OfArray or RuntimeVisibleAnnotationsAttribute)</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
I recommend you return a <code>ClassHierarchyResolver</code> implementation of your own, that returns the real-time results from your ClassHierarchy static fields.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Regards, Chen</div>
<div id="m_6664801759928232881m_-6059752857672973802m_-4730768183408902178m_9136379127984587055appendonsend"></div>
<hr style="display:inline-block;width:98%">
<div id="m_6664801759928232881m_-6059752857672973802m_-4730768183408902178m_9136379127984587055divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> 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>Sent:</b> Friday, October 18, 2024 3:02 AM<br>
<b>To:</b> Chen Liang <<a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a>><br>
<b>Cc:</b> classfile-api-dev <<a href="mailto:classfile-api-dev@openjdk.org" target="_blank">classfile-api-dev@openjdk.org</a>><br>
<b>Subject:</b> Re: I got Exception: Could not resolve class</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div>Here is the link:<br>
</div>
<a href="https://github.com/portablesimula/SimulaCompiler2/blob/main/Simula/src/simula/compiler/utilities/ClassHierarchy.java" target="_blank">https://github.com/portablesimula/SimulaCompiler2/blob/main/Simula/src/simula/compiler/utilities/ClassHierarchy.java</a><br>
<div><br>
</div>
<div>I use:</div>
<div>openjdk version "24-ea" 2025-03-18<br>
OpenJDK Runtime Environment (build 24-ea+16-1800)<br>
OpenJDK 64-Bit Server VM (build 24-ea+16-1800, mixed mode, sharing)<br>
</div>
<div><br>
</div>
<div>- Øystein</div>
</div>
<br>
<div>
<div dir="ltr">On Fri, Oct 18, 2024 at 9:51 AM Chen Liang <<a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a>> wrote:<br>
</div>
<blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">Hi Øystein, can you share a link to your ClassHierarchy code? ClassFile API has a layer of caching for the ClassHierarchyResolver it uses, which can lead to it not updating to the latest information in your ClassHierarchy.
<div><br>
</div>
<div>Chen</div>
</div>
<br>
<div>
<div dir="ltr">On Fri, Oct 18, 2024 at 2:40 AM Øystein Myhre Andersen <<a href="mailto:o.myhre@gmail.com" target="_blank">o.myhre@gmail.com</a>> wrote:<br>
</div>
<blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<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">Below is a snippet of my code:</p>
<p style="margin:0px"><br>
</p>
<p style="margin:0px">public byte[] buildClassFile() {</p>
<p style="margin:0px">ClassDesc CD_ThisClass = currentClassDesc();</p>
<p style="margin:0px">ClassDesc CD_SuperClass = superClassDesc();</p>
<p style="margin:0px">ClassHierarchy.addClassToSuperClass(CD_ThisClass, CD_SuperClass);</p>
<p style="margin:0px">try {</p>
<p style="margin:0px">byte[] bytes = ClassFile.of(ClassFile.ClassHierarchyResolverOption.of(ClassHierarchy.getResolver())).build(CD_ThisClass,</p>
<p style="margin:0px"><br>
</p>
<p style="margin:0px">...</p>
<p style="margin:0px"></p>
<p style="margin:0px">return(bytes);</p>
<p style="margin:0px">} catch(Throwable e) {</p>
<p style="margin:0px">ClassHierarchyResolver resolver = ClassHierarchy.getResolver();</p>
<p style="margin:0px"></p>
<p style="margin:0px">ClassDesc <span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">
desc</span> = ClassDesc.of("simulaFEC.CLASS_CHECKER1_semchecker1_<span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">exp</span>");</p>
<p style="margin:0px">System.out.println("classInfo("+<span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">desc</span>+") = " + resolver.getClassInfo(<span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">desc</span>));</p>
<p style="margin:0px"><br>
</p>
<p style="margin:0px">e.printStackTrace();</p>
<p style="margin:0px">return null;</p>
<p style="margin:0px">}</p>
<p style="margin:0px">}</p>
<p style="margin:0px"></p>
<p style="margin:0px">When I run this code I get:</p>
<p style="margin:0px"><br>
</p>
<p style="margin:0px">classInfo(ClassDesc[CLASS_CHECKER1_semchecker1_<span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">exp</span>]) = ClassHierarchyInfoImpl[superClass=ClassDesc[RTS_CLASS], isInterface=false]</p>
<p style="margin:0px">java.lang.IllegalArgumentException: Could not resolve class CLASS_CHECKER1_semchecker1_<span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">exp</span></p>
<p style="margin:0px">at java.base/jdk.internal.classfile.impl.ClassHierarchyImpl.resolve(ClassHierarchyImpl.java:76)</p>
<p style="margin:0px">at java.base/jdk.internal.classfile.impl.ClassHierarchyImpl.isInterface(ClassHierarchyImpl.java:86)</p>
<p style="margin:0px">at java.base/jdk.internal.classfile.impl.StackMapGenerator$Type.mergeReferenceFrom(StackMapGenerator.java:1334)</p>
<p style="margin:0px">.....</p>
<p style="margin:0px"></p>
<p style="margin:0px"></p>
<p style="margin:0px">I use my own 'resolver' which answers that 'CLASS_CHECKER1_semchecker1_<span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">exp</span>' is a subclass of 'RTS_CLASS'.</p>
<p style="margin:0px">I don't understand this.</p>
<p style="margin:0px"><br>
</p>
<p style="margin:0px">- <span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">
Øystein</span> <span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">
Myhre</span> <span style="text-decoration-line:underline;text-decoration-style:wavy;text-decoration-color:rgb(255,128,64)">
Andersen</span></p>
<p style="margin:0px"></p>
</div>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</div>

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