Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (764)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (852)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Invoking a JVM through JNI  (Read 17104 times)
0 Members and 1 Guest are viewing this topic.
Offline Marvin Fröhlich

Senior Devvie




May the 4th, be with you...


« Posted 2009-06-24 21:43:43 »

I am trying to create a native application, that invokes a JVM. It compiles fine now, but doesn't execute. When I try to execute the resulting native executable "tester.exe", it fails with the following message:

1  
2  
Error occurred during initialization of VM
Unable to load native library: Can't find dependent libraries


I have no idea, what dependent libraries are missing and how I can tell the program to find them.

This is the code of the native program:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
    JavaVM* jvm; // denotes a Java VM
    JNIEnv* env; // pointer to native method interface
    JavaVMInitArgs vm_args; // JDK/JRE 6 VM initialization arguments
    JavaVMOption* options = new JavaVMOption[1];
    //options[0].optionString = "-Djava.library.path=C:\\Programme\\Java\\jre6\\bin;.;C:\\WINDOWS\\Sun\\Java\\bin;C:\\WINDOWS\\system32;C:\\WINDOWS;C:/Programme/Java/jre6/bin/client;C:/Programme/Java/jre6/bin;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem";
    //options[0].optionString = "-Djava.library.path=C:\\Programme\\Java\\jre6\\bin";
    options[0].optionString = "-Djava.class.path=D:\\rfdynhud.jar";
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = false;
    // load and initialize a Java VM, return a JNI interface pointer in env
    JNI_CreateJavaVM( &jvm, (void**)&env, &vm_args ); // This is where the program exists with exit code 1. The Process is terminated here. The next line won't be executed.
    //printf( "%u\n", ret );
    //if ( ret == 0 )
        return;
    //delete options;
    // invoke the Main.test method using the JNI
    //jclass cls = env->FindClass( "net/ctdp/rfdynhud/RFDynHUD" );
    //jmethodID mid = env->GetStaticMethodID( cls, "dumpSomething", "(I)V" );
    //env->CallStaticVoidMethod( cls, mid, 123 );
    // We are done.
    //jvm->DestroyJavaVM();


Any clues? I am completely lost.

Marvin
Offline Riven
Administrator

« JGO Overlord »


Medals: 1342
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2009-06-24 22:35:49 »

You seem to have tried everything, except ...\jre\lib

 Huh

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Marvin Fröhlich

Senior Devvie




May the 4th, be with you...


« Reply #2 - Posted 2009-06-24 23:51:30 »

You seem to have tried everything, except ...\jre\lib

Do you mean "...\jre\lib"? I tried that as well as "jre\lib". It doesn't work.

I just used Dependency Walker on the jvm.dll and it says, that it misses three dlls called ieshims.dll, wer.dll and efsadu.dll. Does anybody know these dlls and where I can (savely) get them?

Marvin
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Stranger
« Reply #3 - Posted 2009-06-25 16:09:02 »

I just used Dependency Walker on the jvm.dll and it says, that it misses three dlls called ieshims.dll, wer.dll and efsadu.dll. Does anybody know these dlls and where I can (savely) get them?

afaik, ieshims.dll, wer.dll - Windows Vista files

Quote
efsadu.dll is only installed if you've enabled the Encrypting File System on one of your drives.

Anton
Offline Marvin Fröhlich

Senior Devvie




May the 4th, be with you...


« Reply #4 - Posted 2009-06-25 21:06:39 »

afaik, ieshims.dll, wer.dll - Windows Vista files

I don't have Vista (using XP), nor have I enabled encryption. So I assume, these DLLs shouldn't needed and their missing is not the cause of my problems.

Has anybody every tried to use the invocation framework?

Marvin
Offline princec

« JGO Spiffy Duke »


Medals: 1042
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #5 - Posted 2009-06-25 22:05:58 »

I use JNI invocation for all my games and they work fine AFAIK.

Cas Smiley

Offline cylab

JGO Kernel


Medals: 182



« Reply #6 - Posted 2009-06-25 22:20:51 »

I use JNI invocation for all my games and they work fine AFAIK.

Cas Smiley

Like he wants to? Invoking a JVM from a C/C++ program and not the other way around? The native aplication is the host in this case...

Mathias - I Know What [you] Did Last Summer!
Offline Marvin Fröhlich

Senior Devvie




May the 4th, be with you...


« Reply #7 - Posted 2009-06-25 23:39:27 »

Like he wants to? Invoking a JVM from a C/C++ program and not the other way around? The native aplication is the host in this case...

