Open nirvdrum opened 2 years ago
The C API has functions to managing isolates, but we want to discourage people from using it. Instead, people should use the JNI invocation API https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html to manage isolates. That is fully supported in Native Image, and it is well specified.
I'm sorry, I don't entirely follow what's being suggested here. Is @CEntryPoint
supposed to be replaced by CallStaticVoidMethod
? Is there a public example of using this invocation API?
Of course you can use JNI also to invoke functions, instead of using @CEntryPoint
. But we need to wait for OpenJDK project Panama to be finished before we can deprecate @CEntryPoint
because JNI has inherently higher overheads than the current low-level SVM C interface.
But your issue was not about that part - you are talking about the functions to create isolates and attach threads to the isolate. For that part, there is actually no good reason to use the low-level SVM API, as the JNI invocation API functions like JNI_CreateJavaVM
and AttachCurrentThread
do exactly that. Now that we fully support JNI, I want to guide people towards that so that eventually we could even deprecate the SVM counterparts (graal_create_isolate
for JNI_CreateJavaVM
and graal_attach_thread
for AttachCurrentThread
).
I think there may be a misunderstanding here. Whether it's through the native image C API or JNI, I have not found an example using a native image as a shared library anywhere in the docs or in the demo repository. There are docs about building a shared library in the Native Image reference manual and those docs show the generated function declarations require a graal_isolatethread_t*
as the first argument. The page then linkes back to the the native C API, very much implying those functions are how you're going to create the graal_isolatethread_t*
that the @CEntryPoint
function requires. But, the docs stop there. They don't actually show how to use this API or call that function.
I ended up asking for help in the #native-image channel on the GraalVM Slack and several people shared open source projects they have where the figured out how to call into these functions. Each one was slightly different in the way it initialized and cleaned up these resources. None of them used JNI.
I also went through all of the GraalVM Demos and none of them have any C code that I could find.
Regardless of whether libpolyglot, the Graal isolate API, or JNI should be used, the purpose of this issue is that there isn't an example of using any of them through C or through an FFI. Without such documentation, developers will use whatever 3rd party source they can find and that very likely will cause bad patterns to propagate.
As a follow-up, I was using GraalVM 21.3.0 when I opened this issue. With 22.0.0, the generated header files now include JNI-based function declarations creating isolates. That's a nice usability improvement.
That's great! The lack of examples for JNI functions invocation remains. We created a task for that.
@olyagpl @christianwimmer a very late follow up but this issue is relevant to what I've been trying to understand for the last few evenings. As far as I can see, the Native C API is much more convenieent for calling shared libraries built with Java from C. The Panama based APIs, in their current form in JDK 22 make the Arena
the entry point (conceptually) for MemorySegment use and all the examples are using try-with-resources syntax, apparently aiming for memory-leak-safe approach for calling native code from Java. I cannot see the convenience offered by the C api in Panama based examples. I have no clue how I'm supposed to allocate some off-heap byte array and return a pointer to it for example: I have to use an Arena, and it would free the allocated memory segment when the java function returns, so calls form C would end up with dangling pointers. Am I missing something here? In other words, which part of Panama is supposed to replace the current native C Api? For example, the section titled "creating C libraries from Java programs" here: https://medium.com/graalvm/3-ways-to-polyglot-with-graalvm-fb28c1542b45 What's the Panama equivalent of that? Especially with Arena apparently making call-native-code-from-Java the primary, if not the only scenario. Am I missing something here? It feels like I am!
The Native Image C API doc introduce the set of functions for managing GraalVM Isolates, but does not provide any sample code for how those functions should be used. I couldn't find anything in the docs for embedding languages either. Additionally, there are no examples in the GraalVM Demos repository.