JNI FindClass returns NULL - 很奇怪
JNI FindClass returns NULL - very strange
我知道 https://whosebug.com/ 上有很多类似的问题,但没有一个能解决我的问题。
我有一个简单的 Java Class 没有包:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TestConsoleHandler {
private static Thread hook;
static File f = new File("c:\Users\ArtUrlWWW\Documents\NetBeansProjects\mavenproject1\shutdown.txt");
public static void main(String[] args) {
FileWriter fw = null;
try {
try {
f.createNewFile();
} catch (Exception ex) {
Logger.getLogger(TestConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
}
fw = new FileWriter(f);
fw.write("Start \r\n");
fw.close();
System.out.println();
hook = new ShutdownHook();
Runtime.getRuntime().addShutdownHook(hook);
replaceConsoleHandler(); // actually not "replace" but "add"
try {
Thread.sleep(10000); // You have 10 seconds to close console
} catch (InterruptedException e) {
}
} catch (IOException ex) {
Logger.getLogger(TestConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
fw.close();
} catch (IOException ex) {
Logger.getLogger(TestConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void shutdown() {
try {
FileWriter fw = new FileWriter(f);
fw.write("Running shutdown \r\n");
fw.close();
hook.run();
} catch (IOException ex) {
Logger.getLogger(TestConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static native void replaceConsoleHandler();
static {
System.loadLibrary("sdh");
}
}
我想从 JNI 中调用 class:
// JavaService.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include "jni.h"
typedef struct JavaVMCreationResult {
JavaVM* jvm;
JNIEnv* env;
} JVMCreationResult;
JVMCreationResult* CreateJavaVM() {
JavaVM* jvm;
JNIEnv* env;
JavaVMInitArgs vm_args;
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=c:/Users/ArtUrlWWW/Documents/NetBeansProjects/mavenproject1/target/";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
JVMCreationResult* cres = new JVMCreationResult();
cres->jvm = jvm;
cres->env = env;
env->GetJavaVM(&jvm);
jint res = jvm->AttachCurrentThread((void **)(&env), &env);
return cres;
}
int _tmain(int argc, _TCHAR* argv[])
{
JVMCreationResult* cres = CreateJavaVM();
if (!cres) return -1;
JavaVM* jvm = cres->jvm;
JNIEnv* env = cres->env;
if (&env == NULL) {
printf("env IS NULL!!! \n\n");
}
jint res = jvm->AttachCurrentThread((void **)(&env), &env);
printf("STEP 1 \n\n");
jclass cls = env->FindClass("TestConsoleHandler");
printf("STEP 2 \n\n");
if (cls == NULL) {
printf("Class IS NULL!!! \n\n");
}
printf("STEP 3 \n\n");
/*jmethodID mid = env->GetStaticMethodID(cls, "shutdown", "()V");
printf("STEP 4 \n\n");
env->CallStaticVoidMethod(cls, mid);
jvm->DetachCurrentThread();*/
return 0;
}
在 c:/Users/ArtUrlWWW/Documents/NetBeansProjects/mavenproject1/target/ 我有 1.jar ,其中包含所需的 classes:
但是我的程序找不到 class TestConsoleHandler
:
请指教,如何解决这个问题?
非常感谢!
问题出在代码 System.loadLibrary("sdh");
中。替换为
后
System.load("c:/Users/ArtUrlWWW/Documents/NetBeansProjects/mavenproject1/sdh.dll");
一切正常。
正如您已经指出的答案,我将添加函数
System.loadLibrary("sdh");
寻找文件 "libsdh.so",这就是它不起作用的原因。
我知道 https://whosebug.com/ 上有很多类似的问题,但没有一个能解决我的问题。
我有一个简单的 Java Class 没有包:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TestConsoleHandler {
private static Thread hook;
static File f = new File("c:\Users\ArtUrlWWW\Documents\NetBeansProjects\mavenproject1\shutdown.txt");
public static void main(String[] args) {
FileWriter fw = null;
try {
try {
f.createNewFile();
} catch (Exception ex) {
Logger.getLogger(TestConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
}
fw = new FileWriter(f);
fw.write("Start \r\n");
fw.close();
System.out.println();
hook = new ShutdownHook();
Runtime.getRuntime().addShutdownHook(hook);
replaceConsoleHandler(); // actually not "replace" but "add"
try {
Thread.sleep(10000); // You have 10 seconds to close console
} catch (InterruptedException e) {
}
} catch (IOException ex) {
Logger.getLogger(TestConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
fw.close();
} catch (IOException ex) {
Logger.getLogger(TestConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void shutdown() {
try {
FileWriter fw = new FileWriter(f);
fw.write("Running shutdown \r\n");
fw.close();
hook.run();
} catch (IOException ex) {
Logger.getLogger(TestConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static native void replaceConsoleHandler();
static {
System.loadLibrary("sdh");
}
}
我想从 JNI 中调用 class:
// JavaService.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include "jni.h"
typedef struct JavaVMCreationResult {
JavaVM* jvm;
JNIEnv* env;
} JVMCreationResult;
JVMCreationResult* CreateJavaVM() {
JavaVM* jvm;
JNIEnv* env;
JavaVMInitArgs vm_args;
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=c:/Users/ArtUrlWWW/Documents/NetBeansProjects/mavenproject1/target/";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
JVMCreationResult* cres = new JVMCreationResult();
cres->jvm = jvm;
cres->env = env;
env->GetJavaVM(&jvm);
jint res = jvm->AttachCurrentThread((void **)(&env), &env);
return cres;
}
int _tmain(int argc, _TCHAR* argv[])
{
JVMCreationResult* cres = CreateJavaVM();
if (!cres) return -1;
JavaVM* jvm = cres->jvm;
JNIEnv* env = cres->env;
if (&env == NULL) {
printf("env IS NULL!!! \n\n");
}
jint res = jvm->AttachCurrentThread((void **)(&env), &env);
printf("STEP 1 \n\n");
jclass cls = env->FindClass("TestConsoleHandler");
printf("STEP 2 \n\n");
if (cls == NULL) {
printf("Class IS NULL!!! \n\n");
}
printf("STEP 3 \n\n");
/*jmethodID mid = env->GetStaticMethodID(cls, "shutdown", "()V");
printf("STEP 4 \n\n");
env->CallStaticVoidMethod(cls, mid);
jvm->DetachCurrentThread();*/
return 0;
}
在 c:/Users/ArtUrlWWW/Documents/NetBeansProjects/mavenproject1/target/ 我有 1.jar ,其中包含所需的 classes:
但是我的程序找不到 class TestConsoleHandler
:
请指教,如何解决这个问题?
非常感谢!
问题出在代码 System.loadLibrary("sdh");
中。替换为
System.load("c:/Users/ArtUrlWWW/Documents/NetBeansProjects/mavenproject1/sdh.dll");
一切正常。
正如您已经指出的答案,我将添加函数
System.loadLibrary("sdh");
寻找文件 "libsdh.so",这就是它不起作用的原因。