- PR -

AXISからJNIメソッドの呼び出しに失敗する

投稿者投稿内容
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-09-02 08:36
unibon です。こんにちわ。
#Web サービスは使ったことはないですが、JNI は使ったことがあります。

引用:

くさかさんの書き込み (2003-09-01 13:10) より:
1.Stub.dll をどこに配置すればよいのか
2.Stub.dll は実行時の「java.library.path」によって検索されるのか、実行時の「java.class.path」によって検索されるのか、それとも別の方法によって検索されるのか
3.実行時の「java.library.path」、「java.class.path」はどこで再指定すればよいのか



DLL は PATH が通っていればどこでも良いと思います。
なお、DLL は、それと依存関係にある DLL にも PATH が通っている必要がありますが、
その点は大丈夫でしょうか。
また、PATH や CLASSPATH は、
その Web サービスが動いているコンテキストのものが使われますので、
その点は注意する必要があります。
とりあえずは(仮にですが確実なものとして)、
DLL は C:\WINDOWS\SYSTEM32 のフォルダに入れておけば良いはずですし、
クラスファイルは jre/lib/ext などのフォルダに入れておけば良いと思います。
#ちなみに java.library.path と java.class.path を意識して使ったことはないです。

なお、可能性はあまり高くないのですが、
DLL の中でメモリ(とくにスタック)を壊しているということも考えられます。
JNI のサンプルプログラムのような簡単なもので試されてはどうでしょうか。
くさか
会議室デビュー日: 2003/08/27
投稿数: 7
投稿日時: 2003-09-02 10:29
Kan さんご返事ありがとうございます。

Eclipse2.1 + Lomboz2.1で試してみました。Axis のサービスリクエスタについてはプロジェクトを構築できるとドキュメントにかかれていましたが、サービスプロバイダについては、記述を探せませんでした。

Eclipse の新規ウィザードの「Lomboz J2EE Wizards」には次のWizardが含まれていました。
・Lomboz SOAP Client wizard
・Lomboz J2EE Project
・Lomboz J2EE Module
・Lomboz EJB Creation Wizard
・Lomboz JSP Wizard
・Lomboz HTML Wizard
・Lomboz Servlet Wizard
・Lomboz EJB Test Client Wizard
・Lomboz EJB Method Wizard

この中で利用できそうなものは「Lomboz Servlet Wizard」だと思ったのですが、「スーパークラス」の項目が「javax.servlet.http.HttpServlet」固定のようで、Axis1.1 に付属する WSDL2Java で生成したクラスを組み込む方法がわかりませんでした。
Axis のサービスプロバイダを無理やり Lomboz のプロジェクトとして構築し、デバッグする方法が探せずにいます。

調べてみたところ Borland JBuilder 9 Enterprise は Axis1.x、Tomcat4.xに対応しているとのことですが、前稿のような開発サイクルを実現しているのでしょうか。しかし50万円は痛いです。
くさか
会議室デビュー日: 2003/08/27
投稿数: 7
投稿日時: 2003-09-02 10:31
unibon さんご返事ありがとうございます。

呼び出しているメソッドは下記のようにいたって簡単なものです
Stub.cpp
----------------------------------------------------------------
#include <windows.h>
#include <string.h>
#include "jp_co_momoalliance_www_ws_demo_Stub.h"
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jbyteArray JNICALL
Java_jp_co_momoalliance_www_ws_demo_Stub_stubJni(JNIEnv * env, jobject obj)
{
jsize n;
jbyteArray jbData;
jbyte * msg = (jbyte *)"XX0123456789abcdefXX:C++JNI";
n = strlen((const char *)msg);

jbData = env->NewByteArray(n);
env->SetByteArrayRegion(jbData, 0, n, msg);
return jbData;
}
#ifdef __cplusplus
}
#endif
----------------------------------------------------------------
このソースを Borland C++ Compiler 5.5 で下記のオプションをつけてコンパイルしています。

bcc32 -IC:\j2sdk1.4.1_03\include -IC:\j2sdk1.4.1_03\include\win32 -tWD Stub.cpp

最初の投稿にあるクラスを生成し、コンパイルされた Stub.dll にある stubJni を呼び出すテストプログラムを作成し、./jp/co/momoalliance/www/ws/demo に Stab.class と Stab.dll を配置してコマンドラインから実行すると、エラーもなく正しく値を返しているようです。
コマンドラインから実行したときは、クラスパスは環境変数CLASSPATHの設定が反映されているようです。
unibon さんにご指摘いただいたことは、コマンドラインレベルではすべてOKだと考えています。

Axis では、クラスファイルは %CATALINA_HOME%\webapps\axis\WEB-INF\classes に、*.jarなどのライブラリファイルは % CATALINA_HOME%\webapps\axis\WEB-INF\lib に配置するようです。
最終的には、Stub.dll も含めてサービスプロバイダに必要なクラスファイルをすべて JAR ファイルにして % CATALINA_HOME%\webapps\axis\WEB-INF\lib に配置するようにしなければならないと考えていたのですが、最初の段階でつまずいている状態です。

どなたかAxisのサービスプロバイダからJNIメソッドの呼び出しに成功しておられる方がいらっしゃれば詳しい方法をお聞きしたいと思っているのですが...。


[ メッセージ編集済み 編集者: くさか 編集日時 2003-09-02 13:30 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-09-02 11:17
unibon です。こんにちわ。

引用:

くさかさんの書き込み (2003-08-27 12:33) より:
static {
System.loadLibrary("Stub");
}


少し外しているかもしれませんが、
loadLibrary は成功しているのにその後でメソッドが呼べないのか、
それとも loadLibrary の時点ですでに失敗していることがあるのか、
を切り分けられると良いかもしれません。
#loadLibrary の前後にログ出力を挟み込んでみるなどして確認するなどが考えられます。

あと、疑問なのですが、いろいろ試される際に、
その都度 Java VM を完全に終了してから再起動されているでしょうか。
なにかの要因で、古い DLL がロード済みだとみなされて、
新しい DLL が使われないような事態になっているのかもしれません。
#私だったら OS 丸ごと再起動して試したいところです。

引用:

くさかさんの書き込み (2003-09-02 10:31) より:
どなたかAxisのサービスプロバイダからJNIメソッドの呼び出しに成功しておられる方がいらっしゃれば詳しい方法をお聞きしたいと思っているのですが...。


#私は Axis 等に依存するようなことだとこれ以上は分からないです。
#(独自のセキュリティポリシなどを持ってたりするのでしょうか...)
Paul
ベテラン
会議室デビュー日: 2002/04/30
投稿数: 75
お住まい・勤務地: 東京
投稿日時: 2003-09-22 14:42
中込です。

>どなたかAxisのサービスプロバイダからJNIメソッドの呼び出しに成功しておられる方がいらっしゃれば詳しい方法をお聞きしたいと思っているのですが...。
当方では成功しています。
とりわけ特殊なことをする必要はありません。JNIの基本どおりに行うだけです。
classファイルは該当するクラスローダが参照するCLASSPATH以下に、正しくパッケージ構造をディレクトリ構造対応付けて配置し、dllはPATHの通っているディレクトリ直下に配置してあれば大丈夫です。

ですから、貴殿の環境では、Stab.classを%CATALINA_HOME%\webapps\axis\WEB-INF\classes\jp\co\momoalliance\www\ws\demoに配置し、Stab.dllをhappyaxis.jspで表示されるjava.library.pathのディレクトリ直下に配置すればよいでしょう。

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