<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    On 03/06/2024 12:14, Jonas Kunz wrote:<br>
    <blockquote type="cite" cite="mid:CAC3isYfkbLdqF4j9ikLP-DUgzH=3KjjmsBJPmPv26eGuRD+L2g@mail.gmail.com">
      
      <div dir="ltr"><br>
        I have some concerns regarding JEP 472 for javaagents. Many
        javaagents (such as the elastic APM agent) use functionality
        which is only available in JNI/JVMTI.<br>
        To do so, they typically ship native binaries embedded in the
        JAR for all platforms and load the matching one at runtime. This
        is done so that users can use a single javaagent JAR instead of
        having to select the correct native agent for their platform.
        <div>Typical use cases are for example loading a profiler (e.g.
          <a href="https://github.com/async-profiler/async-profiler" moz-do-not-send="true">async-profiler</a>) or enabling the
          JVMTI-only <a href="https://openjdk.org/jeps/331" moz-do-not-send="true">allocation profiling</a>.</div>
        <div><br>
        </div>
        <div>IIUC, such agents would now require kind of a "double
          opt-in":<br>
           * the user already added either the <span style="color:rgb(0,0,0);font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono","Luxi Mono","Courier New",monospace;font-size:13.3333px">-javaagent:..</span> or <span style="color:rgb(0,0,0);font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono","Luxi Mono","Courier New",monospace;font-size:13.3333px">-XX:+EnableDynamicAgentLoading</span> command
          line flags, giving the opt-in for the agent to break integrity</div>
        <div> * the user now needs to additionally add <span style="font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono","Luxi Mono","Courier New",monospace;color:rgb(0,0,0);font-size:13.3333px">--enable-native-access=some-vendor-module </span>because
          the agent loads JNI libraries</div>
        <div><br>
        </div>
        <div>I feel like this makes things unnecessarily complex for
          users, because with the explicit loading of the agent they
          already gave that agent the permission to break JVM integrity.</div>
        <div><br>
        </div>
        <div>In my opinion, for that reason there should be an escape
          hatch for javaagents, just like <a href="https://docs.oracle.com/javase%2F9%2Fdocs%2Fapi%2F%2F/java/lang/instrument/Instrumentation.html#redefineModule-java.lang.Module-java.util.Set-java.util.Map-java.util.Map-java.util.Set-java.util.Map-" moz-do-not-send="true">Instrumentation.redefineModule</a>
          which was added for Jigsaw.</div>
        <div>I'd propose to add a method <span style="color:rgb(0,0,0);font-family:"DejaVu Sans Mono","Bitstream Vera Sans Mono","Luxi Mono","Courier New",monospace;font-size:13.3333px">Instrumentation.enableNativeAccess(java.lang.Module)</span>,
          which is a copy of  <a href="https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/ModuleLayer.Controller.html#enableNativeAccess(java.lang.Module)" moz-do-not-send="true">ModuleLayer.Controller.enableNativeAccess(java.lang.Module)</a> but
          without requiring the caller module to be enabled for native
          access. The caller having access to an
          java.lang.instrument.Instrumentation instance should be
          sufficient.<br>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    Instrumentation.redefineModule is not really an escape hatch. It was
    introduced primarily to allow an agent augment readability for
    scenarios where an agent instruments code in one module to call into
    something in another module, usually a supporting library that is
    part of the agent.  An Instrumentation.enableNativeAccess (and JVMTI
    equivalent) would allow an agent to instrument code to make use of
    restricted methods, or invoke native methods, but it doesn't need
    that when it's done in the target method (it's the module containing
    the target class/method that would require native access).<br>
    <br>
    At things stands, there isn't any support for deploying Java agents
    as named modules so there isn't a value for "some-vendor-module",
    only ALL-UNNAMED will work. The issue with the equivalent of
    Enable-Native-Access in agent's JAR manifest is that it would be the
    equivalent of running with --enable-native-access=ALL-UNNAMED, a
    surprising side effect of running with -javaagent. I haven't
    personally come across Java agents that bring along a JNI library
    but it seems plausible, as is Java agents making use of restricted
    methods. So this does seems like something to be explored further
    but may in the context of agents deployed in named modules. JVM TI
    agents use JVM TI in conjunction with JNI but doing upcalls to
    invoke System.loadLibrary or bind native methods may be less likely
    there.<br>
    <br>
    -Alan.<br>
    <br>
  </body>
</html>