1

I'm trying to use a jar file in c++ program using JNI.

I did this:

// TestJavaToCpp.cpp : Defines the entry point for the console application.
//

#include <jni.h>
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;


int main()
{
    JavaVM *jvm;
    JNIEnv *env;
    JavaVMInitArgs vm_args;
    JavaVMOption options;
    options.optionString = "-Djava.class.path=HelloWorld.jar";
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    vm_args.options = &options;
    vm_args.ignoreUnrecognized = 0;
    int ret = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    if (ret == 0) {
        jclass cls = env->FindClass("HelloWorld");
        if (cls != 0) {
            jmethodID meth = env->GetStaticMethodID(cls, "Hello", "([Ljava/lang/String;)V");
            jarray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), 0);
            env->CallStaticVoidMethod(cls, meth, args);
        }
    }
    return ret;
}

When HelloWorld.jar is in the same folder with the exe file. However, i keep getting the error

0xC0000005: Access violation reading location 0x0000000000000000

when it tries to create the JVM.

EDIT 1: Now code looks like this:

// TestJava.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <jni.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;

#define CLEAR(x) memset(&x, 0, sizeof(x))

int main()
{
    JavaVM *jvm(0);
    JNIEnv *env(0);
    JavaVMInitArgs vm_args;
    CLEAR(vm_args);
    JavaVMOption options;
    CLEAR(options);

    options.optionString = "-Djava.class.path=HelloWorld.jar";
    options.extraInfo = 0;
    vm_args.version = JNI_VERSION_1_8;
    vm_args.nOptions = 1;
    vm_args.options = &options;
    vm_args.ignoreUnrecognized = 0;
    int ret = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
        
    return 0;
}

I left only the code that actually creates the vm. When it'll work, I'll go on,

And now I have noticed to error that showed up before but i didn't pay attention to them:

'TestJava.exe' (Win32): Loaded 'C:\Users\amitb\OneDrive\מסמכים\Visual Studio 2015\Projects\TestJava\Debug\TestJava.exe'. Symbols loaded.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\apphelp.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\vcruntime140d.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ucrtbased.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Program Files (x86)\Java\jdk1.8.0_91\jre\bin\client\jvm.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\advapi32.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\user32.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcrt.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\gdi32.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\wsock32.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\winmm.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sechost.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\psapi.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\version.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\winmmbase.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcr100.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\rpcrt4.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\cfgmgr32.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ws2_32.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sspicli.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\cryptbase.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\bcryptprimitives.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\imm32.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Program Files (x86)\Java\jdk1.8.0_91\jre\bin\verify.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Program Files (x86)\Java\jdk1.8.0_91\jre\bin\java.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Program Files (x86)\Java\jdk1.8.0_91\jre\bin\zip.dll'. Cannot find or open the PDB file.

Exception thrown at 0x025A0202 in TestJava.exe: 0xC0000005: Access violation reading location 0x00000000.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\shell32.dll'. Cannot find or open the PDB file. 'TestJava.exe' (Win32): Loaded

'C:\Windows\SysWOW64\windows.storage.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\combase.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\shlwapi.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel.appcore.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\SHCore.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\powrprof.dll'. Cannot find or open the PDB file.

'TestJava.exe' (Win32): Loaded 'C:\Windows\SysWOW64\profapi.dll'. Cannot find or open the PDB file.

The thread 0x2760 has exited with code 0 (0x0).

The thread 0x494c has exited with code 0 (0x0).

The thread 0x3368 has exited with code 0 (0x0).

The thread 0x2e48 has exited with code 0 (0x0).

The thread 0x3d5c has exited with code 0 (0x0).

The thread 0x3b2c has exited with code 0 (0x0).

The thread 0x4490 has exited with code 0 (0x0).

The thread 0x3bb4 has exited with code 0 (0x0). The thread 0x4d18 has exited with code 0 (0x0).

The thread 0x2cac has exited with code 0 (0x0).

The thread 0x4ec8 has exited with code 0 (0x0).

The program '[18476] TestJava.exe' has exited with code 0 (0x0).

Look on the bold sentence. This is where the exception is being thrown...

Community
  • 1
  • 1
kitsuneFox
  • 1,243
  • 3
  • 18
  • 31
  • What do `GetStaticMethodID()`, `NewObjectArray()` and FindClass( "java/lang/String")` return? Your code merely *hopes* those work. – Andrew Henle Jun 06 '16 at 10:43
  • It crashes before the if statment in the line int ret = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); – kitsuneFox Jun 06 '16 at 10:47
  • Try the answers here: http://stackoverflow.com/questions/27435647/jni-createjavavm-crash-my-program-without-any-message-or-exception – samgak Jun 07 '16 at 04:13
  • @samgak I tried to load the jvm.dll dynamically like he did but still nothing. It just can't create the Jvm and i dont know why – kitsuneFox Jun 07 '16 at 04:29
  • https://stackoverflow.com/a/53654317/6160632 this help me – Dmitry Ivanov Dec 29 '22 at 18:44

1 Answers1

1

You need to set options.extraInfo = 0;

I would do all of this for good measure. Defensive programming demands that everything is initialized.

#define CLEAR(x) memset(&x, 0, sizeof(x))
JavaVM *jvm(0);
JNIEnv *env(0);
JavaVMInitArgs vm_args;
CLEAR(vm_args);
JavaVMOption options;
CLEAR(options);

Note:

typedef struct JavaVMOption {
    char *optionString;
    void *extraInfo;
} JavaVMOption;

EDIT: None of this turned out to be the problem. The solution is in the comments -- the JVM is throwing access violation exceptions. They are caught and handled, but not before Visual Studio leads you to believe there is a problem.

Wheezil
  • 3,157
  • 1
  • 23
  • 36
  • I compiled and ran your code in Visual Studio 2013 without error. The one change I had to make was this: vm_args.version = JNI_VERSION_1_6; Note also I am using Java 1.7 not 1.8, but I am unsure why that would matter. – Wheezil Jun 07 '16 at 21:01
  • One other thing to note. The JVM will throw (and handle!) access violation exceptions as part of its internal memory management. Just run the program in the debugger, but first choose "Debug->Exceptions..." and turn off "break on Win32 exceptions thrown". Set a breakpoint at "return 0". Does it get there? If so, you are golden. These spurious access violations will drive you mad. – Wheezil Jun 07 '16 at 21:06
  • Im using vs 2015 and Java 1.8. Could it be that there is a bug in that Java version? – kitsuneFox Jun 07 '16 at 21:06
  • I don't think its a bug in the JVM. See my previous comment about access violations... does that help? – Wheezil Jun 07 '16 at 21:07
  • Omg! It passed... I would never find this solution without you... This is so stupid... Let me just try to run the complete code to see if that works – kitsuneFox Jun 07 '16 at 21:33
  • Kindly mark my answer if it has indeed solved your problem :-) – Wheezil Jun 08 '16 at 03:29