- PR -

JNI使用Servletのデプロイ

1
投稿者投稿内容
くりお
常連さん
会議室デビュー日: 2004/01/30
投稿数: 34
投稿日時: 2004-04-07 02:32
JNIを使用したライブラリをEARファイルのAPP-INF/LIBに格納して
デプロイをしていますが、以下の現象が出てうまくいきません。

・static{}内でSystem.loadlibrary()にてUnsatisfiedLinkedErrorが発生する。
  → APServer(WebLogicServer)を再起動するとSystem.loadlibrary()がError無しに実行される。

JNIを使用したライブラリを再起動無しに反映することは出来ないのでしょうか?

a-san
常連さん
会議室デビュー日: 2004/03/15
投稿数: 30
投稿日時: 2004-04-07 13:06
試したことがないのでわかりませんが、
Javaのソースを見る限り行けるかもしれません。
(まず、System.loadLibrary()が、リロードされるクラスの中で呼んでないとダメです。)
System.loadLibrary()もClassLoaderを使って読み込んでいるので、
リロードしたときには、クラスローダーが以前とは変わっているので、
再読み込みされそうな感じです。
エラーが起こる原因はたくさんあるので、
そちらで、Javaのソースとコールスタックを見比べて、
もう少しエラーの発生個所を特定してはどうでしょう。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2004-04-07 15:34
ネイティブライブラリを呼び出すことができるのは一つのJVM中一つのクラスローダだけです。
APP-INF 以下に配置したクラスはアプリケーションを再デプロイするとクラスローダが刷新されるのでエラーが発生します。
なので当該クラスをシステムクラスローダで読み込ませるように設定すれば Ok です。
つまり startWebLogic.sh や startManagedWebLogic.sh でクラスパスに通します。ただしライブラリやそれを使うクラスを動的に更新することはできません。これは JVM の仕様に起因するものです。
くりお
常連さん
会議室デビュー日: 2004/01/30
投稿数: 34
投稿日時: 2004-04-08 23:49
ご回答ありがとうございます。

ご説明不足で申し訳ございませんが、
現状を以下に示します。

1)JNI呼出クラスをシステムクラスパスに設定
   呼出→OK
   入替→再起動要

2)JNI呼出クラスをEARのAPP-INF/libに格納
   呼出→OK
   入替→?(デプロイできるが、呼出時じUnsatisfiedLinkedError)

となってしまいます。

やりたいことはJNI呼出クラスをAPP-INF/LIBに格納し、
それを再起動なしに置換したいということです。
こちらは可能なのでしょうか?
かっぱ
会議室デビュー日: 2004/04/09
投稿数: 4
投稿日時: 2004-04-09 00:30
利用しているのはSunのJVMでしょうか、BEAのJRockItでしょうか。
JNI関連で(具体的にどんな問題なのかはちょっと忘れたのですが)、JRockItではNGで、SunのJVMならOKということがありました。
具体的な話でなくて申し訳ないです...
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2004-04-09 01:26
繰り返しになりますが、これは JVM の仕様に起因します。アプリケーションを再ロードするとクラスローダが刷新されます。JNI のライブラリは1つのクラスローダからしか呼び出せませんので、動的な更新を行うことはできません。ドキュメントにも太字で記述されているくらいなので確認しましょう。
・[バージョン 1.2 の JavaTM 2 SDK で導入された JNI の拡張機能]
-[ライブラリおよびバージョン管理 ]
http://java.sun.com/j2se/1.4/ja/docs/ja/guide/jni/jni-12.html#libmanage
> 同じ JNI ネイティブライブラリを、2 つ以上のクラスローダにロードすることはできま
>せん。 ロードしようとすると、UnsatisfiedLinkError が発生します。 たとえば
>、System.loadLibrary を使用して 2 つのクラスローダにネイティブライブラリをロード
>しようとすると、UnsatisfiedLinkError が発生します。

JRockit も同じ仕様に基づいた JVM ですので挙動に変わりはありません。Intelプラットフォームでは抜群のパフォーマンスを発揮するのでオススメです。
サポートを一元化できるので安心して運用できるというメリットもあります。
くりお
常連さん
会議室デビュー日: 2004/01/30
投稿数: 34
投稿日時: 2004-04-12 01:13
ご回答ありがとうございます。
申し訳ございませんが、

> アプリケーションを再ロードするとクラスローダが刷新されます。

つまりはデプロイするたびにクラスローダが入れ替わると言うことでしょうか?
これはJ2EEの仕様ですか?
自分でいろいろ探してみましたが、デプロイするごとにクラスローダが刷新されると言う記述が見つからなかったので、申し訳ありませんが、ご教授願えませんか?

山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2004-04-12 10:27
>つまりはデプロイするたびにクラスローダが入れ替わると言うことでしょうか?
>これはJ2EEの仕様ですか?
これはJ2EE の仕様というよりは JVM の仕様に起因するものだと思います。一つのクラスローダで、同じクラスを再ロードすることはできないからです。JVM はクラスを読み込むとメモリに展開してしまい、もう一度そのクラスについてクラスローダに問い合わせることはないからです。
クラスを動的に再ロードできる機構をもったアプリケーションはみんなクラスローダを破棄->new することで実現しているはずです。

補足:
WebLogic のマニュアルにも記述がありましたね
・[WebLogic Server J2EE アプリケーション クラスローディング]-[実行中プログラムのクラス変更]
http://edocs.beasys.co.jp/e-docs/wls/docs81/programming/classloading.html#1073487
---
Java クラスローダには、クラスをアンデプロイしたり、アンロードしたりする標準メカニズムはありません。また、新しいバージョンのクラスをロードすることもできません。実行中の仮想マシンでクラスを更新するには、変更されるクラスをロードしたクラスローダを、新しいクラスローダに置き換える必要があります。クラスローダが置き換えられると、そのクラスローダ (または、そのクラスローダの子に当たるクラスローダ) からロードされたすべてのクラスを、再ロードする必要があります。また、これらのクラスのインスタンスはすべて、再インスタンス化する必要があります。
---

[ メッセージ編集済み 編集者: インギ 編集日時 2004-04-12 10:39 ]
1

スキルアップ/キャリアアップ(JOB@IT)