■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2009年10月04日

    Java総合講座 - 初心者から達人へのパスポート
                  vol.173

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


[このメールマガジンは、画面を最大化して見てください。]


========================================================
◆ 01.SOAPのアプリケーション(Webサービス)
========================================================


以上で、Webサービスを実行するための準備がすべて完了しましたので、クライアントを
用意してテストしてみましょう。



┌───────────────────────────┐
  デプロイしたWebサービスの動作確認
└───────────────────────────┘

では、Eclipseを起動して、JStudySoapClientプロジェクト内のjp.co.flsi.lecture.webservice.hotel
パッケージにHotelClientForLinuxというクラスを作成し、下記の内容に編集しましょう。

--------------------------------------------------------
package jp.co.flsi.lecture.webservice.hotel;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;

public class HotelClientForLinux {
   public static void main(String[] args) throws RemoteException, ServiceException {
      HotelService locator = new HotelServiceLocator();

      Hotel hotel = null;
      String url = "http://192.168.0.5:8080/axis/services/Hotel";
      try {
         hotel = locator.getHotel(new URL(url));
      } catch (MalformedURLException e) {
         e.printStackTrace();
      }
      StayInfoInput stayInfo = new StayInfoInput();
      stayInfo.setStartDate("20091130");
      stayInfo.setNumOfLodgers(2);
      stayInfo.setNumOfNights(3);
      stayInfo.setMinRatePerNight(0);
      stayInfo.setMaxRatePerNight(50000);
      RoomInfo[] roomInfos = hotel.findRooms(stayInfo);
      if (roomInfos == null) {
         System.out.println("Result is null.");
         return;
      }
      for (RoomInfo roomInfo : roomInfos) {
         System.out.println("==============================================");
         System.out.println("Room number : " + roomInfo.getRoomNum());
         System.out.println("Room capacity : " + roomInfo.getCapacity());
         System.out.println("Rate per night : " + roomInfo.getRatePerNight());
         System.out.println("Room type : " + roomInfo.getRoomType());
         System.out.println("Web browsable : " + roomInfo.isWebBrowsable());
      }
      System.out.println("==============================================");
   }

}
--------------------------------------------------------

(もうお気づきかと思いますが、これは以前のHotelClientのソースを利用しています。)

ただし、192.168.0.5の部分はAxisの(Tomcatの)IPアドレスですから、皆さんの環境の
LinuxのPCのIPアドレスに書き換える必要があります。


編集が終わりましたら、このクラスをEclipseで実行してみて下さい。(その前にLinux
のPCでTomcatやMySQLサーバーが起動されていることが前提になります。)


あらまあ、エラーになってしまいますね。NullPointerExceptionが返って来ます。
Eclipse側だけで見ていてもよくわかりませんので、LinuxのPCのTomcatのログを見て
みましょう。

view /var/log/tomcat5/debugout.log

(ここで、viewコマンドはviのread only版です。)

と入力して下さい。
ログの中を見てみると、

java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory

といったClassNotFoundExceptionが出ていますね。つまり「org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory
クラスが見つかりまへん。」と文句を言われているわけです。
これは通常、必要なJARファイルやクラス・ファイルがクラスパスに無い場合に発生
しますから、何かJARファイルなどが不足している可能性があります。

そこで気がつくことは、Windows環境のときはTomcat 6を使っていたのに対し、今の
Linux環境ではTomcat 5.5にバージョンを下げていることです。(本来はバージョンを
合わせるのが鉄則だが、今回は手抜きをした。)

┌補足─────────────────────────┐
通常、技術書などを執筆する際には、十分な準備と試行(検証)
を行ってから書いていくものです。
しかし、当メールマガジンでは、準備無しでいきなり試行(検証)
しながら執筆し、必要に応じて手抜きを行っています。
この執筆スタイルは、ときどき手違いを起したり、問題を発生
する原因になりますが、かえって問題発生を擬似体験してもら
い、問題発生時の対処法を学んでもらうために有効な方法であ
ると考えているので、あえてこのスタイルを維持しています。
└───────────────────────────┘

つまり、これら2つのバージョンの間での、含まれているJARファイルやクラス・ファイル
の構成の違いに起因する可能性が考えられますので、それに着目してみましょう。

すると、調べてみるとWindowsのPCの

C:\Tomcat6.0\lib

の中の

tomcat-dbcp.jar

というJARファイルの中に該当するクラスがあることがわかります(jar -tvfコマンド
などで調べる)。
したがって、このJARファイルをLinuxのPCの

/usr/share/tomcat5/common/lib

の配下にコピーしてやれば解決します。(ただし、これは単なる応急処置に過ぎません。
本来なら、開発環境とテスト環境、本番環境を合わせるべきであって、Tomcatのバージョン
をすべて統一するべきなのですが、今回は手抜きをしているので応急処置で済ませておき
ます。
ソフトウエア技術者は、実際にこういった応急措置のテクニックも必要になることがあり
ます。)

┌補足─────────────────────────┐
ちなみに、
http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html

http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html
を比較すると、Tomcat6.0では
Jakarta-Commons DBCP(注:DBCP=Database Connection Pool)
Jakarta-Commons Collections
Jakarta-Commons Pool
の3つのコンポーネントがtomcat-dbcp.jarという単一のJARファ
イルの中にまとめられており、同じものがTomcat5.5では
naming-factory-dbcp.jarという単一のJARファイルの中にまとめ
られていることがわかります。つまり、naming-factory-dbcp.jar
というJARファイルがあれば問題ないはずなのですが、現在のCentOS
の/usr/share/tomcat5/common/libの中を見てもこのようなJAR
ファイルは見つかりません。
実は、このnaming-factory-dbcp.jarが見つからないのは、
http://bugs.centos.org/view.php?id=3727
を見ると分かるように、CentOSのバグなのです。
つまり、実はTomcatのバージョンの問題というよりもCentOSの
問題なのです。
今回は、このバグに対処する方法としてnaming-factory-dbcp.jar
の代わりにtomcat-dbcp.jarをコピーしますが、ファイル名は
違っても中身は同じものです。
└───────────────────────────┘

というわけで、例によってFFFTPを使って、上記のtomcat-dbcp.jarというJARファイル
を/usr/share/tomcat5/common/libディレクトリーにコピーして下さい。

そうして、Tomcatを再起動してから、再度HotelClientForLinuxを実行してテストして
みて下さい。今度はうまくいきますね。
HotelClientForLinuxを何度か実行してみて、2回目以降の実行は速くなることも
実感しておいて下さい。



(次回に続く)


では、今日はここまでにします。



[Windowsは米国Microsoft Corporationの、米国およびその他の国における登録商標です。]

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      http://www.flsi.co.jp/Java_text/
★このメールマガジンは
     「まぐまぐ(http://www.mag2.com)」
 を利用して発行しています。
★バックナンバーは
      http://www.flsi.co.jp/Java_text/
 にあります。
★このメールマガジンの登録/解除は下記Webページでできます。
      http://www.mag2.com/m/0000193915.html
★このメールマガジンへの質問は下記Webページにて受け付けて
 います。わからない所がありましたら、どしどしと質問をお寄
 せください。
      http://www.flsi.co.jp/Java_text/
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Copyright (C) 2009 Future Lifestyle Inc. 不許無断複製