2010-11-25 15 views
1

問題が発生しています。私はVC++からJavaクラスを呼び出しています。 IDからJavaプログラムを実行するとうまく動作しますが、Tomcatにデプロイすると例外が発生し、デバッグを開始したときにclsにnullが返されることがわかりました。 FindClassでabosulteパスを指定してtomcatから呼び出すこともできます。このクラスもjarファイルにあります。JNIのtomcatからクラスを呼び出す際の問題

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(); 

return 0;

+0

コードをコピーして例外をください。 –

+0

私はコードを貼り付けました。例外は「アクセス違反コード」であり、デバッグしたときにクラスがTomcatで見つからないため、クラスはnullを返します。 –

答えて

3

Tomcatはアプリケーションごとに異なるクラスローダーを使用するため、アプリケーションを分離しておくことができます。つまり、Consumerクラス(Personとして)と同じクラス名Consumer(Threadとして)を提供する他のWebアプリケーションを提供するWebアプリケーションがあれば、両方のアプリケーションでコンフリクトと問題を引き起こす可能性があります?)。そのtomcatに答えるには、それぞれのアプリケーションのClassLoaderを、独自の隔離されたjarとクラスで作成します。下の図でわかるように、これはTomcat ClassLoadersのヒエラルキーです。問題は、JNI呼び出しが、呼び出すクラスの情報を持たないSystem ClassLoader(デフォルト)を取得していることです。

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

これを解決するには、アプリケーションクラスローダーを見つける必要があります。これは、アプリケーションで定義したクラスの中でgetClass().getClassLoader()を呼び出すことで簡単に行うことができます。これにより、そのクラスをロードしたClassLoaderが取得されます。このクラスは、WebアプリケーションClassLoaderです。その後、loadClass("foo.bar.ClassThatIWant"メソッドを呼び出し、目的のクラスを取得します。 Javaではすべてがこのようになります。

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

を使用すると、次の操作を行いJNIでトリックを行うのですか、あなたはwebCLというパラメータとして、あなたのWebアプリケーションのクラスローダに合格していると仮定します。

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); 
関連する問題