2017-11-21 7 views
0

Windows用のJava IDEを学習プロジェクトとして開発しています。JNIを使​​用して変更されたクラスファイルをJVMにロードする

JNIを使​​用してJVMを呼び出し、javacを使用してコードをコンパイルしています。

JVMが正常に起動し、Javaコードが初めてコンパイルされたときにJVMがそれらをクラスパスから取り出し、正しく実行します。

しかし、私はJavaファイルを編集し、コンパイルして(スクリプトを使ってコンパイルして)コードを実行した後も、最初の実行時にコンパイルされたクラスファイルをロードします。変更を適用するには、プロセス全体を停止し、JVMを再起動する必要があります。

EclipseやIntelliJなどのIDEでこれが処理される方法があるはずです。しかし、私はどのように見つけることができませんでした。誰かが私を助けてくれたら本当に感謝しています。

私がクラスファイルを見つけてロードするために使用したコードは以下のとおりです。

bool load(const char* classFile) 
{ 
    JNIEnv* env; 
    bool isAttached = Interpreter::getEnv(&env); 
    auto javacls = env->FindClass(classFile); 
    if (javacls == nullptr) 
    { 
     getLogger().error("ERR: Loading class file %s failed", classFile); 
     env->ExceptionDescribe(); 
     return false; 
    } 
    auto classInstance = getObject(javacls); 

    if (classInstance == nullptr) 
    { 
     getLogger().error("ERR: Invalid Object"); 
     return false; 
    } 

    return true; 
} 
+0

オンザフライでのコードの変更は、ネイティブコード[JVMTI](https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html)の場合は、Instrumentation APIを介してのみ機能します。 #RetransformClasses.classes);それはデバッガが使用するものです。 – Holger

+0

@Holgerありがとう。私はapiに目を通します。 –

答えて

0

私がこれに使用した解決策は、JVMを呼び出すサブプロセスを作成してから、実行する必要があるすべての処理を実行して終了することでした。このようにしてサブプロセスが呼び出されるたびに、新しいJVMが作成され、毎回変更されたクラスファイルがロードされます。

0

あなたは別のClassLoaderの下でテスト対象のコードを実行し、多分各実行のために、それぞれのコンパイル後に新しいものを使用する必要があります。

あなたはJNIは必要ありません。

+0

はい私はこれを純粋にJavaを使って書くことができることを知っています。しかし、私はJNIを使​​ってこのことを学ぶ必要があります。また、私はEclipseがJNIを使​​ってJVMを呼び出すのを知っていますか? –

+0

JNI経由で新しい 'ClassLoader'を作成して呼び出すことができない限り、JNI経由では*できません。それは無意味です。 JNIが必要な他のものを探す。 EclipseはすでにJVMで実行されているため、本質的には 'java.lang.Process'を介して新しいJVM *プロセス*を起動するか、上記で推奨したように実行します。 Javaは、1つのプロセス内で複数のJVMをサポートすることはありません。 – EJP

+0

JNIを使​​用してClassLoaderでloadClassメソッドを呼び出すと、最新のクラスファイルがロードされますか、すでにロードされているクラスファイルがロードされますか?新しいクラスファイルを読み込むことができれば、それは私の質問を解決するだろうから。 –

関連する問題