简体   繁体   中英

JNI - Class loading problem. DefineClass function doesn't seems to work

I'm trying to load specific classes using JNI. The problem is that DefineClass() function doesn't seems to work. And when I try to run function FindClass() it throws ClassNotFoundError . The class that I'm trying to load is a simple Main class with main method and "hello from world" in it. And it's package is correct.

This is what I've managed to do:

#include <iostream>
#include <fstream>
#include <jni.h>

int main() {

    JavaVM *jvm;
    JNIEnv* env;

    JavaVMInitArgs arguments;
    JavaVMOption* options = new JavaVMOption[1];
    
    options[0].optionString = "-Djava.class.path=";

    arguments.version = JNI_VERSION_1_8;
    arguments.nOptions = 1;
    arguments.options = options;
    arguments.ignoreUnrecognized = false;

    jint response = JNI_CreateJavaVM(&jvm, (void**)&env, &arguments);
    delete[] options;

    if (response != JNI_OK) {
        std::cin.get();
        return 0;
    }

    std::cout << "JVM load succeeded. Version ";
    jint ver = env->GetVersion();
    std::cout << ((ver >> 16) & 0x0f) << "." << (ver & 0x0f) << std::endl;

    std::ifstream fl("C:/Users/Admin/Desktop/Main.class");
    fl.seekg(0, std::ios::end);
    size_t lenght = fl.tellg();
    char* buffer = new char[lenght];
    fl.seekg(0, std::ios::beg);
    fl.read(buffer, lenght);
    fl.close();

    jclass mainClazz = env->DefineClass("Main", NULL, (const jbyte*) buffer, lenght);

    delete[] buffer;
    
    if (mainClazz == nullptr) {
        std::cout << "ERROR: class not found!";
        jvm->DestroyJavaVM();
        return 0;
    }

    jmethodID mainMethod = env->GetStaticMethodID(mainClazz, "main", "([Ljava/lang/String;)V");

    jobjectArray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), 0);

    env->CallStaticVoidMethod(mainClazz, mainMethod, args);

    jvm->DestroyJavaVM();
    return 0;
}

If DefineClass fails you should see if there are any pending exceptions. The exception will probably be that your class file is malformed somehow, because you are opening your ifstream in text mode, where it happily replaces 0x0A bytes with a 0x0D 0x0A pair.

Use binary mode instead:

std::ifstream fl("C:/Users/Admin/Desktop/Main.class", std::ios::binary | std::ios::in);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM