<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>I want to caution a bit that, while the FFM API does allow
      loading the same library in multiple class loaders, the underlying
      OS library loader will _not_ load the same library twice, but
      instead keeps a reference count for each library, and increments
      it when it is loaded (again), and decrements it when it is unload.
      This can be demonstrated with the following example:</p>
    <p>lib.c:<br>
    </p>
    <p><font face="monospace">    int x;</font><br>
    </p>
    <p>Main.java:<br>
      <br>
      <span lang="IT"><font face="monospace">    SymbolLookup s1 =
          SymbolLookup.libraryLookup("lib.so", Arena.global());<br>
              MemorySegment x1 = s1.findOrThrow("x")<br>
                      .reinterpret(ValueLayout.JAVA_INT.byteSize());<br>
              SymbolLookup s2 = SymbolLookup.libraryLookup("lib.so",
          Arena.global());<br>
              MemorySegment x2 = s2.findOrThrow("x")<br>
                      .reinterpret(ValueLayout.JAVA_INT.byteSize());<br>
                  <br>
              x1.set(ValueLayout.JAVA_INT, 0L, 42);<br>
              System.out.println(x2.get(ValueLayout.JAVA_INT, 0L));</font></span></p>
    <p><span lang="IT">This program will print '42'. Note that this is a
        limitation of the operating system's library loader, combined
        with how the library is implemented.</span></p>
    <p>> <span lang="IT">The goal is that each object/tread
        parallely instantiate the same library but having isolated
        states, configurations and variables stored in a dedicated
        memory slot for each tread, so even if the C++ library maybe
        does not completely support cuncurrency itself it should attend
        multiple treads as it is virtually responding at once having one
        specific configuration per user.</span></p>
    <p><span lang="IT">In other words, what you seem to want here is not
        possible without either: 1. implementing a custom library loader
        that creates separate instances of the library in memory, or 2.
        changing the library so that each client can have a separate
        library state (this is typically done by the library returning
        some kind of 'handle', and then that handle is used in
        subsequent operations).</span></p>
    <p><span lang="IT">Jorn<br>
      </span></p>
    <div class="moz-cite-prefix">On 5-2-2025 10:50, Maurizio Cimadamore
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:160fdf2a-226b-45e6-b656-3452f89b7a65@oracle.com">
      
      <p>Hi Roberto,<br>
        by "singleton limitation" in JNA, I assume you refer to the fact
        that, in JNA (but also JNI) you can only load a native library
        once, by only one classloader. Correct?</p>
      <p>If that's the limitation you are trying to workaround, then
        yes, FFM allows you to load the same native library multiple
        times using its SymbolLookup abstraction. Make sure to use the
        correct factory -- the one that does not rely on an association
        with the current classloader:</p>
      <p><a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/23/docs//api/java.base/java/lang/foreign/SymbolLookup.html#libraryLookup(java.lang.String,java.lang.foreign.Arena)" moz-do-not-send="true">https://docs.oracle.com/en/java/javase/23/docs//api/java.base/java/lang/foreign/SymbolLookup.html#libraryLookup(java.lang.String,java.lang.foreign.Arena)</a></p>
      <p>This is just a very thin wrapper around dlopen, so it will take
        whatever library name dlopen can resolve, and will also allow
        you to open the library multiple times. Note that the library
        will be unloaded when the provided arena is closed -- so ideally
        you could use one arena per client.</p>
      <p>Examples of Arena.ofConfined, or custom arenas can be found in
        the javadoc:</p>
      <p>* confined arena -
        <a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/23/docs//api/java.base/java/lang/foreign/package-summary.html" moz-do-not-send="true">https://docs.oracle.com/en/java/javase/23/docs//api/java.base/java/lang/foreign/package-summary.html</a><br>
      </p>
      <p>* custom arena -
        <a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/22/docs//api/java.base/java/lang/foreign/SymbolLookup.html#libraryLookup(java.lang.String,java.lang.foreign.Arena)" moz-do-not-send="true">https://docs.oracle.com/en/java/javase/22/docs//api/java.base/java/lang/foreign/SymbolLookup.html#libraryLookup(java.lang.String,java.lang.foreign.Arena)</a></p>
      <p>We also have some narrative documents on how to use memory
        segment and linker API here:</p>
      <p><a class="moz-txt-link-freetext" href="https://github.com/openjdk/panama-foreign/blob/foreign-memaccess%2Babi/doc/panama_memaccess.md" moz-do-not-send="true">https://github.com/openjdk/panama-foreign/blob/foreign-memaccess%2Babi/doc/panama_memaccess.md</a></p>
      <p><a class="moz-txt-link-freetext" href="https://github.com/openjdk/panama-foreign/blob/foreign-memaccess%2Babi/doc/panama_ffi.md" moz-do-not-send="true">https://github.com/openjdk/panama-foreign/blob/foreign-memaccess%2Babi/doc/panama_ffi.md</a></p>
      <p>And, if you want to know more on jextract, we have a
        comprehensive guide here:</p>
      <p><a class="moz-txt-link-freetext" href="https://github.com/openjdk/jextract/blob/master/doc/GUIDE.md" moz-do-not-send="true">https://github.com/openjdk/jextract/blob/master/doc/GUIDE.md</a></p>
      <p><br>
        Cheers<br>
        Maurizio<br>
      </p>
      <div class="moz-cite-prefix">On 05/02/2025 00:03, <a class="moz-txt-link-abbreviated moz-txt-link-freetext" href="mailto:roberto.minoletti@trusthub.cloud" moz-do-not-send="true">roberto.minoletti@trusthub.cloud</a>
        wrote:<br>
      </div>
      <blockquote type="cite" cite="mid:!&!AAAAAAAAAAAuAAAAAAAAAExtYa3gpX5HoQdE6pcyVYEBAMO2jhD3dRHOtM0AqgC7tuYAAAAAAA4AABAAAADd+TEeumaRTZk1zPeQBgVaAQAAAAA=@trusthub.cloud">
        <meta name="Generator" content="Microsoft Word 15 (filtered medium)">
        <style>@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;}@font-face
        {font-family:Aptos;}p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-ligatures:standardcontextual;
        mso-fareast-language:EN-US;}span.EstiloCorreo18
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}.MsoChpDefault
        {mso-style-type:export-only;
        font-size:11.0pt;
        mso-ligatures:none;
        mso-fareast-language:EN-US;}div.WordSection1
        {page:WordSection1;}</style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
        <div class="WordSection1">
          <p class="MsoNormal">Hello Maurizio,<o:p></o:p></p>
          <p class="MsoNormal" style="text-indent:35.4pt">Thank you to
            provide the right contact of the Panama project (I reached
            to you in LinkedIn some days ago)<o:p></o:p></p>
          <p class="MsoNormal">I am writing to you on behalf of a
            backend development team that is trying to accomplish our
            requirements.<o:p></o:p></p>
          <p class="MsoNormal"><o:p> </o:p></p>
          <p class="MsoNormal">We need to interact from our java code
            (JDK21 that we can easely update to JDK23 if required and
            Spring Web-Flux) to a C++ library that allow to create
            Slots, generate Keypairs store Certificates simulating a
            real HSM (Hardware Security Module). This is named
            libsofthsm2.so (SoftHSM2).<o:p></o:p></p>
          <p class="MsoNormal"><span lang="IT">As I mentioned we
              customized this library as we need to store certificates
              and keys in a different path for each user. One important
              requirement is that we need to be able to process many
              requests coming from many different users to the same
              library that should operate in different paths at the same
              time.<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT">We preliminary resolved a
              POC using JNA but when tried to execute many parallel
              treads we faced with his singleton limitation and after a
              deep reasearch we founded Panama project.<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT"><o:p> </o:p></span></p>
          <p class="MsoNormal"><span lang="IT">Does Panama FFI support
              multiple parallel treads? Does it have any Singleton
              limitations?<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT">What we need is to get
              many objects/treads at the same time (paralley) loading
              its own different instance of the same library, getting
              its own memory context, variables and states, all
              completely isolated but working at the same time. This was
              not possible for us because JNA uses the Singleton pattern
              to load the library directly into the process, making it
              only possible to have a single instance of the library for
              the entire process.<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT"><o:p> </o:p></span></p>
          <p class="MsoNormal"><span lang="IT">The goal is that each
              object/tread parallely instantiate the same library but
              having isolated states, configurations and variables
              stored in a dedicated memory slot for each tread, so even
              if the C++ library maybe does not completely support
              cuncurrency itself it should attend multiple treads as it
              is virtually responding at once having one specific
              configuration per user.<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT"><o:p> </o:p></span></p>
          <p class="MsoNormal"><span lang="IT">What we are looking for
              is that each ARENA has access to libsofthsm2.so and its
              internal variables using that dedicated memory space to
              each tread to calculate the operations it must perform.<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT"><o:p> </o:p></span></p>
          <p class="MsoNormal"><span lang="IT">Does Panama FFI allow all
              this? This is the first basic question we have. After this
              we will be able to perform more specific questions.<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT">Also if you have any
              sample of code that use Arena.ofConfined() or any Custom
              Arena it would be really fantastic.<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT"><o:p> </o:p></span></p>
          <p class="MsoNormal"><span lang="IT">Thank you in advance for
              any information and/or support impelmenting Panama in our
              Project.<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT"><o:p> </o:p></span></p>
          <p class="MsoNormal"><span lang="IT">Roberto Minoletti<o:p></o:p></span></p>
          <p class="MsoNormal"><span lang="IT">Trusthub LLC<o:p></o:p></span></p>
        </div>
      </blockquote>
    </blockquote>
  </body>
</html>