JNI - Class 加载问题。 DefineClass 函数似乎不起作用
JNI - Class loading problem. DefineClass function doesn't seems to work
我正在尝试使用 JNI 加载特定的 classes。问题是 DefineClass()
功能似乎不起作用。当我尝试 运行 函数 FindClass()
时,它抛出 ClassNotFoundError
。我要加载的 class 是一个简单的 Main class,其中包含 main 方法和“hello from world”。而且它的包装是正确的。
这是我设法做到的:
#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;
}
如果 DefineClass
失败,您应该查看是否有任何未决的异常。
例外情况可能是您的 class 文件格式不正确,因为您在文本模式下打开 ifstream
,它很乐意用 0x0D 0x0A 对替换 0x0A 字节。
改为使用二进制模式:
std::ifstream fl("C:/Users/Admin/Desktop/Main.class", std::ios::binary | std::ios::in);
我正在尝试使用 JNI 加载特定的 classes。问题是 DefineClass()
功能似乎不起作用。当我尝试 运行 函数 FindClass()
时,它抛出 ClassNotFoundError
。我要加载的 class 是一个简单的 Main class,其中包含 main 方法和“hello from world”。而且它的包装是正确的。
这是我设法做到的:
#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;
}
如果 DefineClass
失败,您应该查看是否有任何未决的异常。
例外情况可能是您的 class 文件格式不正确,因为您在文本模式下打开 ifstream
,它很乐意用 0x0D 0x0A 对替换 0x0A 字节。
改为使用二进制模式:
std::ifstream fl("C:/Users/Admin/Desktop/Main.class", std::ios::binary | std::ios::in);