I have a native function, defined in my C++ code, that is called within Java (after the Java code is called by C++).
(1) Declaration / definition of the native function in C++:
// C++ declaration/definition of the native function:
JNIEXPORT void JNICALL setEncoderProgressStatus (JNIEnv * env, jobject theClass, jlong jEncoderDecoderDlg, jstring status)
{
// Do nothing. Obviously, the real function does something.
// But an access violation is reported even in the do-nothing case.
}
(2) Registration of the native function in C++
// Registration of this function with JNI in the C++ code
JNINativeMethod commandLineEncoderMethods[] =
{
{"setEncoderProgressStatus","(JLjava/lang/String;)V", (void*)setEncoderProgressStatus}
};
// pEnv is a valid JNIEnv *
// jCommandLineEncoderClass has already been initialized
pEnv->RegisterNatives(jCommandLineEncoderClass, commandLineEncoderMethods, sizeof(commandLineEncoderMethods)/sizeof(JNINativeMethod))
(3) Declaration of the native function in Java:
// The Java code, in turn, declares the native function as follows:
public static native void setEncoderProgressStatus(long EncoderDecoderDlg, String status);
(4) Calling the native function within the Java code:
// Finally, the Java code calls the native function as follows:
// The real code passes different args,
// but an access violation is reported even in the do-nothing case.
// Commenting out the following line of code makes the access violation disappear.
setEncoderProgressStatus(0, "");
Note that this code works 100% successfully, and has worked for a long time. I just noticed that when running in the debugger in Visual Studio 2010, an access violation is reported. Simply commenting out the call to the native function in Java, causes the access violation to disappear.
If I knew that this is a known “fluke” with JNI when running applications in debug mode in VS 2010, and that it does not represent a problem with my code, then I would be satisfied.
However, I would like to confirm that there is no possible problem with my code.
…
* ADDENDUM *
The access violations do not cause program execution to halt. Instead, the only indication of the access violation is a line in the Output window. I am not sure if this means that the access violation was handled or not; however, I would guess it means that it was handled. Even if it’s handled, however, I would like to know if it necessarily indicates that there is a problem with my code.
Here is the message in the Output window:
First-chance exception at 0x03fbb256 in EncoderDecoder.exe:
0xC0000005: Access violation reading location 0x003d0100
…
* SECOND ADDENDUM *
I find that when the C++ application remains connected to the JVM, and I execute the same code again from the C++ application (causing the same Java code to be called, which in turn causes the Java code to call the same JNI function), that the access violations do not appear.
(In my actual program, there are a number of different native functions called within a number of different classes, so it’s not simple to isolate exactly when the access violation is reported, and when it stops being reported – but by the third run of the same functionality without quitting the C++ application, using the same loaded JVM, there are no first-chance access violation errors (and no plain access violation errors, either)).
This leads me to believe, in conjunction with Ben Voigt’s answer (and associated comments) below, that the JVM code does cause a first-chance exception (access violation) to occur as part of its NORMAL processing, and that this is not an issue with my code.
…
* ADDENDUM 3 *
From http://blogs.msdn.com/b/davidklinems/archive/2005/07/12/438061.aspx:
First chance exception messages most often do not mean there is a
problem in the code.
There still is the possibility that a first-chance exception that happens to be an access violation is more likely to represent a real problem, in which case my question is still open; but – I think the evidence points to the possibility that this is just how the JVM works, and does not represent a problem with my code.
Is it an unhandled access violation, or does the call proceed if you continue (letting the exception handler run)?
JIT compilers have a whole bunch of tricks to generate the native code for a function without every call suffering the cost of a conditional to see if the function has been JITted. One such technique is for the first call to be intercepted because it generates an access violation to trigger the JIT compiler. After the code has been generated once, future calls go through without an exception.
I’m not familiar with whether any Java JIT compiler actually does so, but you can’t get a definitive answer without giving specific information about what JIT you’re running. Is it the Sun/Oracle HotSpot compiler? x86 or x86_64 or some other platform? You’re deep into implementation details which vary by implementation.