<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">One possible compatibility
        issue is the exceptions that may be thrown.  Have we done a
        review to compare the exceptions thrown by Class::forName vs the
        substituted code?  </font></font><br>
    <br>
    <div class="moz-cite-prefix">On 9/28/2022 11:51 AM, Sonia Zaldana
      Calles wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CADo2k6uXfO9L=WG0TUgSthdsDkGnAZhuJjBGOx+zmOVMmjt5bA@mail.gmail.com">
      
      <div dir="ltr">
        <div><span style="background-color:transparent;color:rgb(0,0,0);font-family:Arial;font-size:11pt;white-space:pre-wrap">Hi folks, </span><br>
        </div>
        <div><span id="gmail-docs-internal-guid-642ba8c8-7fff-be5c-a34d-550cb1df331e">
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">
</span></p>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">In line with Dan’s previous investigation on bytecode transformations to modify Java’s dynamic behaviour, I have created a ClassForName JLink Plugin which translates the reflective operation </span><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-" style="text-decoration-line:none" moz-do-not-send="true"><span style="font-size:11pt;font-family:Arial;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">Class.forName</span></a><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> to the ldc bytecode instruction using the </span><a href="https://asm.ow2.io/" style="text-decoration-line:none" moz-do-not-send="true"><span style="font-size:11pt;font-family:Arial;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">ASM</span></a><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> library. </span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">The bytecode transformation switches out calls to Class.forName to ldc instructions for classes that are statically known, along with addressing the mismatch between Class.forName, which initialises the class by default, and ldc, which does not, by using </span><a href="https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/invoke/MethodHandles.Lookup.html#ensureInitialized(java.lang.Class)" style="text-decoration-line:none" moz-do-not-send="true"><span style="font-size:11pt;font-family:Arial;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">MethodHandles.Lookup.ensureInitialized</span></a><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">. </span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">For example, the bytecode sequence Class.forName(“com.sonia.hello.HelloWorld”) is transformed as shown below: </span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Original: </span></p>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><font size="1">0: ldc           #7                  // String com.sonia.hello.HelloWorld</font></span></p>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><font size="1">2: invokestatic  #9                  // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;</font></span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Transformed: </span></p>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><font size="1">0: invokestatic  #43 // Method java/lang/invoke/MethodHandles.lookup:()Ljava/lang/invoke/MethodHandles$Lookup;</font></span></p>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><font size="1">3: ldc           #45                 // class com/sonia/hello/HelloWorld</font></span></p>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><font size="1">5: invokevirtual #51 // Method java/lang/invoke/MethodHandles$Lookup.ensureInitialized:(Ljava/lang/Class;)Ljava/lang/Class;</font></span></p>
            <br>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">The plugin supports configuring two modes: global and module-aware. The module mode transforms Class.forName calls only when accessing a class accessible to the current module per the module graph, while the global mode transforms all classes regardless of readability. Note, class accessibility is determined per the </span><a href="http://cr.openjdk.java.net/~iris/se/18/latestSpec/java-se-18-jvms-fr-diffs.pdf" style="text-decoration-line:none" moz-do-not-send="true"><span style="font-size:11pt;font-family:Arial;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">JVMS 5.4.4</span></a><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> - a class must be public, its module must be read by the current class’s module and its package must be exported to the current class’s module.  There are slight differences between the language’s and the VM’s view of accessibility.</span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">We have also introduced an internal plugin called ModuleGraphPlugin which creates a single logical view of the module graph. This plugin separates the logic determining class readability and is queried by the ClassForName plugin to drive transformations. It doesn’t require further configuration from users as it is configured by default when using the ClassForName plugin.</span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">The ModuleGraphPlugin was separated out as it allows other plugins to share a common view of the module graph without needing to have each plugin process the module-info.java files.</span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">While a Class.forName JLink plugin previously existed (and was removed), it was limited to modifications within a module as it didn’t have the ModuleGraphPlugin-awareness of the full module graph.</span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">We don’t expect any performance improvement from this change itself, but we are expecting it to increase the ability of other future plugins to reason about application behaviour and to potentially help remove reflective operations in other contexts.</span></p>
            <br>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Find below the GitHub link with the changes: </span></p>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><a href="https://github.com/SoniaZaldana/jdk-sandbox/tree/classforname-plugin" style="text-decoration-line:none" moz-do-not-send="true"><span style="font-size:11pt;font-family:Arial;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">https://github.com/SoniaZaldana/jdk-sandbox/tree/classforname-plugin</span></a></p>
            <p dir="ltr" style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><br>
            </p>
            <p style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="color:rgb(0,0,0);font-family:Arial;font-size:14.6667px;white-space:pre-wrap">Thanks, </span><br>
            </p>
            <p style="text-align:left;line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="color:rgb(0,0,0);font-family:Arial;font-size:14.6667px;white-space:pre-wrap">Sonia</span></p>
            <br>
          </span></div>
      </div>
    </blockquote>
    <br>
  </body>
</html>