<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:36.0pt;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle20
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:1219395089;
mso-list-template-ids:996996122;}
@list l0:level1
{mso-level-tab-stop:36.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level2
{mso-level-tab-stop:72.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level3
{mso-level-tab-stop:108.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level4
{mso-level-tab-stop:144.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level5
{mso-level-tab-stop:180.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level6
{mso-level-tab-stop:216.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level7
{mso-level-tab-stop:252.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level8
{mso-level-tab-stop:288.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level9
{mso-level-tab-stop:324.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
ol
{margin-bottom:0cm;}
ul
{margin-bottom:0cm;}
--></style>
</head>
<body lang="en-CZ" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt">New behavior is “no assumptions” and throw IllegalArgumentException if information about type necessary to build stack map (or verify stack map) is not obtained from the resolver (or better say
chain of resolvers). If user provides no resolver – the default is used. <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt">The way how default resolver gets the information from system classloader is subject of discussion below (resource parsing and fallback to class loading).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt">Custom resolver can be constructed as a fallback chain from all provided resolver types (including the default resolver instance).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt">On 20.03.2023 14:25, "Brian Goetz" <brian.goetz@oracle.com> wrote:<o:p></o:p></span></p>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:12.0pt;margin-left:36.0pt">
<span style="font-size:11.0pt"><br>
</span><span style="font-size:13.5pt;font-family:"Courier New"">If the user provides no resolver at all, what is the new behavior? Do we just assume Object is the common supertype for any pair of classes?</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt">On 3/20/2023 7:17 AM, Adam Sotona wrote:<o:p></o:p></span></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US" style="font-size:11.0pt">FYI: I’ve filled a new bug and proposed patch:
</span><b><span style="font-size:11.0pt"><a href="https://github.com/openjdk/jdk/pull/13099">8304502: Classfile API class hierarchy makes assumptions when class is not resolved #13099</a></span></b><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US" style="font-size:11.0pt">Thanks,</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US" style="font-size:11.0pt">Adam</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<div>
<p class="MsoNormal" style="margin-left:72.0pt"><span style="font-size:11.0pt">On 20.03.2023 10:50, "Adam Sotona"
<a href="mailto:adam.sotona@oracle.com"><adam.sotona@oracle.com></a> wrote:</span><o:p></o:p></p>
</div>
<p class="MsoNormal" style="margin-left:72.0pt"><span style="font-size:11.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">I agree with your concerns. The benevolence of the CHR was decision of an early development stage, it supposed to be temporary and now it is a clear bug.</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">So from my perspective - yes, fail fast and fail when any required class is not resolved.</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">Classfile API as well as ASM are designed to handle majority of cases without user knowledge of CHR or class loading details. I guess only few ASM users know how to
pass custom class loader for correct CHR for stack maps generation. I’ll try to summarize benefits and negatives of my proposal to extend default CHR to fall back to a class loading CHR.
</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">Benefits of CHR by classfile parsing:</span><o:p></o:p></p>
<p class="MsoListParagraph" style="margin-left:108.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2">
<![if !supportLists]><span style="mso-list:Ignore">1.<span style="font:7.0pt "Times New Roman"">
</span></span><![endif]><span lang="EN-US" style="font-size:11.0pt">Performance – “skip-parsing” of constant pool + classfile header is in order of magnitude faster than class loading</span><o:p></o:p></p>
<p class="MsoListParagraph" style="margin-left:108.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2">
<![if !supportLists]><span style="mso-list:Ignore">2.<span style="font:7.0pt "Times New Roman"">
</span></span><![endif]><span lang="EN-US" style="font-size:11.0pt">Simplicity/Stability – it is not necessary to provide all dependencies to identify if the type is an interface or what is its super. It is not necessary to have complete classpath with implementation
of some API to generate code using the API.</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">Negatives of CHR by classfile parsing:</span><o:p></o:p></p>
<p class="MsoListParagraph" style="margin-left:108.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2">
<![if !supportLists]><span style="mso-list:Ignore">3.<span style="font:7.0pt "Times New Roman"">
</span></span><![endif]><span lang="EN-US" style="font-size:11.0pt">Availability - a classfile may not be available or accessible as a resource for parsing</span><o:p></o:p></p>
<p class="MsoListParagraph" style="margin-left:108.0pt;text-indent:-18.0pt;mso-list:l0 level1 lfo2">
<![if !supportLists]><span style="mso-list:Ignore">4.<span style="font:7.0pt "Times New Roman"">
</span></span><![endif]><span lang="EN-US" style="font-size:11.0pt">Different results – a classfile may be modified when loaded, however the modification would have to change its super class or its status of being an interface to make any impact.</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">By adding a fallback to class loading CHR we will eliminate the “Availability“ negative, with no performance loose.</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">I think that the default should be rock-solid, because 99% of users will use the default.</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">Thanks,</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">Adam</span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt">BTW: Maybe even more beneficial would be an ability to question already loaded classes first (without loading them), parse them as resource if not already loaded and
fallback to load them if not available as resource. </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:72.0pt"><span lang="EN-US" style="font-size:11.0pt"> </span><o:p></o:p></p>
<div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt">On 18.03.2023 5:06, "Michael van Acken"
<a href="mailto:michael.van.acken@gmail.com"><michael.van.acken@gmail.com></a> wrote:</span><o:p></o:p></p>
</div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt"> </span><o:p></o:p></p>
<div>
<div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt">Am Fr., 17. März 2023 um 19:34 Uhr schrieb Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</a>>:</span><o:p></o:p></p>
</div>
<div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt">
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt">I'm not so comfortable adding this to DEFAULT_CHA. In addition to
<br>
adding another degree of environmental dependence, and the issues of <br>
additional exceptions you raise, I suspect it may also have a <br>
performance cost. I would like for programmers to opt into which CHA <br>
they use, and the default should be the most minimal. This means having <br>
a menu of CHAs to choose from, rather than guessing what the user wants.</span><o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt"> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt">The default classHierarchyResolver has an opaque (to me) error<br>
mode that tripped me up. Similar to my experience with ASM some<br>
years ago, it works fine for a lot (most?) of code, but then some<br>
input causes it to silently produce a stack map the verifier does<br>
not agree with. For me, this happens usually quite late in the<br>
game and at first is completely baffling. Back in July it was<br>
mostly luck and half buried memories that sent me into the<br>
direction of CHR as the solution to the verifier error. If the<br>
default CHR had raised an exception at the point where<br>
information was missing, the path to the fix (preloading the CHR<br>
with information about future classes) would have been clearer.</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt"> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt">--mva</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt"> </span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:108.0pt"><span style="font-size:11.0pt"> </span><o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt">
<p class="MsoNormal" style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:12.0pt;margin-left:108.0pt">
<span style="font-size:11.0pt"><br>
On 3/17/2023 2:25 PM, - wrote:<br>
> I've submitted a patch at <a href="https://urldefense.com/v3/__https:/github.com/openjdk/jdk/pull/13082__;!!ACWV5N9M2RV99hQ!IckIM3pDx0kj8-sYmKqh2mYHCcMDA3jEXIwOwzMAsirh8YKg1N949owV5wzMUHjA8_uF8Seb8GjSAMGhFN0zL4nTfIE$" target="_blank">
https://github.com/openjdk/jdk/pull/13082</a><br>
> Yet with it comes 3 questions:<br>
><br>
> 1. Should the resolver fail fast on IllegalAccessException from the<br>
> lookup? This usually indicates the hierarchy resolver is set up<br>
> improperly, and proceeding may simply yield verification errors in<br>
> class loading that are hard to track. For bytecode-generating APIs,<br>
> throwing access errors for the Lookup eagerly is also more preferable<br>
> than later silent generation failure.<br>
><br>
> The main concern for me to fail fast is that I don't understand how<br>
> the Classfile API propagates resolver exceptions. If wrapping the<br>
> IllegalAccessException in an IllegalAccessError is safe, then I may<br>
> change it and add a test case with HashMap.<br>
><br>
> 2. Whether the default resolver should be reading from jrt alone,<br>
> reflection alone, or jrt then reflection. I personally believe<br>
> reflection alone is more reliable, for classes may be redefined with<br>
> instrumentation or jfr, which may not be reflected in the system<br>
> resources.<br>
><br>
> This idea came to me while I was working on jfr and instrumentation<br>
> tests. Luckily, it seems they don't touch class hierarchy that the<br>
> default resolver suffices.<br>
><br>
> 3. In addition, I don't think chaining system class loader reflection<br>
> after system resource retrieval is really meaningful: is there any<br>
> case where reflection always works while the system resource retrieval<br>
> always fails?<br>
><br>
> Chen<br>
><br>
> On Fri, Mar 17, 2023 at 7:11 AM Adam Sotona <<a href="mailto:adam.sotona@oracle.com" target="_blank">adam.sotona@oracle.com</a>> wrote:<br>
>> I like your proposal and I would like to see it as a fallback solution for DEFAULT_CLASS_HIERARCHY_RESOLVER when the class is not available as resource stream.<br>
>><br>
>><br>
>><br>
>> /**<br>
>><br>
>> * Default singleton instance of {@linkplain ClassHierarchyResolver}<br>
>><br>
>> * using {@link ClassLoader#getSystemResourceAsStream(String)}<br>
>><br>
>> * as the {@code ClassStreamResolver} with fallback to<br>
>><br>
>> * {@link ClassLoader.getSystemClassLoader()} class loading resolver.<br>
>><br>
>> */<br>
>><br>
>> ClassHierarchyResolver DEFAULT_CLASS_HIERARCHY_RESOLVER<br>
>><br>
>> = new ClassHierarchyImpl.CachedClassHierarchyResolver(<br>
>><br>
>> new Function<ClassDesc, InputStream>() {<br>
>><br>
>> @Override<br>
>><br>
>> public InputStream apply(ClassDesc classDesc) {<br>
>><br>
>> return ClassLoader.getSystemResourceAsStream(Util.toInternalName(classDesc) + ".class");<br>
>><br>
>> }<br>
>><br>
>> }).orElse(ClassHierarchyResolver.of(ClassLoader.getSystemClassLoader()));<br>
>><br>
>><br>
>><br>
>> Thanks,<br>
>><br>
>> Adam<br>
>><br>
>><br>
>><br>
>> On 16.03.2023 17:05, "<a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a>" <<a href="mailto:liangchenblue@gmail.com" target="_blank">liangchenblue@gmail.com</a>> wrote:<br>
>><br>
>><br>
>><br>
>> For context, in 8294961<br>
>> <a href="https://urldefense.com/v3/__https:/github.com/openjdk/jdk/pull/10991/files*r1133086265__;Iw!!ACWV5N9M2RV99hQ!IckIM3pDx0kj8-sYmKqh2mYHCcMDA3jEXIwOwzMAsirh8YKg1N949owV5wzMUHjA8_uF8Seb8GjSAMGhFN0zkG4CkgE$" target="_blank">
https://github.com/openjdk/jdk/pull/10991/files#r1133086265</a> I wondered<br>
>> about whether to use a hierarchy resolver for LambdaMetafactory, that<br>
>> I think resolution may encounter problems as the default resolver may<br>
>> not be able to resolve user-supplied interfaces.<br>
>><br>
>> In addition, many of the class file generation usages I've seen<br>
>> include firing events via an event bus, calling patched external addon<br>
>> code (as seen in Minecraft modding), in which Reflection-based<br>
>> hierarchy resolution would work better than reading bytecode files.<br>
>><br>
>> Thus, I've prepared a patch creating ClassHierarchyResolver<br>
>> <a href="https://urldefense.com/v3/__https:/github.com/openjdk/jdk/commit/0c888ba1e2953cf946012244446f4f8c05ba5d77__;!!ACWV5N9M2RV99hQ!IckIM3pDx0kj8-sYmKqh2mYHCcMDA3jEXIwOwzMAsirh8YKg1N949owV5wzMUHjA8_uF8Seb8GjSAMGhFN0zl_RRNVo$" target="_blank">
https://github.com/openjdk/jdk/commit/0c888ba1e2953cf946012244446f4f8c05ba5d77</a><br>
>> to ease up resolution with reflection, when a ClassLoader (for older<br>
>> APIs) or a MethodHandle.Lookup (for modern APIs) is available.<br>
>><br>
>> Does this appear feasible?<br>
>><br>
>> Chen</span><o:p></o:p></p>
</blockquote>
</div>
</div>
</blockquote>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
</body>
</html>