- PR -

AXISのサービスメソッド内ではRMIは使えない?

投稿者投稿内容
おちゃ
常連さん
会議室デビュー日: 2005/01/07
投稿数: 25
投稿日時: 2005-01-21 20:16
現在使っているプログラムで、AXISのサービスメソッドからRMIで別のサーバのメソッドが呼ぶものを作ったのですが、動作しません。

Exceptionは以下のものが出力されています。

AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.lang.reflect.InvocationTargetException
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace: AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.lang.reflect.InvocationTargetException
faultActor:
faultNode:
faultDetail:

java.lang.reflect.InvocationTargetException
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:260)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:169)
at org.apache.axis.encoding.DeserializationContextImpl.endElement(DeserializationContextImpl.java:1015)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.content(Unknown Source)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.content(Unknown Source)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
at org.apache.crimson.parser.Parser2.parse(Unknown Source)
at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContextImpl.parse(DeserializationContextImpl.java:242)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:538)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:376)
at org.apache.axis.client.Call.invokeEngine(Call.java:2583)
at org.apache.axis.client.Call.invoke(Call.java:2553)
at org.apache.axis.client.Call.invoke(Call.java:2248)
at org.apache.axis.client.Call.invoke(Call.java:2171)
at org.apache.axis.client.Call.invoke(Call.java:1691)
at DBClient.main(DBClient.java:33)


java.lang.reflect.InvocationTargetException
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:260)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:169)
at org.apache.axis.encoding.DeserializationContextImpl.endElement(DeserializationContextImpl.java:1015)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.content(Unknown Source)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.content(Unknown Source)
at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
at org.apache.crimson.parser.Parser2.parse(Unknown Source)
at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContextImpl.parse(DeserializationContextImpl.java:242)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:538)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:376)
at org.apache.axis.client.Call.invokeEngine(Call.java:2583)
at org.apache.axis.client.Call.invoke(Call.java:2553)
at org.apache.axis.client.Call.invoke(Call.java:2248)
at org.apache.axis.client.Call.invoke(Call.java:2171)
at org.apache.axis.client.Call.invoke(Call.java:1691)
at DBClient.main(DBClient.java:33)

--クライアント側のソース
import java.util.Date;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;

