[JNI Beginner] GC of Java arrays returned by the native code

Hello all,
I am beginning with JNI, to integrate a C library that pilots an industrial equipment, into a java UI. This library enables to exchange various proprietary PDUs (protocol data units), with the equipment, up and down (request/replies). Both requests and replies are arrays of bytes (+char*+).
"Request" byte arrays are constructed by Java code, which passes them to the JNI code that glues with the lib. "Reply" byte arrays are returned to the Java code, which analyzes them.
The "return reply" part is very similar to this [tutorial example|http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html] , which returns bytes read from a file. However there's something I don't understand with regard to garbage collection of the returned byte array:
- in this stock example, the C code creates a Java byte array fills it, and simply returns it (example code stripped to highlight only the parts relevant to my question):
    jByteArray=(*env)->NewByteArray(env, size);
    (*env)->SetByteArrayRegion(env, jByteArray, 0, size, (jbyte *)sourceBytes);
    return (jByteArray);What will happen to this Java array (jByteArray) with regard to garbage collection?
- if it's no more referenced (the example Java code just systemouts it and forgets it), will it be eligible to GC?
- if it is referenced by a Java variable (in my case, I plan to keep a reference to several replies as the business logic requires to analyze several of them together), do regular Java language GC rules apply, and prevent eligibility of the array to GC as long as it's referenced?
That may sound obvious, but what mixes me up is that the same tutorial describes memory issues in subsequent chapters: spécifically, the section on "passing arrays states that:
[in the example] the array is returned to the calling Java language method, which in turn, garbage collects the reference to the array when it is no longer usedThis seems to answer "yes" to both my questions above :o) But it goes on:
The array can be explicitly freed with the following call:
{code} (*env)-> ReleaseByteArrayElements(env, jByteArray, (jbyte *)sourceBytes, 0);{code}Under what circumstances would one need to explicitly free jByteArray when it's about to be returned to the Java calling method? Or does this sentence apply to completely different situations (such as, when the array is +not+ returned as is to a Java method)?
The tutorial's next section has a much-expected +memory issues+ paragraph, from which I quote:
By default, JNI uses local references when creating objects inside a native method. This means when the method returns, the references are eligible to be garbage collected.I assume this means, +unless the references are assigned, in the Java code, to a Java variable+, right?
If you want an object to persist across native method calls, use a global reference instead. A global reference is created from a local reference by calling NewGlobalReference on the the local reference.I assume this enables the C code to maintain a global reference to a java object even if it's not referenced anymore from the Java variables, right?
I also checked the [JNI specification|http://download-llnw.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp1242] , but this didn't clear the doubt completely:
*Global and Local References*
The JNI divides object references used by the native code into two categories: local and global references. Local references are valid for the duration of a native method call, and are automatically freed after the native method returns. Global references remain valid until they are explicitly freed.
Objects are passed to native methods as local references. All Java objects returned by JNI functions are local references. The JNI allows the programmer to create global references from local references. JNI functions that expect Java objects accept both global and local references. A native method may return a local or global reference to the VM as its resultAgain I assume the intent is that Global references are meant for objects that have to survive across native calls, regardless of whether they are referenced by Java code. But what worries me is that combining both sentences end up in +All Java objects returned by JNI functions are local references (...) and are automatically freed after the native method returns.+.
Could you clarify how to make sure that my Java byte arrays, be they allocated in C code, behave consistently with a Java array allocated in Java code (I'm familiar already with GC of "regular" Java objects)?
Thanks in advance, and best regards,
J.

jduprez wrote:
Hello all,
I am beginning with JNI, to integrate a C library that pilots an industrial equipment, into a java UI. This library enables to exchange various proprietary PDUs (protocol data units), with the equipment, up and down (request/replies). Both requests and replies are arrays of bytes (+char*+).
"Request" byte arrays are constructed by Java code, which passes them to the JNI code that glues with the lib. "Reply" byte arrays are returned to the Java code, which analyzes them.
The "return reply" part is very similar to this [tutorial example|http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html] , which returns bytes read from a file. However there's something I don't understand with regard to garbage collection of the returned byte array:
- in this stock example, the C code creates a Java byte array fills it, and simply returns it (example code stripped to highlight only the parts relevant to my question):
    jByteArray=(*env)->NewByteArray(env, size);
(*env)->SetByteArrayRegion(env, jByteArray, 0, size, (jbyte *)sourceBytes);
return (jByteArray);What will happen to this Java array (jByteArray) with regard to garbage collection?It will be collected when it is no longer referenced.
The fact that you created it in jni doesn't change that.
The array can be explicitly freed with the following call:
(*env)-> ReleaseByteArrayElements(env, jByteArray, (jbyte *)sourceBytes, 0);Under what circumstances would one need to explicitly free jByteArray when it's about to be returned to the Java calling method? Or does this sentence apply to completely different situations (such as, when the array is not returned as is to a Java method)?
Per what the tutorial says it is either poorly worded or just wrong.
An array which has been properly initialized it a just a java object. Thus it can be freed like any other object.
Per your original question that does not concern you because you return it.
In terms of why you need to explicitly free local references.
[http://download-llnw.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp16785]
The tutorial's next section has a much-expected memory issues paragraph, from which I quote:
By default, JNI uses local references when creating objects inside a native method. This means when the method returns, the references are eligible to be garbage collected.I assume this means, unless the references are assigned, in the Java code, to a Java variable, right?As stated it is not precise.
The created objects are tracked by the VM. When they are eligible to be collected they are.
If you create a local reference and do NOTHING that creates an active reference elsewhere then when the executing thread returns to the VM then the local references are eligible to be collected.
>
If you want an object to persist across native method calls, use a global reference instead. A global reference is created from a local reference by calling NewGlobalReference on the the local reference.That is not precise. The scope is the executing thread. You can pass a local reference to another method without problem.
I assume this enables the C code to maintain a global reference to a java object even if it's not referenced anymore from the Java variables, right?
It enables access to it to be insured across multiple threads in terms of execution scope. Normally you should not use them.

Similar Messages

  • Not returning from the native code

    Hi,
    I am trying to access the native code using java applet. My java code seems to load the DLL(created using the VC++ 6.0) properly. Then when i call the native method called crypto, it does not seem to return from the nayive code . I am signing the applet and putting it a signed jar .Any suggestion is appreciated. I mite be wrong in the design too ...pleas ehelp. I am pasting the java code and the C code.
    cryptoJNI.java
    import java.awt.*;
    import java.io.*;
    import java.lang.*;
    import java.applet.*;
    public class cryptoJNI extends Applet {
         String uname=null;
         String b=null,ret=null;
         String a=null;
    public void init(){
              System.out.println("in init");
         public void dll_load(){
              b="before dll";
              System.loadLibrary("Msgimpl");
              a="after dll load";
         private native String crypto(String store);
    public void paint(Graphics g) {
              g.setColor(Color.blue);
              g.setColor(Color.magenta);
              load_dll();
              g.drawString(b, 5, 5);
              g.drawString(a, 15, 15);
              g.drawString("first call const", 25, 25);
              cryptoJNI app = new cryptoJNI();
              ret=app.crypto("My");
    g.drawString(ret, 75, 75);
              g.drawString("Signed 11", 120, 80);
              stop();
    CryptoJNI.c
    #define WIN32WINNT 0x0400
    #include <windows.h>
    #include <jni.h>
    #include <wincrypt.h>
    #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
    #include "cryptoJNI.h"
    BOOL APIENTRY DllMain(HANDLE hModule,
    DWORD dwReason, void** lpReserved) {
    return TRUE;
    JNIEXPORT void JNICALL
    Java_CryptoJNI_crypto(JNIEnv * jEnv,jobject obj,jstring jstore) {
    //     char               name[256];
         const char *msg;
         msg = (*jEnv)->GetStringUTFChars(jEnv, jstore,0);
         //printf("Before context\n");
         //(*jEnv)->ReleaseStringUTFChars(jEnv, jstore,msg);
         return (*jEnv)->NewStringUTF(jEnv, msg);
    In my applet, i have some debugging statements that helps me verify that the Msgimpl.dll loads properly. When i invoke the app.crypto() it just "hangs". Please help
    Thanks,
    Vivek

    Hi,
    This is the exception that i am getting?? my cryptoJNIImp.c is is in the same directory as the my java file,c:\vivek work\signedcode. and i have added this to my path env variable...If u see the output, it executes the init() and then loads the Msgimpl.dll. So its got nothing do with loading a DLL. Any pointers on this..
    in init
    before loading dll
    After loading dll
    java.lang.UnsatisfiedLinkError: crypto
    at cryptoJNI.crypto(Native Method)
    at cryptoJNI.paint(cryptoJNI.java:65)
    at sun.awt.RepaintArea.paint(Unknown Source)
    at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

  • Java Runtime crash while executing native code.(version 1.6.0_10-beta)

    HI all
    i observed a crash while execution a native fuction , which is initializing an
    char array of size (1024*1024).Plz see the code snippet below:
    But it is working with java version: 1.5.0
    FileTest.c:
    #include<stdio.h>
    #include<fcntl.h>
    #include<string.h>
    #include<stdlib.h>
    #include "HelloWorld.h"
    JNIEXPORT jint JNICALL Java_HelloWorld_CreateLargestF<div style="direction: ltr">ile (JNIEnv * env, jclass obj)
    //int CreateLargestFile(char* filename)
    char *filename = "LargestFile.tmp";
    int fd = creat(filename, 0666);
    if(fd == -1)
    return 0;
    int size = 1024 * 1024;
    char buffer[size];
    //buffer is not filled fully, JRE aborts after i reaches to 61327 approx.
    int i;
    for( i = 0;i<size;i++)
    buffer[i] = 'a';
    printf("\n\n==>> Executing FSTLD0001 : buffer %d = %c \n",i,buffer);
    printf("\n\n==>> Executing FSTLD0001 : after init\n");
    //memset(buffer, 'a', size);
    while(1)
    long bytes = write(fd, buffer, size);
    if(bytes < size)
    break;
    close(fd);
    return 1;
    HelloWorld.java
    public class HelloWorld {
    public static native int CreateLargestFile();
    public static void main(String[] args)
    String dir = System.getProperty("user.dir");
    String libpath = dir + "/libFileTest.so";
    System.load(libpath);
    CreateLargestFile();
    jni.h version used is: 1.56 03/12/19
    jni_md.h version used is : 1.14 03/12/19
    FULL PRODUCT VERSION :
    java version "1.6.0_10-beta"
    Java(TM) SE Runtime Environment (build 1.6.0_10-beta-b14)
    Java HotSpot(TM) Client VM (11.0-b11 mixed mode, sharing)
    FULL OS VERSION :
    Linux debian 2.6.18-6-686 #1 SMP Sun Feb 10 22:11:31 UTC 2008 i686 GNU/Linux
    ERROR MESSAGES:
    # An unexpected error has been detected by Java Runtime Environment:
    # SIGSEGV (0xb) at pc=0xb7eec667, pid=7128, tid=3084340144
    # Java VM: Java HotSpot(TM) Client VM (11.0-b11 mixed mode, sharing linux-x86)
    # Problematic frame:
    # C [libFileTest.so+0x667] Java_HelloWorld_CreateLargestFile+0x8b
    <div style="direction: ltr">#
    # If you would like to submit a bug report, please visit:
    # [http://java.sun.com/webapps/bugreport/crash.jsp]
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.</div>
    May i have any feedbacks or help?
    Thanks
    </div>

    Stack size perhaps?
    Allocate the buffer off the heap instead of the stack.
    The following might be related (might not as well.)
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227033
    There is a flag that adds info for jni via the command line turn it on.

  • �possible that the JNI side generates many instances of the native code?

    Hi guys,
    I asked this in a previous post but maybe with a bad constructed question.
    I have C code that generate data (particles) for one client (non multithreading). In my webapp Im gonna have many clients but changing the C side is not initially my best solution.
    When one client connects to the server ( calls the C code to generate data) it works ok, because I have only one client. When two or more clients connects to the server,
    the data generated by the C side is DIVIDED over all clients. So, I need 'n' replications of the C side, non one C side, this way my data structures in the C side will be replicated
    'n' times and could generate data for 'n' clients. Hope I have explained the right way.
    Please replies! :).

    1. Serialize the requests into the C code so that only one request is active. Save any state elsewhere. (Could be saved in java, could be saved in some C-side structure)Hi bschauwejava,
    I think my problem is not concurrency, saving the state in java will mean a lot of overload but its an option.
    Do you mean there is no way of having many instances of the C code ? this way I will have my state in each particular instance (one instance per client connected), and I could can forget about state.

  • Weird crmForms array returned in the Contact record

    I have 2 CRM forms (Photo and History) attached to the contact. Both have only one field right now (will add more in the future). The structure in the contact record looks like this...
    [crmForms] => stdClass Object
                [CrmForms] => Array
                        [0] => stdClass Object
                                [formId] => 141376
                                [formName] => Photo
                                [crmFormFields] => stdClass Object
                                        [CrmFormFields] => stdClass Object
                                                [fieldId] => 437621
                                                [fieldTypeId] => 8
                                                [fieldName] => Photo
                                                [fieldValue] =>
                        [1] => stdClass Object
                                [formId] => 144272
                                [formName] => History
                                [crmFormFields] => stdClass Object
                                        [CrmFormFields] => Array
                                                [0] => stdClass Object
                                                        [fieldId] => 437621
                                                        [fieldTypeId] => 8
                                                        [fieldName] => Photo
                                                        [fieldValue] =>
                                                [1] => stdClass Object
                                                        [fieldId] => 439623
                                                        [fieldTypeId] => 9
                                                        [fieldName] => Classes Taken
                                                        [fieldValue] =>
    Why is the Photo field returned inside of the History form???

    I have 2 CRM forms (Photo and History) attached to the contact. Both have only one field right now (will add more in the future). The structure in the contact record looks like this...
    [crmForms] => stdClass Object
                [CrmForms] => Array
                        [0] => stdClass Object
                                [formId] => 141376
                                [formName] => Photo
                                [crmFormFields] => stdClass Object
                                        [CrmFormFields] => stdClass Object
                                                [fieldId] => 437621
                                                [fieldTypeId] => 8
                                                [fieldName] => Photo
                                                [fieldValue] =>
                        [1] => stdClass Object
                                [formId] => 144272
                                [formName] => History
                                [crmFormFields] => stdClass Object
                                        [CrmFormFields] => Array
                                                [0] => stdClass Object
                                                        [fieldId] => 437621
                                                        [fieldTypeId] => 8
                                                        [fieldName] => Photo
                                                        [fieldValue] =>
                                                [1] => stdClass Object
                                                        [fieldId] => 439623
                                                        [fieldTypeId] => 9
                                                        [fieldName] => Classes Taken
                                                        [fieldValue] =>
    Why is the Photo field returned inside of the History form???

  • HT4009 How long does it take for apple to return with the needed code for in app purchases.  We have a developer working through elance that states he submitted a finalized version last friday to apple and is still waiting to get the code back from Apple?

    We are being told by our elance developer that he is just waiting on apple to return the code for in app purchases with our app.  he says he had to submit a complete version before they would give it to him and that he did that last friday.  Needless to say i don;t beleive him.  Can anyone validate for me the process of getting the code installed into our app and how long it should really take.

    I'd say an average of one week, depending on backlog. Expect two if you are outside the US.
    The outage has caused some lingering effects that seem to be delaying things for some, however.
    Patience is key in all things when it comes to being a developer

  • Return to the last code position

    When I'm searching through cases of a large event structure or a case structure to investigate its LabVIEW code it would be helpful to have the possibilty just to jump back to the last position inside the code. (like in C# with "STRG + .") Even better it would be to jump back along a whole history of positions.
    Solved!
    Go to Solution.

    I have this JKI RCF plug-in in the LAVA Code Repository.  The tree in the second image is a list of all the states in my VI.  The state navigation feature sorta works
    Jim
    You're entirely bonkers. But I'll tell you a secret. All the best people are. ~ Alice

  • Returning new objects on uninitialized native code arguments

    I have a C library I am trying to interface to that returns arrays whose size
    I do not know in advance. I would like to be able to write a java wrapper
    library that accepts uninitialized java arrays as arguments, and creates
    arrays of the appropriate size, and gives them back to the Java code.
    In the code below, I try to pass an uninitialized String array to native
    function, and create the String array in the native function. The String
    array "str" is still null after the native function returns. I can make it
    work by creating the String array in the java code, or making the return value
    a String array created in the native code. Why doesn't it work when I pass an
    uninitialized array as a parameter?
    Java:
    public native int getStrings(int length, String [] strings);...
    String [] str= null;
    int result = test.getStrings(10,str);C:
    JNIEXPORT jint JNICALL Java_StringArrayTest_getStrings
    (JNIEnv *env, jobject obj, jint length, jobjectArray strings)
        //create the java string array
       jclass elementType = (*env)->FindClass(env,"java/lang/String");
        if(NULL==elementType) return -1;
        strings=(*env)->NewObjectArray(env,length,elementType,NULL);
        if(NULL==strings)      return -1;
       jsize i;
        for(i=0; i<length; i++)
         char buf[100];
         snprintf(buf,99,"String %i",(int) i);
         jstring tempString=NULL;
         tempString=(*env)->NewStringUTF(env,buf);
         if(NULL==tempString) return -1;
         (*env)->SetObjectArrayElement(env, strings, i, tempString);
        return 0;
    }

    That kind of return-by-reference is not supported in Java. Consider: could it work if getStrings were written in Java language instead of native code? The answer is no.
    -slj-

  • How to call a C sort function to sort a Java Array.

    My name is David, I'm interning this summer doing some High Performance Computing work. I'm significantly out of my comfort zone here; I am primarily a network/network security geek, not a programming guy. I took one Java based class called problem solving with programming where we wrote like 3 programs in Java and did everything else in pseudocode and using a program called Alice http://www.alice.org/ to do things graphically. Learned basically no actual programming syntax. Also have done some self-taught perl, but only through one book and I didn't finish it, I only got about half way through it. So my expertise in programming are pretty much null.
    That being said, I currently am tasked with having to figure out how to make JNI work... specifically at this time I am tasked with writing an array in Java, and designing a C program that can be called by means of JNI to sort the array. I have chosen to work with the Merge Sort algorithm. My method of coding is not one where I write the entire thing from scratch, I don't particularly have a need to master languages at this point, rather I just need to make them work. I am interested in learning, but time is of the essence for me right now. So thus far what I have done is take sample codes and tweak them to meet my purpose. However, I currently am unable to make things work. So I am asking for help.
    I am going to paste 3 codes here, the first one will be my basic self-written instructions for JNI (Hello World Instructions), the second one will be my Java Array, and the third one will be my MergeSort function. I am not asking for you to DO my work for me by telling me how to manipulate my code, but rather I am asking for you to send me in the direction of resources that will be of some aid to me. Links, books (preferrably e-books so I don't have to go to a library), anything that you can send my direction that may help will be deeply appreciated. Thanks so much!
    JNI Instructions:
    /*The process for calling a C function in Java is as follows:
    1)Write the Java Program name. Eg. HelloWorld.java
    2)Compile it: javac HelloWorld.java
    3)Create a header file: javah -jni HelloWorld
    4)Create a C program eg. HelloWorld.java
    5)Compile the C program creating a shared library eg. libhello.so (My specifc command is cc -m32 -I/usr/java/jdk1.7.0_05/include -I/usr/java/jdk1.7.0_05/include/linux -shared -o libhello.so -fPIC HelloWorld.c
    6) Copy the library to the java.library.path, or LD_LIBRARY_PATH (in my case I have set it to /usr/local/lib.
    7)Run ldconfig (/sbin/ldconfig)
    8)Run the java program: java HelloWorld. */
    //Writing the code:
    //For the HelloWorld program:
    //In java:
    //You need to name a class:
    class HelloWorld {
    //You then need to declare a native method:
    public native void displayHelloWorld();
    //You now need a static initializer:
    static {
    //Load the library:
    System.loadLibrary("hello");
    /*Main function to call the native method (call the C code)*/
    public static void main(String[] args) {
    new HelloWorld().displayHelloWorld();
    //In C:
    #include <jni.h> //JNI header
    #include "HelloWorld.h" //Header created by the javah -jni command parameter
    #include <stdio.h> //Standard input/output header for C.
    //Now we must use a portion of the code provided by the JNI header.
    JNIEXPORT void JNICALL
    Java_HelloWorld_displayHelloWorld(JNIENV *env, jobject obj)
    //Naming convention: Java_JavaProgramName_displayCProgramName
        printf("Hello World!\n");
        return;
    }Java Array:
    class JavaArray {
         private native int MergeSort(int[] arr);
         public static void main(String[] args)
             int arr[] = {7, 8, 6, 3, 1, 19, 20, 13, 27, 4};
         static
             System.loadLibrary("MergeSort");
    }Hacked and pieced together crappy C Merge Sort code:
    #include <jni.h>
    #include <stdio.h>
    #include "JavaArray.h"
    JNIEXPORT jint JNICALL
    Java_JavaArray_MergeSort(JNIEnv *env, jobject obj, jintArray arr[],jint low,jint mid,jint high)
       jint i,j,k,l,b[10];
    l=low;
    i=low;
    j=mid+1;
    while((l<=mid)&&(j<=high))
        if(arr[l]<=arr[j])
           b=arr[l];
    l++;
    else
    b[i]=arr[j];
    j++;
    i++;
    if(l>mid)
    for(k=j;k<=high;k++)
    b[i]=arr[k];
    i++;
    else
    for(k=l;k<=mid;k++)
    b[i]=arr[k];
    i++;
    for(k=low;k<=high;k++)
    arr[k]=b[k];
    void partition(jint arr[],jint low,jint high)
    jint mid;
    if(low<high)
    mid=(low+high)/2;
    partition(arr,low,mid);
    partition(arr,mid+1,high);
    sort(arr,low,mid,high);

    You're doing OK so far up to here:
    Java_JavaArray_MergeSort(JNIEnv *env, jobject obj, jintArray arr[],jint low,jint mid,jint high)This is not correct. It is not what was generated by javah. It would have generated this:
    Java_JavaArray_MergeSort(JNIEnv *env, jobject obj, jintArray arr,jint low,jint mid,jint high)A 'jintArray' is already an array, embedded in an object. You don't have an array of them.
    So you need to restore that, and the header file, the way 'javah' generated them, then adjust your code to call GetIntArrayElements() to get the elements out of 'arr' into a local int[] array, sort that, and then call ReleaseIntArrayElements() to put them back.

  • JNI - Java code executed before native code

    Hi there, I'm having a problem, I've got this native thing working but it seems like my java code is being executed before the native one. Example :
    class Hello
    { static { System.loadLibrary("D1"); }
    public native void displayHello();
    public static void main(String[] args)
    new Hello().displayHello();
    System.out.println("kfdhgkfldh");
    The output is:
    "kfdhgkfldh"
    "Message from JNI"
    So the printfunction from the main has been executed before the one in my C++ program
    Any idea why ??
    (this is quite important)
    thx

    Tryfflush(stdin);before returning from the native function

  • How can I return in a native method a Java type?

    Hi,
    i want to return in the native methode ja Java type java.awt.Dimension!
    How can I do this?
    Java code:--------------------------------------------------------------------------------
    public native java.awt.Dimension getSize()
    generating the JNI header file
    JNI header code:--------------------------------------------------------------------------------
    JNIEXPORT jobject JNICALL Java_Video_getSize(JNIEnv *, jobject)
    my c function looks like this
    code:--------------------------------------------------------------------------------
    JNIEXPORT jobject JNICALL Java_Video_getSize(JNIEnv *env, jobject obj)
    return ???????
    how can I return in C an object like jawa.awt.Dimension?
    Thx
    Ronny

    Here is my 2 cents for a way we pass data between Java and C via the Java Native Interface. This excerpt is an example of passing an int value through a locally created Integer wrapper class, which must be adapted for local use. Note that because of the wrapper, return values are not needed.
    1. Create the Java class file.
    * This class encapsulates a Java <CODE>int</CODE> primitive.
    * This class was created to allow programmers to change
    * the value of an existing integer object without being
    * forced to create a new object (as is the case with the
    * Java Integer object).
    public class LocalInteger
         private int     value;
         * Creates a LocalInteger object and initializes
         * it to <I>0</I> (the default in Java).
         public LocalInteger ()
              super ();
         * Creates a LocalInteger object and initializes
         * it using the given <I>int</I> value.
         * @param i Integer value to use in initializing
         * the object.
         public LocalInteger (int i)
              super ();
              value = i;
         * Gets the value of the object.
         * @return The value of the object.
         public int getValue ()
              return (value);
    2. Create the jni header file.
    DLL_EXTERN void jni_GetValue_from_LocalInteger(int* LocalInteger, JNIEnv *env, jobject thisLocalInteger);
    3. Create the C file.
    /*start of jni header****************************************
    *NAME/TITLE:       jni_GetValue_from_LocalInteger
    *DESCRIPTION:      This routine copies the integer value
    * from the Java LocalInteger object to the
    * C 'int' variable.
    *CALLING SEQUENCE: jni_GetValue_from_LocalInteger (LocalInteger,
    * env,
    * thisLocalInteger)
    *PARAMETERS:
    * Type Name I/O Description
    * int * LocalInteger I/O C variable
    * JNIEnv * env I JNIEnv pointer
    * jobject thisLocalInteger I Java object
    *RETURN:           N/A
    **end of header*********************************************/
    /* ********************** BEGIN CODE ********************** */
    DLL_EXPORT
    void jni_GetValue_from_LocalInteger(int* LocalInteger, JNIEnv *env, jobject thisLocalInteger)
         LocalInteger = (int) (env)->GetIntField(env, thisLocalInteger, LocalInteger_Value);

  • JNI Problem - JAVA invoke C++ and the way back from C++ to JAVA

    Hi @ all!
    I am a computer science student and I have a problem with the JNI Interface.
    First the program structure:
    We have a Java GUI a wrapper and a C++ protocol. That is the general communication way:
    left side:
    JAVA GUI
    |
    Wrapper (JAVA)
    |
    C++ protocol
    |
    |
    Network transfer
    |
    |
    C++ protocol
    |
    Wrapper (JAVA)
    |
    JAVA Gui
    The program sequence is following:
    - The GUI will be started and call a protocol init method in the native code. The JAVA and C++ instance are already running!!
    - The protocol handles some information.
    - Then the left side e.g. invoke a method. The protocol transmits the packet to the other side. But HERE is the problem. On the other side the protocol must call a static JAVA Method from the running JAVA instance.
    I have no idea how I can handle this problem. I tried to save the env pointer und the jobject at the first invocation from Java to C++. With this elements I tried to getObjectClass(saved jobject) and tried to invoke the static JAVA method but I got a SIGSEGV from the JVM.
    How can I solve this problem??
    By the way, I generate through the java wrapper my C++ header and the the Java wrapper load a shared object!
    I work with a Gentoo System and with Java 1.5.
    I hope anybody can help me!
    Cheers,
    Edited by: polo6n2 on Jul 3, 2008 1:04 AM

    You mean the communication is aschronous?
    Then the C++ side will have a C++ thread. That thread calls a method. That method FIRST uses the JNI method to attache the thread.
    Then you look up whatever you need in java, maybe a class and you call JNI methods to interact with it.
    If you don't attach the thread it will not work.
    JAVA method but I got a SIGSEGVThen you did something wrong in your C++ code.

  • Make native code and Java VM interact

    Hi all,
    I am building a native components (Delphi and C++) using JNI.
    Currently my components involve a Java GUI.
    It loads the JVM, then request for that Java Object GUI.
    When the interface is created, I need to get back information
    from what the user can type in.
    However, the native code doesn't wait. It runs and continues right after
    the creation of the GUI, thus causing me trouble (trying to get
    null objects).
    Is there a way to make the native code wait for a java command from
    the interface, or is there a way to make both part of the component
    (java / native) to communicate and interact ?
    Any help would be appreciated.
    Thanks
    Regards,
    Florent

    There are quite a few options here, and this may not
    be the best, per se, but you could make a blocking
    call from the JNI to a Java method. That Java method
    will only return after whatever you want done in the
    interface has completed.Thanks for your reply. Is there other solution in the JNI itself,
    using the JNIEnv Object ?
    Else, I'll try to use that solution.
    Regards,
    Florent

  • JVM dies when JNI native code causes a SIGABRT from assertions

    Hi,
    I am wondering whether there is a way to prevent the JVM from dying when the JNI native code hits an assertion.
    #include "NativeTest.h"
    #include <assert.h>
    JNIEXPORT jstring JNICALL Java_NativeTest_sayHello (JNIEnv *env, jobject thisobject, jstring js)
    assert(0);
    return js;
    Calling this code from Java through JNI causes a SIGABRT when assert(0) is hit. This causes the java program to terminate. Is there a way for the JVM to recover from the SIGABRT from the native code?

    929919 wrote:
    I am wondering whether there is a way to prevent the JVM from dying when the JNI native code hits an assertion.There is no way to prevent the VM from exiting if native code does anything that causes an exit.
    An assertion is only one way that can happen.
    So to prevent the VM from exiting - don't run native code. The safe way to execute OS native library is to do the following.
    1. Wrap the library in an executable.
    2. Create a communications API for the executable.
    3. Manage the executable via Java Runtime.exec/ProcessBuilder.
    4. Talk to the executable using the communications API from 2 in the java code.
    The above is safe because if the library exits it exits the executable, not the VM.

  • The crash happened outside the java virtual machine in native code

    Hi,
    I have a biometric device with which I am given some C++ dlls. I am trying to call methods inside these using java (jna). I am loading the dll "zkemsdk.dll+" as follows:
    zkemkeeper INSTANCE1 = (zkemkeeper)Native.loadLibrary("zkemsdk", zkemkeeper.class);//zkemsdk is the dll, I am loading the dll here.
    Then, I am calling the function:
    zkemkeeper.INSTANCE1.Z_Connect_NETEX("ip address",4370);//Z_Connect_NETEX is a function inside zkemsdk.dll
    This returns me true or false based on whether am connected to the biometric device or not.Thus I am able to invoke this method without issues. But for other methods inside the dll, run time exception is thrown in console:
    Can someone help me resolve this issue. ??? Following is the content of the log file generated.
    # A fatal error has been detected by the Java Runtime Environment:
    # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0351fe3b, pid=1664, tid=3832
    # JRE version: 6.0_20-b02
    # Java VM: Java HotSpot(TM) Client VM (16.3-b01 mixed mode, sharing windows-x86 )
    # Problematic frame:
    # C [zkemsdk.dll+0xfe3b]
    # If you would like to submit a bug report, please visit:
    # http://www.java.net/external?url=http://java.sun.com/webapps/bugreport/crash.jsp
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.
    --------------- T H R E A D ---------------
    Current thread (0x003a9000): JavaThread "main" [_thread_in_native, id=3832, stack(0x008c0000,0x00910000)]
    siginfo: ExceptionCode=0xc0000005, reading address 0x00000106
    Registers:
    EAX=0x0090f7c4, EBX=0x00000001, ECX=0x00000000, EDX=0x00000001
    ESP=0x0090f7b4, EBP=0x0090f848, ESI=0x00000096, EDI=0x003a9000
    EIP=0x0351fe3b, EFLAGS=0x00010216
    Top of Stack: (sp=0x0090f7b4)
    0x0090f7b4: 00000000 0090f930 000003fc 00000103
    0x0090f7c4: 0090f800 6d9532d0 373e92a0 00912ec5
    0x0090f7d4: 00000401 0090f7d8 369860d1 0090f800
    0x0090f7e4: 37390050 00000000 37390f90 00000000
    0x0090f7f4: 0090f800 0090f930 003a9000 0090f830
    0x0090f804: 10008fd8 0090f840 0090f930 00000008
    0x0090f814: 0090f88c 0090fa28 0090f8f4 0090f848
    0x0090f824: eb53f637 0351ffdc 00000096 00000003
    Instructions: (pc=0x0351fe3b)
    0x0351fe2b: 0f 53 50 8d 44 24 18 50 e8 58 7c 00 00 83 c4 0c
    0x0351fe3b: 8b 4e 70 51 8b 0e 83 c3 04 53 6a 64 8d 54 24 18
    Stack: [0x008c0000,0x00910000], sp=0x0090f7b4, free space=13d0090f2e8k
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    C [zkemsdk.dll+0xfe3b]
    C [jna5972695927945545932.tmp+0x9182]
    C [jna5972695927945545932.tmp+0x2161]
    C [jna5972695927945545932.tmp+0x2849]
    j com.sun.jna.Function.invokeInt(I[Ljava/lang/Object;)I+0
    j com.sun.jna.Function.invoke([Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;+90
    j com.sun.jna.Function.invoke(Ljava/lang/Class;[Ljava/lang/Object;Ljava/util/Map;)Ljava/lang/Object;+194
    j com.sun.jna.Library$Handler.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;+344
    j $Proxy0.Z_Beep(J)Z+19
    j com.rfarrays.bhabs.fingerPrint.main([Ljava/lang/String;)V+84
    v ~StubRoutines::call_stub
    V [jvm.dll+0xf049c]
    V [jvm.dll+0x17fcf1]
    V [jvm.dll+0xf051d]
    V [jvm.dll+0xf9bc5]
    V [jvm.dll+0x10181d]
    C [javaw.exe+0x2155]
    C [javaw.exe+0x8614]
    C [kernel32.dll+0xb729]
    Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
    j com.sun.jna.Function.invokeInt(I[Ljava/lang/Object;)I+0
    j com.sun.jna.Function.invoke([Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;+90
    j com.sun.jna.Function.invoke(Ljava/lang/Class;[Ljava/lang/Object;Ljava/util/Map;)Ljava/lang/Object;+194
    j com.sun.jna.Library$Handler.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;+344
    j $Proxy0.Z_Beep(J)Z+19
    j com.rfarrays.bhabs.fingerPrint.main([Ljava/lang/String;)V+84
    v ~StubRoutines::call_stub
    --------------- P R O C E S S ---------------
    Java Threads: ( => current thread )
    0x02b10c00 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=1976, stack(0x02dc0000,0x02e10000)]
    0x02b0a400 JavaThread "CompilerThread0" daemon [_thread_blocked, id=1280, stack(0x02d70000,0x02dc0000)]
    0x02b08c00 JavaThread "Attach Listener" daemon [_thread_blocked, id=1984, stack(0x02d20000,0x02d70000)]
    0x02b07800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=2160, stack(0x02cd0000,0x02d20000)]
    0x02b02400 JavaThread "Finalizer" daemon [_thread_blocked, id=2052, stack(0x02c80000,0x02cd0000)]
    0x02afd800 JavaThread "Reference Handler" daemon [_thread_blocked, id=752, stack(0x02c30000,0x02c80000)]
    =>0x003a9000 JavaThread "main" [_thread_in_native, id=3832, stack(0x008c0000,0x00910000)]
    Other Threads:
    0x02afc400 VMThread [stack: 0x02be0000,0x02c30000] [id=1504]
    0x02b1b800 WatcherThread [stack: 0x02e10000,0x02e60000] [id=1980]
    VM state:not at safepoint (normal execution)
    VM Mutex/Monitor currently owned by a thread: None
    Heap
    def new generation total 4928K, used 2455K [0x22970000, 0x22ec0000, 0x27ec0000)
    eden space 4416K, 55% used [0x22970000, 0x22bd5db0, 0x22dc0000)
    from space 512K, 0% used [0x22dc0000, 0x22dc0000, 0x22e40000)
    to space 512K, 0% used [0x22e40000, 0x22e40000, 0x22ec0000)
    tenured generation total 10944K, used 0K [0x27ec0000, 0x28970000, 0x32970000)
    the space 10944K, 0% used [0x27ec0000, 0x27ec0000, 0x27ec0200, 0x28970000)
    compacting perm gen total 12288K, used 343K [0x32970000, 0x33570000, 0x36970000)
    the space 12288K, 2% used [0x32970000, 0x329c5f20, 0x329c6000, 0x33570000)
    ro space 10240K, 51% used [0x36970000, 0x36e9ae00, 0x36e9ae00, 0x37370000)
    rw space 12288K, 54% used [0x37370000, 0x37a072d8, 0x37a07400, 0x37f70000)
    Dynamic libraries:
    0x00400000 - 0x00424000 C:\Program Files\Java\jre6\bin\javaw.exe
    0x7c900000 - 0x7c9b2000 C:\WINDOWS\system32\ntdll.dll
    0x7c800000 - 0x7c8f6000 C:\WINDOWS\system32\kernel32.dll
    0x77dd0000 - 0x77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
    0x77e70000 - 0x77f03000 C:\WINDOWS\system32\RPCRT4.dll
    0x77fe0000 - 0x77ff1000 C:\WINDOWS\system32\Secur32.dll
    0x7e410000 - 0x7e4a1000 C:\WINDOWS\system32\USER32.dll
    0x77f10000 - 0x77f59000 C:\WINDOWS\system32\GDI32.dll
    0x76390000 - 0x763ad000 C:\WINDOWS\system32\IMM32.DLL
    0x7c340000 - 0x7c396000 C:\Program Files\Java\jre6\bin\msvcr71.dll
    0x6d800000 - 0x6da97000 C:\Program Files\Java\jre6\bin\client\jvm.dll
    0x76b40000 - 0x76b6d000 C:\WINDOWS\system32\WINMM.dll
    0x6d7b0000 - 0x6d7bc000 C:\Program Files\Java\jre6\bin\verify.dll
    0x6d330000 - 0x6d34f000 C:\Program Files\Java\jre6\bin\java.dll
    0x6d290000 - 0x6d298000 C:\Program Files\Java\jre6\bin\hpi.dll
    0x76bf0000 - 0x76bfb000 C:\WINDOWS\system32\PSAPI.DLL
    0x6d7f0000 - 0x6d7ff000 C:\Program Files\Java\jre6\bin\zip.dll
    0x68000000 - 0x68036000 C:\WINDOWS\system32\rsaenh.dll
    0x77c10000 - 0x77c68000 C:\WINDOWS\system32\msvcrt.dll
    0x769c0000 - 0x76a74000 C:\WINDOWS\system32\USERENV.dll
    0x5b860000 - 0x5b8b5000 C:\WINDOWS\system32\netapi32.dll
    0x6d610000 - 0x6d623000 C:\Program Files\Java\jre6\bin\net.dll
    0x71ab0000 - 0x71ac7000 C:\WINDOWS\system32\WS2_32.dll
    0x71aa0000 - 0x71aa8000 C:\WINDOWS\system32\WS2HELP.dll
    0x71a50000 - 0x71a8f000 C:\WINDOWS\System32\mswsock.dll
    0x76f20000 - 0x76f47000 C:\WINDOWS\system32\DNSAPI.dll
    0x76d60000 - 0x76d79000 C:\WINDOWS\system32\iphlpapi.dll
    0x76fb0000 - 0x76fb8000 C:\WINDOWS\System32\winrnr.dll
    0x76f60000 - 0x76f8c000 C:\WINDOWS\system32\WLDAP32.dll
    0x76fc0000 - 0x76fc6000 C:\WINDOWS\system32\rasadhlp.dll
    0x10000000 - 0x10052000 C:\Documents and Settings\bkonwar\Local Settings\Temp\jna5972695927945545932.tmp
    0x03510000 - 0x03546000 C:\WINDOWS\system32\zkemsdk.dll
    0x03560000 - 0x03574000 C:\WINDOWS\system32\commpro.dll
    0x662b0000 - 0x66308000 C:\WINDOWS\system32\hnetcfg.dll
    0x71a90000 - 0x71a98000 C:\WINDOWS\System32\wshtcpip.dll
    VM Arguments:
    jvm_args: -Dfile.encoding=Cp1252
    java_command: com.xyz.bhabs.fingerPrint
    Launcher Type: SUN_STANDARD
    Environment Variables:
    PATH=C:/Program Files/Java/jre6/bin/client;C:/Program Files/Java/jre6/bin;C:/Program Files/Java/jre6/lib/i386;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;;C:\Program Files\Java\jre1.6.0_07\bin;C:\Program Files\Android\android-sdk-windows\tools;C:\Program Files\TortoiseSVN\bin
    USERNAME=BKonwar
    OS=Windows_NT
    PROCESSOR_IDENTIFIER=x86 Family 6 Model 15 Stepping 13, GenuineIntel
    --------------- S Y S T E M ---------------
    OS: Windows XP Build 2600 Service Pack 3
    CPU:total 2 (2 cores per cpu, 1 threads per core) family 6 model 15 stepping 13, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3
    Memory: 4k page, physical 2085780k(1286036k free), swap 4024188k(3249652k free)
    vm_info: Java HotSpot(TM) Client VM (16.3-b01) for windows-x86 JRE (1.6.0_20-b02), built on Apr 12 2010 13:52:23 by "java_re" with MS VC++ 7.1 (VS2003)
    time: Wed May 25 10:02:24 2011
    elapsed time: 21 seconds
    Regards,
    Bhabs
    Edited by: 861222 on May 25, 2011 12:19 AM

    861222 wrote:
    # A fatal error has been detected by the Java Runtime Environment:
    # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0351fe3b, pid=1664, tid=3832Not much to tell here. This line here looks suspiciously like a null-pointer error happening in the native code. It is impossible to say how, where and why. Go back to your code and start debugging I'd say, see where invalid data can be passed to the native code.

Maybe you are looking for