JNI accessing a class that instantiates another class

D

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.

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!
 
F

Florian Weimer

* 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?
 
D

Danno

* Danno:


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[]) {


}

}
 
F

Florian Weimer

* 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.
 
R

Roedy Green

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top