JNI FindClass返回NULL - 非常奇怪

时间:2015-11-11 09:14:28

标签: java c++ java-native-interface

我知道,https://stackoverflow.com/上有很多类似的问题,但没有一个问题解决了我的问题。

我有一个没有包的简单Java类:

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打电话给那个班:

// 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,其中包含所需的类: enter image description here

但是我的程序找不到类TestConsoleHandlerenter image description here

请,建议,如何解决这个问题?

非常感谢!

2 个答案:

答案 0 :(得分:0)

问题出在代码System.loadLibrary("sdh");中。用

替换之后
System.load("c:/Users/ArtUrlWWW/Documents/NetBeansProjects/mavenproject1/sdh.dll");

一切正常。

答案 1 :(得分:0)

正如您已经指出的答案,我只是添加了该功能

System.loadLibrary("sdh");

查找文件&#34; libsdh.so&#34;这就是为什么它不起作用。