public class DBClient
{
public static void main(String[] args)
{
try {

String endpointURL = "http://172.16.20.21:8080/axis/services/DataService";
String sql = "SELECT 顧客コード,氏名 FROM 顧客マスタ";

Date date1 = new Date();
long timer1;
timer1 = date1.getTime();

Service service = new Service();
Call call = (Call) service.createCall();

call.setTargetEndpointAddress( new java.net.URL(endpointURL) );
call.setOperationName( new QName("DataService", "getCustomer") );
call.addParameter( "sql", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType( org.apache.axis.encoding.XMLType.XSD_STRING );

String ret = (String) call.invoke( new Object[] { sql } );


Date date2 = new Date();
long timer2;
timer2 = date2.getTime();

System.out.println("Timer = " + (timer2 - timer1));
System.out.println("XML:\n" + ret);
} catch (Exception e) {
e.printStackTrace();
}
}
}


--AXIS側のサービスメソッド
package jp.ne.netsolutions.www.axis;

import jp.ne.db.RemoteInterface;

/*
* AXIS Server のインターフェイス
*/
public class DataService {

/**
* クエリーの結果をXML形式で取得する
* @param sql SQLクエリー
* @return XML形式のクエリーの結果
*/
public String getCustomer(String sql) {

String result = null;
RemoteInterface obj = null;
String name = "rmi://123.45.67.89/RemoteInterface";


try {
// RMIの呼び出しを行っている
obj = (RemoteInterface)java.rmi.Naming.lookup(name);
result = obj.getCustomer( sql);
} catch(Exception e) {
e.printStackTrace();
}
return result;
}
}


Webにあがっている文献の中に以下のような文がありました。
http://ws.apache.org/axis/java/install.html
引用:

SOAP is intended to link disparate systems. It is not a mechanism to tightly bind Java programs written by the same team together. It can bind Java programs together, but not as tightly as RMI or Corba. If you try sending many Java objects that RMI would happily serialize, you will be disappointed at how badly Axis fails. This is by design: if Axis copied RMI and serialized Java objects to byte streams, you would be stuck to a particular version of Java everywhere.



最初私は、この文を「SOAPはRMIやCORBAのようにどんなオブジェクトもシリアライズできるわけではないよ」と読みましたが「AXIS環境下ではRMIやCORBAは使えない」と読むこともできるような気がしました。
AXIS環境下ではRMIやCORBAは使えないのでしょうか?


[ メッセージ編集済み 編集者: おちゃ 編集日時 2005-01-21 20:19 ]
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2005-01-21 20:31
おそらくRMI云々とはまったく関係ないと思うんですが、そもそもWebサービス実装クラスの
メソッド(DataService#getCustomer)は呼び出されていますか?

それにしても、WebサービスでSQLを渡してそれをさらにRMIでリモートオブジェクトに渡すって
設計としてかなり問題ありそうに思うのですが。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2005-01-21 21:10
使えますよ。実際使っていました。ただ、デバッグが大変ですし、別の方法で解決したりするのでお勧めはしません。

私が作ったやつは、

<物理的なシステム> --- <Remote Object> --- <GUIのRMIクライアント>

なシステムを

<物理的なシステム> --- <Remote Object> --- <AXIS用のブリッジRMIクライアント> --- <GUI SOAPクライアント>

に変えたものです。ただ、実験用に作ったものですので実際には使用することは今のところありません。ちょっと遅い感じはしますが動きますよ。

引用:

それにしても、WebサービスでSQLを渡してそれをさらにRMIでリモートオブジェクトに渡すって設計としてかなり問題ありそうに思うのですが。


同感ですが、既存のJava RMIシステムをWebサービスでラップすれば、クライアントに他の言語が使えるという利点があります(でもそれだったら最初からCORBAとか使えばいいのに・・・とも思いますが) やっておいて「同感」というのもなんでけど
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2005-01-21 21:27
引用:

同感ですが、既存のJava RMIシステムをWebサービスでラップすれば、クライアントに他の言語が使えるという利点があります(でもそれだったら最初からCORBAとか使えばいいのに・・・とも思いますが) やっておいて「同感」というのもなんでけど


そういう話ではなくて、「SQL」を渡しているのを問題にしているのです。
おちゃ
常連さん
会議室デビュー日: 2005/01/07
投稿数: 25
投稿日時: 2005-01-25 10:40
ukさん、ありがとうございます。

Webサービス実装クラスのメソッド(DataService#getCustomer)は、呼ばれていることが確認されています。
DataService#getCustomerの
obj = (RemoteInterface)java.rmi.Naming.lookup(name);
で、停止しているようです。

H2さんありがとうございます。
使用できますか!
うーんじゃぁなにが悪いんだろう…

実は最終的なクライアントは、FlashとPHPになるので、このような仕様になっています。
WebServiceでSQLを渡していますが、これは完全に実験的なもので、実装ではAXISのサービスメソッド内でSQLを生成します。

今後とも、なぜこのコードが動かないのか、ご指南お願いいたします。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2005-01-25 12:10
引用:

おちゃさんの書き込み (2005-01-25 10:40) より:
DataService#getCustomerの
obj = (RemoteInterface)java.rmi.Naming.lookup(name);
で、停止しているようです。


「停止している」というのは、ハングアップしているということですか? それとも例外が
発生しているということですか? 例外が発生しているのであれば、どんな例外が発生して
いるのかを書いてみてください。
おちゃ
常連さん
会議室デビュー日: 2005/01/07
投稿数: 25
投稿日時: 2005-01-25 17:22
ukさん、ありがとうございます。

Exceptionが発生しています。
出力は、最初の書き込みにあった通りです。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2005-01-25 18:51
InvocationTargetExceptionは要するに実装クラスを呼び出したら例外が発生した、という
ことしか示していませんので、これだけでは何が起こっているのかわかりません。

引用:

Webサービス実装クラスのメソッド(DataService#getCustomer)は、呼ばれていることが確認されています。
DataService#getCustomerの
obj = (RemoteInterface)java.rmi.Naming.lookup(name);
で、停止しているようです。


これはどのように確認したのでしょうか。もしlookupで例外が発生しているのであれば、
サーバ側にスタックトレースが出力されていると思いますが。

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