0

I want call java function from Qt application. I have succeed to create javaVM but I have problem to get my java class.

main.cpp

#include <jni.h>
#include <qDebug>
#include <string.h>
#include <windows.h>

#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif

int main()
{
    JavaVMOption options[1];
    JNIEnv *env;
    JavaVM *jvm;
    JavaVMInitArgs vm_args;
    long status;
    jclass cls;
    jmethodID mid;
    jint square;
    typedef jint(JNICALL *pCreateJavaVM)(JavaVM **, void**, void *);

    HINSTANCE hInstance = LoadLibrary(L"C:\\Program Files (x86)\\Java\\jdk1.8.0_101\\jre\\bin\\client\\jvm.dll");
    qDebug()<<"histance"<<hInstance;
    pCreateJavaVM CreateJavaVM = (pCreateJavaVM)GetProcAddress(hInstance, "JNI_CreateJavaVM");

    options[0].optionString = "-Djava.class.path=.";
    vm_args.version = JNI_VERSION_1_2;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = JNI_TRUE;
    status = CreateJavaVM(&jvm, (void**)&env, &vm_args);

    qDebug()<<"status"<<status;
    if (status != JNI_ERR)
    {
        //cls = (env)->FindClass("Test");
        cls = (env)->FindClass("java/Test");
        if(cls !=0)
        {   mid = (env)->GetStaticMethodID( cls, "intMethod", "(I)I");
            if(mid !=0)
            {
                square = (env)->CallStaticIntMethod(cls, mid, 5);
                qDebug()<<"square"<<"5²"<<square;
            }else qDebug()<<"function not found";

        } else qDebug()<<"class not found";

        (jvm)->DestroyJavaVM();
        return 0;
    }
    else
        qDebug()<<"jni error"<<status;
        return -1;
}

Test.java

public class Test
  {
    public static int intMethod(int n) {
        return n*n;
    }
 }

.pro

TEMPLATE = app

CONFIG += c++11

SOURCES += main.cpp

# Default rules for deployment.
include(deployment.pri)

INCLUDEPATH += "C:/Program Files (x86)/Java/jdk1.8.0_101/include"
DEPENDPATH += "C:/Program Files (x86)/Java/jdk1.8.0_101/include"

INCLUDEPATH += "C:/Program Files (x86)/Java/jdk1.8.0_101/include/win32"
DEPENDPATH += "C:/Program Files (x86)/Java/jdk1.8.0_101/include/win32"

LIBS += -L"C:/Program Files (x86)/Java/jdk1.8.0_101/lib/" -ljvm

HEADERS +=

DISTFILES += \
    java/Test.java

folder

MyProject/
    |__MyProject.pro
    |__MyProject.pro.user
    |__deployment.pri
    |__main.cpp
    |__java/
        |__Test.java

I think my file is on the wrong place but i don't know where I have to copy it


Edit : I have compiled my file .java to .class (with javac) and edit my file main.cpp :

#include <jni.h>
#include <qDebug>
#include <string.h>
#include <windows.h>

#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
#define PATH_SEPARATOR ':'
#endif

int main()
{
    JavaVMOption options[1];
    JNIEnv *env;
    JavaVM *jvm;
    JavaVMInitArgs vm_args;
    long status;
    jclass cls;
    jmethodID mid;
    jint square;
    typedef jint(JNICALL *pCreateJavaVM)(JavaVM **, void**, void *);

    HINSTANCE hInstance = LoadLibrary(L"C:\\Program Files (x86)\\Java\\jdk1.8.0_101\\jre\\bin\\client\\jvm.dll");
    qDebug()<<"histance"<<hInstance;
    pCreateJavaVM CreateJavaVM = (pCreateJavaVM)GetProcAddress(hInstance, "JNI_CreateJavaVM");

    options[0].optionString = "-Djava.class.path=classes:.";
    vm_args.version = JNI_VERSION_1_2;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = JNI_TRUE;
    status = CreateJavaVM(&jvm, (void**)&env, &vm_args);

    qDebug()<<"status"<<status;
    if (status != JNI_ERR)
    {
        cls = (env)->FindClass("Test");
        if(cls !=0)
        {   mid = (env)->GetStaticMethodID( cls, "intMethod", "(I)I");
            if(mid !=0)
            {
                square = (env)->CallStaticIntMethod(cls, mid, 5);
                qDebug()<<"square"<<"5²"<<square;
            }else qDebug()<<"function not found";

        } else qDebug()<<"class not found";

        (jvm)->DestroyJavaVM();
        return 0;
    }
    else
        qDebug()<<"jni error"<<status;
        return -1;
}

folder

MyProject/
    |__MyProject.pro
    |__MyProject.pro.user
    |__deployment.pri
    |__main.cpp
    |__classes/
        |__Test.class

My class isn't found

1 Answer 1

1

3 things:

  1. The .java file has to be compiled with javac into a .class file. Put this Test.class file in a "classes" directory.

  2. the .class file has to be reachable in the path declared by

    -Djava.class.path=.

    Say instead

    -Djava.class.path=classes:.

  3. FindClass just takes a class name, not a path. So it should be "Test".

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your help but I have the same result. Maybe i's because I have warning "deprecated conversion from string constant to 'char *'; I have edit my post
A warning shouldnt matter. If the app is reporting the class is not found- where is the c++ app being run from? Does the compiled binary get dropped in an "out" directory or something? Try putting the Test.class file in that directory.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.