Can a pthread dispatched from native code call back into JNI? - java

Hypothetical: Calling C++ code from Java is relatively straightforward. As I understand it, the C++ code is executed in the same thread as the Java code calling it (correct me if I'm wrong). If the C++ code then starts a new native thread with pthread_key_create(), can this thread call back into Java through JNI? If so, how is this possible, since the code would then be executing in a pthread instead of a Java thread on the JVM?

As I understand it, the C++ code is executed in the same thread as the Java code calling it (correct me if I'm wrong)
The JNIEnv is attached to a thread, you cannot share a JNIEnv between threads. Your native functions all receive a JNIEnv as the first argument so it corresponds to the current Thread's JNIEnv.
If the C++ code then starts a new native thread with pthread_key_create(), can this thread call back into Java through JNI?
All threads are Linux threads, scheduled by the kernel. They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then attached to the JavaVM. For example, a thread started with pthread_create can be attached with the JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv, and cannot make JNI calls.
If so, how is this possible, since the code would then be executing in a pthread instead of a Java thread on the JVM?
See previous response too ;) (the first two sentences)
More infos here and here.

In order to make upcalls to Java, a natively create thread should call first AttachCurrentThread or AttachCurrentThreadAsDaemon.

Take a look at this sample:
In this sample, you have a multi thread based code that calls Java code.
You can find full description here: http://jnicookbook.owsiak.org/recipe-no-027/
And source code is available here:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo027
I will not put all the codes here as it takes some space.
In fact, here: https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo032,
you have more suitable sample for your. Where JVM calls C that calls JVM back invoking static method in Main class.
> java -Djava.library.path=${LD_LIBRARY_PATH}:./lib -cp target recipeNo032.Main
I will call JVM
From JVM
I will call JVM
From JVM
I will call JVM
From JVM
I will call JVM
From JVM
I will call JVM
From JVM
I will call JVM
From JVM
Have fun with JNI.

Related

Calling C++ library function using JNI and which process executes that C++ library

I am new to Java & JNI. This question maybe very newbe. I have C++ library and Java application which interns call the C++ function using JNI concepts.
As per my understanding, JVM loads the C++ dll/SO in JVM space before calling a native function call.
If my understanding on the JVM is correct on JNI. Can someone tell me which/who is going to execute the C++ library function which is loaded inside the JVM.
Let say for C++, there is standard dynamic linker-loader present to handling the dynamic execution part of the C++ and executes all the machine instructions.
In case of JVM loaded JNI Libs (in this case C++ libs), does JVM executes the those libs ? If so does it uses its memory to execute the native function?
Thanks in advance.
The Java language allows you to mark certain methods as native. The Java Native Interface allows you to link these Java methods to a function address in native code.
When you System.loadLibrary a library that contains native code, the JVM will do two things:
Look for specifically named functions such as Java_pkg_Cls_f_ILjava_lang_String_2 and link this to the function f in class pkg.Cls.
Call JNI_OnLoad, if it exists in the library. This can perform initialization and optionally link more native methods using registerNatives.
After this point, the native library indeed resides in the process' memory space like any other library (say, libcurl or libssl). When you actually call one of the native methods, the JVM will find the function address and use a native call instruction to jump into the function. The function will execute as part of the stack trace of that thread and will show up as such in both the JVM and native stack traces.
In more advanced cases, the library might spawn additional native threads. These work like regular threads in native code and are invisible to the JVM. If these threads need to talk to the JVM as well, the developer can attach them.

when execute Agent_UnLoad() method about "java -agentpath:c:/tool.dll javaClass

I just start learning JVM TI.
About the java command: java -agentpath:../tool.dll javaClass, I know that there is a Agent_OnLoad() method in dll and maybe it set some event callback method. And I know the jvm execute Agent_OnLoad() first and then execute javaClass.And the Agent_OnUnLoad() is also called by jvm.
Then the problem comes, how the jvm know when call Agent_OnUnLoad() method . At First, I think that after javaClass is executed jvm will calls Agent_OnUnload(), but then I discard this thought because at this time, maybe the dll is doing sth e.g. writing data to disk.
So how jvm know it is the right time to call Agent_OnUnLoad() method?
There is no standard mechanism defined to unload agent libraries. Agent_OnUnload will be called only before the VM termination, when all Shutdown hooks are completed.

JNI: AttachCurrentThread returns -1

I have created a JNI wrapper with swig for a library. I use swig directors to call back into the JVM. Some of these callbacks occur on threads created within the native library. The first callback on a non JVM thread fails with a SIGSEGV which I could trace down to ignoring the negative return value (-1) of AttachCurrentThread and thus dereferencing a jenv pointer which is actually null. This happens in the swig generated code.
I have tried to call back into the JVM via the director classes from a thread that I created on the native side. This works fine. It does however not work from the thread created by the library I wrapped.
What can be possible reasons that AttachCurrentThread fails?
When a thread does not have sufficient stack space left AttachCurrentThread fails. Unfortunately the documentation of the Oracle JVM does not mention the minimum required stack space for AttachCurrentThread to work.
In my case the native library was optimized for embedded hardware and therefore creates threads generally with a stack size of 100000 bytes.

JNI - Java exits before native threads finish executing

I'm in the early stages of developing an API in C++, which I'm wrapping in Java using JNI. The native code creates a socket listener thread using WinAPI which should run indefinitely, thereby keeping the program open indefinitely (tested and works fine).
However, when I try to invoke this code in Java, the JVM still terminates when it reaches the end of main, ignoring the running thread. A little research has hinted that Java might think the thread is a daemon rather than a "user thread". But if that's the case, then I can't quite figure out how to convince Java that it actually is a user thread.
Does anyone have a clue about this?
You need to call AttachCurrentThread() for all your native threads, to ensure Java knows about them, so it will wait for them to finish.
Windows doesn't have daemon threads. The process exits when ExitProcess() is called or when the initial thread returns from the application's main function. (In principle, it will also exit if the last thread exits, but that can't be relied upon because Windows may create threads in your process that you don't know about.)
The Java runtime presumably waits for all of its own threads to exit (except for those that it considers daemon threads) before exiting the process. But your threads were created directly via the Win32 API, so Java doesn't know about them and therefore won't wait for them.
If your API wants to continue performing some task beyond the natural lifetime of the calling process, it should probably create a child process rather than a thread. (Or, if the API is Java-specific, it can presumably make use of JNI to ask that Java create the thread on its behalf, or to register the thread with Java.)

How to get a callback when Android NatveActivity is finished/exited in c++ JNI side?

I have a native activity that runs a openGL window and have a JNI integrated where I have also registered calls so I can call c++ to Java and vice-versa.
Since I have to detach the native thread before I call finish on Java side, I cannot have a registered call from c++ to Java (as I have to release it, otherwise I get error reports from DalvinVM that native thread was not detached).
Can you tell me which function I can call on c++ side to "finish()" this native activity (some call that is provided by JNI) ? And what callback I can expect on Java side ? Will the OnDestroy get called ?
So what has to be done is as you exit the main loop from the c++ side, the native-activity terminates. No need for complicated communication between c++ and Java.

Categories

Resources