Java Native Interface problems

Started by
4 comments, last by Antheus 16 years, 10 months ago
I am launching a Java Virtual Machine from my c++ code and attempting to create an instance of my custom "JavaClass" class or one of the native classes such as the Java String. However it crashes upon invoking the FindClass method. Below is my source, if anyone sees anything glaringly wrong please let me know.

//My Java Class which makes a simple JFrame with a label
//It works fine from within Java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class JavaClass 
{
    static
    {
        System.loadLibrary( "JavaClass" );
    }
    
    
    private JFrame frame;
    private JLabel label;
 
    public JavaClass() 
    {
        
    }
    
    public native void Call_MakeJFrame();
    
    public void MakeJFrame()
    {
        frame = new JFrame("JFrame Source Demo");
        frame.setSize(512, 512);
        frame.setVisible( true );
        
         //Add a window listner for close button
        frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});

        label = new JLabel( "label");
        label.setSize( 100, 50 );
        frame.getContentPane().add(label);   
    }
    
}



//This is my c++ code which is trying to make an instance of JavaClass

#include <iostream>
#include "javaclass.h"
using namespace std;



JNIEXPORT void JNICALL Java_JavaClass_Call_1MakeJFrame(JNIEnv* JEnv, jobject JObj)
{
	//don't need this right now, just look at the main function
}

int main()
{
	JavaVM*				JavaVirtualMachine;
	JNIEnv*				JavaNativeEnvironment;
	JavaVMInitArgs		VirtualMachineInitArgs;
	JavaVMOption		VirtualMachineOptions[1];

	VirtualMachineOptions[0].optionString = "-Djava.class.path=C:\\Documents and Settings\\conway.m\\JavaClassLib\\build\\classes\\";
	VirtualMachineInitArgs.version  = JNI_VERSION_1_6;
	VirtualMachineInitArgs.nOptions = 1;
	VirtualMachineInitArgs.options = VirtualMachineOptions;
	VirtualMachineInitArgs.ignoreUnrecognized = JNI_FALSE;

	JNI_CreateJavaVM( &JavaVirtualMachine, (void**) &JavaNativeEnvironment, &VirtualMachineInitArgs );

	cout << "before FindClass\n";
	
	//crashes here
	jclass JavaClass = JavaNativeEnvironment->FindClass( "JavaClass" );

	cout << "after FindClass\n";

	JavaVirtualMachine->DestroyJavaVM();
	return 0;
}

Advertisement
JNI_CreateJavaVM returns a result.

Check that first to see if the engine was created at all.

Also, add "-verbose:jni" to you command line arguments.
Here is my modified main function. JNI_CreateJavaVM returns -1 which indicates there was an error in creating the virtual machine. I am not sure if there is a way to get a printout of the error from my error code. I also am not sure how to get printouts of the output from setting my verbose option.

int main(){	JavaVM*				JavaVirtualMachine;	JNIEnv*				JavaNativeEnvironment;	JavaVMInitArgs		VirtualMachineInitArgs;	JavaVMOption		VirtualMachineOptions[1];	VirtualMachineOptions[0].optionString = "-Djava.class.path=C:\\Documents and Settings\\conway.m\\JavaClassLib\\build\\classes\\";	VirtualMachineOptions[1].optionString = "-verbose:jni"; 	VirtualMachineInitArgs.version  = JNI_VERSION_1_6;	VirtualMachineInitArgs.nOptions = 2;	VirtualMachineInitArgs.options = VirtualMachineOptions;	VirtualMachineInitArgs.ignoreUnrecognized = JNI_FALSE;	long ErrorCode = JNI_CreateJavaVM( &JavaVirtualMachine, (void**) &JavaNativeEnvironment, &VirtualMachineInitArgs );	cout << "ErrorCode for CreateJavaVM: " << ErrorCode << "\n";	cout << "before FindClass\n";		//crashes here	jclass JavaClass = JavaNativeEnvironment->FindClass( "()Ljava\\lang\\String" );	cout << "after FindClass\n";	JavaVirtualMachine->DestroyJavaVM();	return 0;}
Try this syntax:
JavaVMInitArgs vm_args;JNI_GetDefaultJavaVMInitArgs(&vm_args);res = JNI_CreateJavaVM(&jvm,&env,&vm_args);if (res < 0) {  fprintf(stderr, "Can't create Java VM\n");}


Also make sure that the JVM is actually available as a library (via path). Application needs to have access to full installation, not just jvm.dll.
When filling my options with the default arguments, I now get an error code of -3.

How do I make sure that the JVM is available as a path?
-3 = EVERSION error, or, you're requesting JNI protocol your JVM doesn't support.

If you have 1.6 installed, then it's likely your path references some other JVM first.

Try:
set PATH=c:\jdk1.6\jre\bin\client;%PATH%  <-- obviously path to your 1.6 jvm, %PATH% is laststart_jvm.exe   <-- your exe

This topic is closed to new replies.

Advertisement