- PR -

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

投稿者投稿内容
くさか
会議室デビュー日: 2003/08/27
投稿数: 7
投稿日時: 2003-08-27 12:33
Windows2000にTomcat4.1とAxis1.1をインストールしてWebサービスプロバイダのテストをしています。
下記のようなJNIでつくられたメソッドを含むクラスを作成してサービスプロバイダから呼び出そうとしています。
----------------------------------------------------------------
package jp.co.momoalliance.www.ws.demo;
import java.io.*;
public class Stub {
static {
System.loadLibrary("Stub");
}
private native byte[] stabJni() throws IOException;

public byte[] func() throws IOException {
byte[] ba = null;

try {

ba = stabJni();
// ba = stubJava();
} catch(IOException ioe) {
}
return ba;
}

private byte[] stubJava() throws IOException {
byte[] ba = "XX0123456789abcdefXX".getBytes();
if(ba == null) {
throw new IOException();
}
return ba;
}
}
----------------------------------------------------------------
ところがサービスリクエスタからサービスプロバイダ経由で呼び出すと下記の例外が発生します。

java.lang.reflect.InvocationTargetException

現在判っていることは次のようなことです。
1.サービスプロバイダはWSDLよりWSDL2Javaを使って生成したものを使用している。
2.同様の処理をするJavaコンソールアプリケーションからの呼び出しには成功している。
3.SOAP Monitor で確認すると Active のままレスポンスが表示されない。
4.TcpMon で確認すると下記のレスポンスを返しているので、サービスプロバイダ側で例外が発生していると推測している。
----------------------------------------------------------------
HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf-8
Date: Wed, 27 Aug 2003 01:52:58 GMT
Server: Apache Coyote/1.0
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>java.lang.reflect.InvocationTargetException</faultstring>
<detail/>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
----------------------------------------------------------------
4.生成したJNIのDLLの検索パスの問題ではないかと考えC:\WINNT、C:\WINNT\system、C:\WINNT\system32等にこの dll を置いても状況は変わらない。
5.クラス内で、JNIメソッドを呼び出す部分を通常のJavaメソッドに置き換えると例外は発生せず正常にやり取りできる。

サービスプロバイダ側でJNIメソッドを正しく呼び出す方法について、なにか対応策がありましたらご教示ください。よろしくお願いします。
ken
常連さん
会議室デビュー日: 2002/04/29
投稿数: 38
投稿日時: 2003-08-27 12:42
例外や、それを引き起こす部分に関する情報が
java.lang.reflect.InvocationTargetException
これだけだと、少なすぎはしませんでしょうか?

Regards,
I love Borland.
TAKAHASHI, KEN, Tomohiro
くさか
会議室デビュー日: 2003/08/27
投稿数: 7
投稿日時: 2003-08-27 13:33
ご返事ありがとうございます。
サービスプロバイダ側のどこで例外が発生しているのかが今ひとつはっきりとわかりません。
調べてみるとStubクラスのfuncメソッド内で、stubJniメソッドを呼ばずに変わりにコメントアウトしている部分のstubJavaメソッドを呼ぶと例外が発生しないため、この部分で発生しているのはないかと考えています。
具体的にどのように問題を切り分けるとよいかわからないため困っています。よろしければ原因を追求するための方法を教えていただけませんか。
また、実際にサービスプロバイダからJNIメソッドを呼び出されている方はいらっしゃるのでしょうか。
くさか
会議室デビュー日: 2003/08/27
投稿数: 7
投稿日時: 2003-08-28 13:30
サービスプロバイダ側でのデバックの方法がわからなかったので、下記のようにしてサービスリクエスタに例外を投げるようにしてテストしてみました。
----------------------------------------------------------------
public byte[] operation() throws java.rmi.RemoteException, MyFaultException {
byte[] byteArray = null;
Stub stub;

try {
stub = new Stub();
} catch (Throwable e) {
throw new MyFaultException(3, "CREATE ERROR: " + e);
}

try {
byteArray = stub.func();
} catch (Throwable e) {
throw new MyFaultException(3, "FUNC ERROR: " + e);
}
return byteArray;
}
----------------------------------------------------------------
結果、stub = new Stub(); のところで

java.lang.UnsatisfiedLinkError: no Stub in java.library.path

というエラーが出ていることがわかりました。

上記メソッドの実行時の java.library.path を System.getProperty("java.library.path") を使って調べると下記のようになっていました。

java.library.path=
D:\ProgramFiles\Apache Group\Tomcat 4.1\bin;.;C:\WINNT\system32;C:\WINNT;
C:\WINNT\System32\Wbem;C:\j2sdk1.4.1_03\bin

パスの通っている場所 D:\ProgramFiles\Apache Group\Tomcat 4.1\bin に JNI メソッドの Stub.dll を配置してもう一度テストを行うと、stub = new Stub(); のところで

java.lang.NoClassDefFoundError

