<!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>