2010-11-25 6 views
1

J'ai un problème. J'appelle une classe Java de VC++. Quand j'exécute un programme java à partir d'ID, ça fonctionne bien mais quand je le déploie sur Tomcat ça me donne une exception et quand j'ai commencé à le déboguer, j'ai trouvé que ça retourne null dans cls. Comment donner un chemin abosulte dans FindClass pour qu'il puisse aussi être appelé depuis tomcat et cette classe réside aussi dans le fichier jar.Problème lors de l'appel de classe de tomcat dans JNI

JNIEnv * envx = NULL;

JavaVM * vm = NULL;

env1-> GetJavaVM (& vm);

int état = 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(); 

return 0;

+0

Copiez le code et l'exception, s'il vous plaît. –

+0

J'ai collé le code. et l'exception est "Access Violation Code" et quand je l'ai débogué, la classe renvoie null car elle ne trouve pas la classe dans tomcat. –

Répondre

3

Tomcat utilise différents chargeurs de classes pour chaque application, ce qui permet de les isoler. Autrement dit, si vous avez une application Web qui fournit une classe Consumer (en tant que personne) et une autre application Web qui fournit le même nom de classe Consumer (en tant que thread), elle peut provoquer des conflits et des problèmes pour les deux applications. ?). Pour répondre à ce tomcat, créez un ClassLoader pour chaque application avec ses propres jars et classes isolés. Comme nous pouvons le voir dans le diagramme ci-dessous, il s'agit de la hiérarchie de Tomcat ClassLoaders. Le problème est que votre appel JNI obtient le System ClassLoader (par défaut) qui n'a pas d'informations de la classe que vous essayez d'invoquer.

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

Pour résoudre cela, vous devez trouver votre classloader application. Vous pouvez le faire facilement en appelant le getClass().getClassLoader() dans une classe que vous avez définie dans votre application. Cela obtiendra le ClassLoader qui a chargé cette classe, dont nous savons qu'il s'agit de votre Web Application ClassLoader. Après cela, vous appelez la méthode loadClass("foo.bar.ClassThatIWant") et obtenez la classe désirée. En Java tout ressemblerait à ceci:

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

Ce qu'il faut faire le tour de JNI vous procédez comme suit, supposons que vous avez passé votre classe Web chargeur d'applications en tant que paramètre appelé 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);