という違ったエラーが出ていることがわかりました。このエラーはリファレンスによると、
----------------------------------------------------------------
通常のメソッド呼び出し、あるいは new 式を使った新しいインスタンスの生成で、Java 仮想マシンまたは ClassLoader インスタンスがクラス定義をロードしようとしたが、クラス定義が見からない場合にスローされます。

検索されるクラス定義は、現在実行中のクラスをコンパイルする時点では存在していましたが、その後見つからなくなっています。
----------------------------------------------------------------
とかかれていますが、この状況は具体的にはどのようなことをさしているのでしょうか。どのようにすれば解決できるのでしょうか。

何か情報を持っておられる方がいらっしゃいましたら、すみませんがよろしくお願いします。


[ メッセージ編集済み 編集者: くさか 編集日時 2003-08-28 15:53 ]
くさか
会議室デビュー日: 2003/08/27
投稿数: 7
投稿日時: 2003-09-01 13:10
あれからまた少し調べてみました。
サービスプロバイダ側で発生しているエラー「java.lang.NoClassDefFoundError」は実行時に該当するクラス定義を見つけることができなかったために発生しているらしいことがわかりました。

JNIメソッドを含まないクラスを作成して実行した時にはこのようなエラーは発生していなかったので、Stub.class そのものではなく、Stub.dll を見つけれなかったのだろうと推測しています。

このメソッド実行時の「java.class.path」は次のようになっていました。
D:\ProgramFiles\Apache Group\Tomcat 4.1\bin\bootstrap.jar

環境変数のCLASPATHは下記のように設定しています。
CLASSPATH=.;C:\j2sdk1.4.1_03\jre\lib;C:\j2sdk1.4.1_03\lib;C:\j2sdk1.4.1_03\lib\tools.jar;D:\ProgramFiles\Apache Group\Tomcat 4.1\common\lib\servlet.jar;D:\ProgramFiles\Apache Group\axis-1_1\lib\axis.jar;D:\ProgramFiles\Apache Group\axis-1_1\lib\axis-ant.jar;D:\ProgramFiles\Apache Group\axis-1_1\lib\commons-discovery.jar;D:\ProgramFiles\Apache Group\axis-1_1\lib\commons-logging.jar;D:\ProgramFiles\Apache Group\axis-1_1\lib\jaxrpc.jar;D:\ProgramFiles\Apache Group\axis-1_1\lib\log4j-1.2.8.jar;D:\ProgramFiles\Apache Group\axis-1_1\lib\saaj.jar;D:\ProgramFiles\Apache Group\axis-1_1\lib\wsdl4j.jar

環境変数での設定が実行時にそのまま反映されると思っていたのですが、どうも違うみたいです。

Stub.dll を正しく見つけるようにしてテストしたいのですが次のことがわかりません。

1.Stub.dll をどこに配置すればよいのか
2.Stub.dll は実行時の「java.library.path」によって検索されるのか、実行時の「java.class.path」によって検索されるのか、それとも別の方法によって検索されるのか
3.実行時の「java.library.path」、「java.class.path」はどこで再指定すればよいのか

判らないまま、あれこれと調べていますが、根本的におかしいことをしているのかもしれません。なにか情報を持っておられる方がいらっしゃいましたら、すみませんがよろしくお願いします。
ken
常連さん
会議室デビュー日: 2002/04/29
投稿数: 38
投稿日時: 2003-09-01 13:26
そぼくな疑問なのですが、まずは、Apache-Axisを含んだサーブレットコンテナ
(Tomcat等)をデバッグ実行して、ブレークポイント等を置きながら、どの箇所で
どのような原因で問題が発生しているのか確かめるのが先決のように思えますが、
いかがでしょうか?
JBuilder等のIDEをお使いではないのでしょうか?

Best Regards,
I love Borland.
TAKAHASHI, KEN, Tomohiro
くさか
会議室デビュー日: 2003/08/27
投稿数: 7
投稿日時: 2003-09-01 15:24
残念ながらIDEはもっておりません。下記ようなの開発サイクルを行えるIDEを探してみましたが見つけることができていません。

1.WSDL から Axis1.1 に付属する WSDL2Java を使って、サービスプロバイダのスケルトンを生成する。
2.生成したスケルトンを基に、サービスプロバイダのプロジェクトを構築する。
3.Tomcat4.1 + Axis1.1の環境にデプロイしてデバッグを行う。

Eclipse であればすぐに用意できるのですが、Eclipse で Axis のサービスプロバイダのデバッグはできるのでしょうか。市販のIDEであればどのようなものが最適でしょうか。

また、エラーの個所は、stub = new Stub(); の部分での java.lang.NoClassDefFoundError だと思うのですが見当違いでしょうか。

すみませんがよろしくお願いします。
kan
ベテラン
会議室デビュー日: 2002/11/28
投稿数: 55
投稿日時: 2003-09-02 08:04
Eclipseで以下のLombozプラグインを使うのはどうでしょう?
http://www.objectlearn.com/index.jsp
http://www.atmarkit.co.jp/fjava/rensai2/eclipse03/eclipse03.html

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