web-dev-qa-db-ja.com

.dllはすでに別のクラスローダーにロードされていますか?

レガシーC++コードのデータとメソッドにアクセスするためにJNI呼び出しを行う必要があるTomcat 3.2.1で実行されているWebアプリケーションがあります。サーブレットはWebアプリケーションの起動時にロードされ、そのinitメソッドの一部として、そのWebアプリケーションインスタンスに固有のデータセットがC++データ構造にロードされます。

このJavaコードには以下が含まれます:

static
{
    try {
        System.loadLibrary("JCoreImpl");
        System.out.println("JCoreImpl loaded");
        m_bLibraryLoaded = true;
    } catch (UnsatisfiedLinkError e) {
        m_bLibraryLoaded = false;
        System.out.println("JCoreImpl NOT loaded " + e);
    }
}

Webappが1つしかない場合は問題なく動作します(「webapps/aaa」と呼びましょう)。

C++データ構造で使用されるデータセットを除いてwebapps/aaaと同じ2番目のwebapp( "webapps/bbb")がある場合、webapps/aaaは問題なく起動しますが、webapps/bbbを起動すると次のことを示すエラー:

JCoreImpl NOT loaded Java.lang.UnsatisfiedLinkError: Native Library
E:\WebStation\binDebug\JCoreImpl.dll already loaded in another classloader

各インスタンスにはその特定のWebアプリに固有のデータが含まれている必要があるため、Webアプリケーションごとにネイティブライブラリの個別のインスタンスを用意する必要があります。メールアーカイブを検索し、クラスローダーの階層を説明するクレイグマクラナハンのメールを読みました。しかし、各Webアプリのネイティブライブラリの一意のインスタンスをロードすることに固有のものを見つけることができませんでした。

21
krishnakumar

同じネイティブライブラリを2回ロードすることはできません。

クラスを<Tomcat>/lib/の下のjarファイルに入れます。これは、すべての戦争で共有されます。

15
J-16 SDiZ
9
ctrlspace

私はこの問題を抱えていて解決しました:

問題:

この問題は、アプリケーションサーバーの構成によって、複数のwarまたはearファイルが作成され、その結果、複数のデプロイ済みファイルが作成されることが原因です。これらのデプロイされたファイルは、静的ブロックにロードされたネイティブライブラリへの同時アクセスを試みます。

ソリューション:

  1. アプリケーションサーバーを停止してIDEAを閉じます
  2. タスクマネージャからすべてのJavaプロセスを完了します
  3. アプリサーバーの次のアドレスに移動します:jboss-eap-6.4.0\standalone\configurationそして開くstandalone.xmlファイル
  4. の中に standalone.xmldeploymentsタグをすべて削除します(心配しないでください。アプリケーションサーバーを再実行すると、このタグが挿入されます。
  5. アプリサーバーの次のアドレスに移動します:jboss-eap-6.4.0\standalone\deploymentsと展開されたすべてのファイルとwarファイルを削除します。 (warファイルをバックアップできます)
  6. IntelliJ Ideaを開き、次のように移動します:構成JBOSSの編集->配置タブ
  7. 現在のデプロイメントを削除し、explodedである必要がある新しいデプロイメントを追加します
0
Hosein Aqajani

DLLをロードする前に、一時ディレクトリ内の一時ファイルにDLLをコピーします。完了したらファイルを削除します。このようにして、同じDLLが2回ロードされないようにすることができます。

0
Demi