Yes. Very most tutorials deal with the other way round (a Java program defines a native method and is the host). And I can find absolutely not a single tutorial about how to correctly setup a Visual C++ project for that or how to configure your environment.

It is also strange, that no tutorial describes, how to compile or write your C++ program, so that it finds the Java dlls in the installation path.

@princec: If you really use invocation, could you possibly give kick to get started?

Marvin
Offline Martin Strand

Junior Devvie





« Reply #8 - Posted 2009-06-26 00:24:42 »

Perhaps you could have a look at a java executable wrapper to get started, they invoke the JVM from C code.
http://launch4j.sourceforge.net/
Offline princec

« JGO Spiffy Duke »


Medals: 1042
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #9 - Posted 2009-06-26 14:42:14 »

Er, no. My games are Windows executables that invoke a JVM.

Cas Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

« JGO Spiffy Duke »


Medals: 1042
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #10 - Posted 2009-06-26 14:45:02 »

Like this: (warning: crap code alert)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
/*
 * Droid Assault launcher
 */


#include "launcher.h"

#define OPTIONS 7

static JNIEnv *env;
static jobject jobj = 0;
static JavaVM *vm;

/*
 * Display an error message
 */

void messageBox(char * message) {
   MessageBox(NULL, message, APP_TITLE, MB_OK);
}

typedef jint (APIENTRY * CreateJavaVMPROC) (JavaVM **pvm, void **penv, void *args);

/*
 * Invoke our embedded JVM
 */

int WINAPI WinMain
(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
)
{
    jint res;
   jclass cls;
    jmethodID mid;
    jobjectArray args;
    JavaVMInitArgs vm_args;
    JavaVMOption options[OPTIONS];

   options[0].optionString = "-Djava.class.path=patch.jar;DroidAssault.jar;gamecommerce.jar;spgl-lite.jar;common.jar;jorbis.jar;lwjgl.jar;lwjgl_util.jar;jinput.jar;music.jar;resources.jar";
   options[1].optionString = "-Dworkdir=.";
   options[2].optionString = "-Xms96m";
   options[3].optionString = "-Xmx96m";
   options[4].optionString = "-XX:MaxGCPauseMillis=5";
   options[5].optionString = "-XX:+UseAdaptiveSizePolicy";
   options[6].optionString = "-Xincgc";

   HMODULE jvmdll = LoadLibrary("bin\\client\\jvm.dll");
   if (jvmdll == NULL) {
      messageBox("Failed to load Java dll.");
   }

    vm_args.version = JNI_VERSION_1_2;
    vm_args.options = options;
    vm_args.nOptions = OPTIONS;
    vm_args.ignoreUnrecognized = TRUE;

   CreateJavaVMPROC CreateJavaVM = (CreateJavaVMPROC) GetProcAddress(jvmdll, "JNI_CreateJavaVM");

    res = CreateJavaVM(&vm, (void **)&env, &vm_args);

    if (res < 0) {
      messageBox("Failed to create Java virtual machine.");
        return 0;
    }

    // Get the main class
    cls = env->FindClass(MAIN_CLASS);

    if (cls == 0) {
        messageBox("Failed to find the main class.");
        return 0;
    }

    // Get the method ID for the class's main(String[]) function.
    mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");

    if (mid == 0) {
        messageBox("Failed to find the main method.");
        return 0;
    }
    args = env->NewObjectArray(0, env->FindClass("java/lang/String"), NULL);

    // Run the main class...
    env->CallStaticVoidMethod(cls, mid, args);

   return 1;

}


Cas Smiley

Offline Marvin Fröhlich

Senior Devvie




May the 4th, be with you...


« Reply #11 - Posted 2009-06-29 16:05:48 »

Thank you so much, Cas. This is exactly, what I needed and it really works.

I have a few new questions:

Do I have to unload a library loaded through LoadLibrary()? I couldn't find a function for that.

The installation path of the jre is not in my PATH environment variable not anywhere else, where it could be found through standard searches, so I have to use the full path for LoadLibrary() to load msvcr71.dll and jvm.dll. I could inspect the registry to find the path. But I guess, there's some common way to find the java installation path, is there? I am using a standard java installation (no modified paths, etc.).

Is it important, whether I use JNI_VERSION_1_2 or JNI_VERSION_1_6?

Marvin
Offline princec

« JGO Spiffy Duke »


Medals: 1042
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #12 - Posted 2009-06-29 16:53:00 »

