Проблема в вызове класса из Tomcat в JNI - PullRequest
1 голос
/ 25 ноября 2010

У меня проблема. я вызываю Java-класс из VC ++. когда я запускаю java-программу из ID, она работает нормально, но когда я ее развертываю на tomcat, это дает мне исключение, и когда я начал отлаживать ее, я обнаружил, что она возвращает ноль в cls. Как указать абсолютный путь в FindClass, чтобы его также можно было вызывать из tomcat, и этот класс также находится в jar-файле.

JNIEnv * envx = NULL;

JavaVM * vm = NULL;

env1-> GetJavaVM (& VM);

int status = vm-> AttachCurrentThread ((void **) & envx, NULL);

jclass cls = envx-> FindClass ("/ org / software / initmethod / GetInitValue");

jmethodID mid = envx-> GetStaticMethodID (cls, "onRegStateChanged", "(II) I");

if(mid==NULL)

{

    return 0;

}

printf("In C\n");

envx->CallStaticIntMethod(cls,mid,s1,s2);

vm->DetachCurrentThread();

возврат 0;

1 Ответ

3 голосов
/ 26 ноября 2010

Tomcat использует разные загрузчики классов для каждого приложения, поэтому он может изолировать их.То есть, если у вас есть веб-приложение, которое предоставляет класс Consumer (как Person), и другое веб-приложение, которое предоставляет одно и то же имя класса Consumer (как поток), оно может вызвать конфликт и проблему для обоих приложений (которые Consumer должен загрузить Tomcat).?).Чтобы ответить на этот вопрос, создайте ClassLoader для каждого приложения со своими изолированными банками и классами.Как мы можем видеть на диаграмме ниже, это иерархия загрузчиков классов Tomcat.Проблема в том, что ваш JNI-вызов получает System ClassLoader (по умолчанию), в котором нет информации о классе, который вы пытаетесь вызвать.

      Bootstrap
          |
       System
          |
       Common
      /      \
 Catalina   Shared
             /   \
        Webapp1  Webapp2 ... 

Чтобы решить эту проблему, вам нужно найти загрузчик классов приложения.,Вы можете легко сделать это, вызвав getClass().getClassLoader() в некотором классе, который вы определили в своем приложении.Это получит ClassLoader, который загрузил этот класс, который, как мы знаем, является вашим ClassLoader веб-приложения.После этого вы вызываете метод loadClass("foo.bar.ClassThatIWant") и получаете нужный класс.В Java все выглядело бы так:

ClassLoader cl = AWebClass.class.getClassLoader();
Class myClass = cl.loadClass("foo.bar.ClassThatIWant");

Сделайте трюк в JNI, сделав следующее, предположим, что вы передали загрузчик классов веб-приложений в качестве параметра с именем webCL.

jclass classLoaderClass = env->GetObjectClass(webCL);
jmethodID loadClassMethod = env->GetMethodID(classLoaderClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");

const char *className = "foo.bar.ClassThatIWant"; // This needs dots because it's the arg for Java
jstring javaClassName = env->NewStringUTF(desiredClass);

jclass desiredClass = env->CallObjectMethod(webCL, loadClassMethod, javaClassName);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...