我的FindClass调用返回null时遇到问题:

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


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

IgZorroBridgePath这是我的类,具有完全合格的程序包名称,即。 com / igz / Zorro。
您还可以看到,我正在此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();
}

最佳答案

我使用的是spring boot maven插件,它重新调整了软件包的结构。我改用了shade插件,它不会移动软件包。这使FindClass可以找到我的Java类。

10-06 10:53