Conversion between Java objects and native pointers
Jorn Vernee
jorn.vernee at oracle.com
Sat Dec 3 17:59:03 UTC 2022
Note that in practice JNI also doesn't really allow you to pass objects
to native code, what it actually passes is object handles. Semantically
this is just a token that can be turned into an object again by the JNI
runtime later.
Something similar can be achieved with a simple object store [1]
static final ObjectStore STORE = new ObjectStore();
...
Object objectToPass = ...;
int token = STORE.allocate(objectToPass);
// pass 'token' to native code
... later:
int token = ...; // from native code
Object obj = STORE.resolve(token); // turn back into object
... when done:
STORE.free(token);
Of course this is a simple example, but this is the basic principle:
store your object in some store, and have a handle/token that you pass
to native code instead.
HTH,
Jorn
[1] :
Simple example of an object store:
public class ObjectStore {
private final Deque<Node> freeList =new ArrayDeque<>();
private final List<Node> store =new ArrayList<>();
public int allocate(Object obj) {
if (!freeList.isEmpty()) {
Node n =freeList.pop();
n.obj = obj;
return n.index;
}
int index =store.size();
store.add(new Node(index, obj));
return index;
}
public Object resolve(int token) {
return store.get(token).obj;
}
public void free(int token) {
Node n =store.get(token);
n.obj =null;
freeList.push(n);
}
private static class Node {
final int index;
Object obj;
public Node(int index,Object obj) {
this.index = index;
this.obj = obj;
}
}
}
On 02/12/2022 18:02, Maurizio Cimadamore wrote:
>
> On 02/12/2022 16:44, Gregory Klyushnikov wrote:
>> But since you say the decision to not allow native Java object
>> handles was intentional, I'll try it.
>
> Some background: if we start allowing Java instances being passed to
> native function, then we have to start worrying about the same class
> "spoofing" issues that JNI suffers from.
>
> That is, you can crete an handle for Foo in one class loader, then the
> handle is stored by the native code, and passed again to Java code in
> _another_ class loader, thus violating classloader constraints (maybe
> the class definition for Foo in that second class loader is different).
>
> For these reasons, JNI restricted library loading to a _single_ class
> loader. This restriction solves the spoofing issues, but comes at a
> price: any attempt to load same library from two loaders will fail.
> Frameworks have in the past resorted to various "tricks" (such as
> renaming libraries) to workaround this limitation.
>
> Since Panama doesn't allow passing Java objects _directly_ to native
> functions (you can pass memory segments, but they are either passed by
> reference - a long - or deconstructed into multiple primitive values
> which are then passed separately), it is not subject to same library
> loading limitations. That is, if you load a library with
> SymbolLookup::libraryLookup you can load it as many times as you like,
> from _any_ classloader you like. Which is nice to have.
>
> Of course I understand where you are coming from with this use case:
> you want to store an object pointer in the native code. We have
> considered APIs to allow developers to do that (e.g. temporarily turn
> a Java object into a native memory segment, controlled by a given
> memory session). But, as shown above, there are some safety
> consideration when going down that path.
>
> Now, in some cases, but not all, you can achieve a similar effect with
> the new scoped value feature:
>
> https://openjdk.org/jeps/429
>
> E.g. you could "bind" a ScopedValue object before the native call
> takes place, so that the receiver class is set to some known instance.
> The method handle you upcall to would read the ScopedValue, fetch the
> receiver instance, and dispatch to that.
>
> This would be more efficient than using a Map (as ScopedValues have
> caches) - but your usage has to be "structured" for ScopedValue to be
> usable.
>
> Anyway, I thought I'd mention the connection, in case it's useful (if
> not for this use case, for others).
>
> Cheers
> Maurizio
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20221203/14e7060b/attachment-0001.htm>
More information about the panama-dev
mailing list