FindClass返回null

时间:2017-03-09 05:31:59

标签: c++ java-native-interface

我的FindClass调用出现问题,返回null:

JData::JIgZorroBridgeClass = env->FindClass(JData::IgZorroBridgePath);

我发现的大多数答案都指向缺少包名或类加载器问题。

IgZorroBridgePath这是我的班级,拥有完全合格的包名,即。 COM / igz /佐罗。 另外你可以看到我在这个FindClass调用之前正在初始化JVM,所以我想我应该已经在正确的线程上了。

还有什么我可以检查吗?

#include <assert.h>
#include "JNIHandler.hpp"
#include "JReferences.hpp"

const char* JVMClassPathOption =  "-Djava.class.path=Plugin/ig/igplugin-0.1.jar";
const char* IgZorroBridgePath = "com/danlind/igz/ZorroBridge";


void JNIHandler::init()
{
    initializeJVM();
    initializeJavaReferences();
}

void JNIHandler::initializeJVM()
{
    if(isJVMLoaded) return;

    JavaVMInitArgs args;
    JavaVMOption options[1];

    args.version = JData::JNI_VERSION;
    args.nOptions = 1;
    args.options = options;
    options[0].optionString = (char*)JData::JVMClassPathOption;
    args.ignoreUnrecognized = JNI_FALSE;

    jint res = JNI_CreateJavaVM(&jvm, (void **)&env, &args);
    assert(res ==  JNI_OK);
    isJVMLoaded = true;
}

JNIEnv* JNIHandler::getJNIEnvironment(){
    return env;
}

JNIEnv* JNIHandler::getEnvForCurrentThread()
{
    int envStat = jvm->GetEnv((void **)&env, JData::JNI_VERSION);
    if (envStat == JNI_EDETACHED) {
        jint res = jvm->AttachCurrentThread((void**)&env, NULL);
        assert (res == JNI_OK);
    }
    return env;
}


void JNIHandler::initializeJavaReferences()
{
    if(areJavaReferencesInitialized) return;

    initExceptionHandling();
    initBridgeObject();
    registerNatives();

    areJavaReferencesInitialized = true;
}

void JNIHandler::initBridgeObject()
{
    JData::JIgZorroBridgeClass = env->FindClass(JData::IgZorroBridgePath);
    checkJNIExcpetion(env);
    registerClassMethods();
    JData::JIgZorroBridgeObject = env->NewObject(JData::JIgZorroBridgeClass, JData::constructor.methodID);
    checkJNIExcpetion(env);
}

void JNIHandler::initExceptionHandling()
{
    JData::ExceptionClass = env->FindClass(JData::ExcPath);
    JData::excGetName.methodID = env->GetMethodID(JData::ExceptionClass, JData::excGetName.name, JData::excGetName.signature);
}

void JNIHandler::registerNatives()
{
    JData::JZorroClass = env->FindClass(JData::ZorroPath);
    env->RegisterNatives(JData::JZorroClass, JData::nativesTable, JData::nativesTableSize);
    checkJNIExcpetion(env);
}

void JNIHandler::registerClassMethods()
{
    for(auto *desc : JData::igZorroBridgeMethods)
    {
        desc->methodID = env->GetMethodID(JData::JIgZorroBridgeClass, desc->name, desc->signature);
        checkJNIExcpetion(env);
    }
}

void JNIHandler::checkJNIExcpetion(JNIEnv* env)
{
    jthrowable exc = env->ExceptionOccurred();
    if (!exc) return;

    jclass exccls(env->GetObjectClass(exc));
    jstring name = static_cast<jstring>(env->CallObjectMethod(exccls, JData::excGetName.methodID));
    char const* utfName(env->GetStringUTFChars(name, 0));

    JData::excGetMessage.methodID = env->GetMethodID(exccls, JData::excGetMessage.name, JData::excGetMessage.signature);
    jstring message = static_cast<jstring>(env->CallObjectMethod(exc, JData::excGetMessage.methodID));
    char const* utfMessage(env->GetStringUTFChars(message, 0));

    BrokerError(utfName);
    BrokerError(utfMessage);

    env->ReleaseStringUTFChars(message, utfMessage);
    env->ReleaseStringUTFChars(name, utfName);
    env->ExceptionClear();
}

1 个答案:

答案 0 :(得分:1)

我使用的是spring boot maven插件,它重新整理了包结构。我改用了使用阴影插件,它不会移动包裹。这使FindClass能够找到我的java类。