Jump to content
  • Advertisement
Sign in to follow this  
Khaos Dragon

Java Native Interface problems

This topic is 4147 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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;
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
-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 last
start_jvm.exe <-- your exe


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!