No idea about the difference between 1_2 and 1_6. There probably exists an API to get the path to the currently installed runtime but I don't know what it is and in any case I don't trust existing runtimes, I always embed the JVM installation privately and use that, thus bypassing the problem (and many others) completely. But you can otherwise just look in the system registry - the Sun JVMs stash the path in there, but it's in HKLM rather than HKCU and therefore may require elevated privileges to read on Vista.

I've never bothered unloading a library but then I never need to do anything fancy on app exit, I just quit the process and the OS takes care of cleanup.

Cas Smiley

Offline Marvin Fröhlich

Senior Devvie




May the 4th, be with you...


« Reply #13 - Posted 2009-06-29 21:55:19 »

ok, thank you very much.

Marvin
Offline Marvin Fröhlich

Senior Devvie




May the 4th, be with you...


« Reply #14 - Posted 2009-06-30 01:36:29 »

I'm sorry, but I have a new question.

I have a simple example class with an instance method as follows:
1  
2  
3  
4  
5  
6  
7  
public class MyClass
{
    public int getInt()
    {
        return ( 1234567 );
    }
}


In my native (invocation) code I first get the class and the do the following:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
jmethodID mid = env->GetMethodID( cls, "<init>", "(II)V" );

if ( mid == 0 )
{
    messageBox( "Failed to find the constructor method." );
    return ( FALSE );
}

jobject obj = env->NewObject( cls, mid, 123, 456 );

mid = env->GetMethodID( cls, "getInt", "()I" );

if ( mid == 0 )
{
    messageBox( "Failed to find the getInt() method." );
    return ( FALSE );
}

jint i = env->CallIntMethod( obj, mid );
std::cout << i; std::cout << "\n";


The returned integer is always 0 (zero). If I try the same with a method retuning an object, the object will always be NULL.

The same will work perfectly with a static method. What am I doing wrong?

Marvin
Offline princec

« JGO Spiffy Duke »


Medals: 1042
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #15 - Posted 2009-06-30 10:58:07 »

You never checked obj to see if you got something or not. And what I suspect you'll find is that it's null, and you've got an exception pending, which is that you didn't have access to the constructor, which you've not defined and is therefore package private Smiley

I am a human compiler  Cool

Cas Smiley

Offline Stranger
« Reply #16 - Posted 2009-06-30 14:12:29 »


1  
2  
jmethodID mid = env->GetMethodID( cls, "<init>", "(II)V" );
...


You typed wrong signature for default constructor, should be "()V".
 

Anton
Offline Marvin Fröhlich

Senior Devvie




May the 4th, be with you...


« Reply #17 - Posted 2009-06-30 18:12:16 »

It works now. There was indeed something going wrong in the constructor.

Is there a way to read the last exception's message in the native code?

Thanks a lot again.

Marvin
Offline Roquen

JGO Kernel


Medals: 517



« Reply #18 - Posted 2009-07-01 07:12:22 »

Look at: ExceptionOccurred, ExceptionDescribe & ExceptionClear in the JNI ref.
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #19 - Posted 2009-07-03 00:29:17 »

You never checked obj to see if you got something or not. And what I suspect you'll find is that it's null, and you've got an exception pending, which is that you didn't have access to the constructor, which you've not defined and is therefore package private Smiley

I am a human compiler  Cool

Cas Smiley

A broken human compiler ;-)

With no constructors defined the default no-args constructor is public not package private. 

Offline princec

« JGO Spiffy Duke »


Medals: 1042
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #20 - Posted 2009-07-03 00:48:36 »

Cheesy Half right then Wink
You know, I didn't know that! I thought it was package private. Mind you I almost never declare things without constructors.

Cas Smiley

Pages: [1]
  ignore  |  Print  
 
 

 
EgonOlsen (591 views)
2018-06-10 19:43:48

EgonOlsen (694 views)
2018-06-10 19:43:44

EgonOlsen (478 views)
2018-06-10 19:43:20

DesertCoockie (831 views)
2018-05-13 18:23:11

nelsongames (1026 views)
2018-04-24 18:15:36

nelsongames (1083 views)
2018-04-24 18:14:32

ivj94 (1664 views)
2018-03-24 14:47:39

ivj94 (590 views)
2018-03-24 14:46:31

ivj94 (1501 views)
2018-03-24 14:43:53

Solater (568 views)
2018-03-17 05:04:08
Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46

Deployment and Packaging
by philfrei
2018-08-19 23:53:08

Deployment and Packaging
by philfrei
2018-08-19 23:50:04

Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!