JNI accessing a class that instantiates another class

Discussion in 'Java' started by Danno, Aug 15, 2011.

  1. Danno

    Danno Guest

    I'm taking my first stab at JNI. I have a main Java class that
    instantiates another class. In my C++ code, I am using the FindClass
    function for the main class and calling the method in the main class
    using GetStaticMethodId/CallStaticIntMethod. The C++ code is
    successfully finding the Java class and calling the method that I
    specified in the GetStaticMethoId function. The only problem is, when
    the Java class attempts to create an instance of this second, inner
    class, it dies. I don't get an error, it just doesn't work.

    My question is... Do I need another FindClass statement for the second
    class even though the C++ code is not invoking the second class
    directly? If so, how would I do that?

    Thanks so much for your insight!
    Danno, Aug 15, 2011
    #1
    1. Advertising

  2. * Danno:

    > I'm taking my first stab at JNI. I have a main Java class that
    > instantiates another class. In my C++ code, I am using the FindClass
    > function for the main class and calling the method in the main class
    > using GetStaticMethodId/CallStaticIntMethod. The C++ code is
    > successfully finding the Java class and calling the method that I
    > specified in the GetStaticMethoId function. The only problem is, when
    > the Java class attempts to create an instance of this second, inner
    > class, it dies. I don't get an error, it just doesn't work.


    Please post code demonstrating the problem. Have you checked if
    -Xcheck:jni reports anything useful?
    Florian Weimer, Aug 15, 2011
    #2
    1. Advertising

  3. Danno

    Danno Guest

    On Aug 15, 1:06 pm, Florian Weimer <> wrote:
    > * Danno:
    >
    > > I'm taking my first stab at JNI.  I have a main Java class that
    > > instantiates another class.  In my C++ code, I am using the FindClass
    > > function for the main class and calling the method in the main class
    > > using GetStaticMethodId/CallStaticIntMethod.  The C++ code is
    > > successfully finding the Java class and calling the method that I
    > > specified in the GetStaticMethoId function.  The only problem is, when
    > > the Java class attempts to create an instance of this second, inner
    > > class, it dies.  I don't get an error, it just doesn't work.

    >
    > Please post code demonstrating the problem.  Have you checked if
    > -Xcheck:jni reports anything useful?


    Thank you for taking the time to reply to my post. I have attached my
    code below. I have not used -Xcheck:jni before. I may not fully
    understand how to use it, but the way I understand it, it is a command
    line argument. The java program, however, is not being called from a
    command line. I have a MicroFocus COBOL program that is calling a C++
    dll that starts a JVM and invokes a Java method via JNI. Is there a
    way to run -Xcheck:jni under that scenario?

    Here is my code...

    C++:
    #include <jni.h>
    #include <windows.h>
    #include <string>
    #include <stdio.h>
    #include <stdlib.h>
    #include "IGVIEWER_JNI.H"

    using namespace std;

    bool initJNI() {
    JNILoaded = false;
    JavaVMOption options[1];
    JavaVMInitArgs vm_args;
    long status;

    options[0].optionString = "-Djava.class.path=.";
    memset(&vm_args, 0, sizeof(vm_args));
    vm_args.version = JNI_VERSION_1_4;
    vm_args.nOptions = 1;
    vm_args.options = options;
    status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

    if (status == 0) {
    cls = env->FindClass("IgViewerJNI");
    if(cls ==0) {
    jvm->DestroyJavaVM();
    return false;
    } else {
    JNILoaded = true;
    return true;
    }
    }
    else {
    return false;
    }

    }

    extern ULONG WINAPI IMGINIT_JNI () {
    jmethodID mid;
    bool bResults;

    if (!JNILoaded) {
    bResults = initJNI();
    if (!bResults) {
    return 8;
    }
    }

    mid = env->GetStaticMethodID(cls, "initializeViewer", "()I");
    if(mid !=0) {
    return env->CallStaticIntMethod(cls, mid);
    } else {
    return 8;
    }


    }




    Java:

    import javax.swing.JOptionPane;


    public class IgViewerJNI {

    public static int initializeViewer(){

    try {
    // ** THIS IS WHERE IT DIES - I didn't include
    the IgViewerInit class code since it seemed unnecessary.
    IgViewerInit viewInit = new IgViewerInit();
    return viewInit.initializeViewer();
    } catch (Exception e) {
    JOptionPane.showMessageDialog(null, "Error - "
    + e.getMessage());
    return 8;
    }
    }

    public static void main(String args[]) {


    }

    }
    Danno, Aug 15, 2011
    #3
  4. * Danno:

    > Thank you for taking the time to reply to my post. I have attached my
    > code below. I have not used -Xcheck:jni before. I may not fully
    > understand how to use it, but the way I understand it, it is a command
    > line argument. The java program, however, is not being called from a
    > command line. I have a MicroFocus COBOL program that is calling a C++
    > dll that starts a JVM and invokes a Java method via JNI. Is there a
    > way to run -Xcheck:jni under that scenario?


    The JVM cannot be linked into all processes as a library, at least on
    UNIX-like platforms. I'm not sure if Windows is different in this
    regard. In your case, the JVM does not seem to properly support
    exception handling.

    There are options that supposedly increase compatibility, see the JVM
    documentation.

    > options[0].optionString = "-Djava.class.path=.";


    I think you have to put "-Xcheck:jni" here, as an additional option.
    Florian Weimer, Aug 15, 2011
    #4
  5. Danno

    Roedy Green Guest

    On Mon, 15 Aug 2011 07:55:50 -0700 (PDT), Danno
    <> wrote, quoted or indirectly quoted someone
    who said :

    > The only problem is, when
    >the Java class attempts to create an instance of this second, inner
    >class, it dies. I don't get an error, it just doesn't work.


    This why JNI is so difficult. The Java trace will not follow the code
    through it. Is there anything that will do that?

    My rule of thumb is to do everything in Java you possibly can, and do
    only in C++ what you can't do in Java.

    You might consider creating the object in Java and passing it in as a
    reference.

    To handle it the way you want, however, create a test program that
    does absolutely nothing else but create a Java object in JNI. That way
    you get all distractions out the way. Also scan the net for sample
    code that creates Java objects in C++ to see if there is some catch.

    If you don't have a textbook, get one. Almost nothing about JNI is
    obvious.

    see http://mindprod.com/jgloss/jni.html
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Most of computer code is for telling the computer
    what do if some very particular thing goes wrong.
    Roedy Green, Aug 15, 2011
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    451
  2. hubritic
    Replies:
    4
    Views:
    248
    Aaron Brady
    Apr 14, 2009
  3. Replies:
    1
    Views:
    342
  4. Matt Hicks
    Replies:
    7
    Views:
    225
    Peter J. Holzer
    Dec 23, 2012
  5. Rainer Weikusat
    Replies:
    5
    Views:
    221
    Rainer Weikusat
    Dec 19, 2012
Loading...

Share This Page