简体   繁体   English

JNI - Class 加载问题。 DefineClass function 似乎不起作用

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

I'm trying to load specific classes using JNI.我正在尝试使用 JNI 加载特定的类。 The problem is that DefineClass() function doesn't seems to work.问题是DefineClass() function 似乎不起作用。 And when I try to run function FindClass() it throws ClassNotFoundError .当我尝试运行 function FindClass()它抛出ClassNotFoundError The class that I'm trying to load is a simple Main class with main method and "hello from world" in it.我试图加载的 class 是一个简单的 Main class ,其中包含 main 方法和“来自世界的你好”。 And it's package is correct.它的 package 是正确的。

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.如果DefineClass失败,您应该查看是否有任何未决的异常。 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.例外情况可能是您的 class 文件格式不正确,因为您在文本模式下打开ifstream ,它很乐意用 0x0D 0x0A 对替换 0x0A 字节。

Use binary mode instead:改用二进制模式:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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