JXTAのインストール

http://e-words.jp/w/Jxta.html
Sun Microsystems社が2001年4月に概要を発表したフレームワーク技術で、P2P型アプリケーションを容易に開発できる環境

を使ってみたかったので,使ってみました.
といってもP2P for Java / JXTAを参考に,指示通りに使ってみただけなので深みは無い.単純に動かしてみただけ.

ダウンロードとインストール

DownloadとInstallにあるとおりにやってみる.
上記のページにある「実行ファイル」から”all.zip”をダウンロードして,適当な場所に解凍する.
適当な場所に”jxtaディレクトリに作って,all.zipの中身をコピーする.(コマンドプロンプトから指定しやすい場所が便利だと思います.今回は”D:\jxta”に入れている)
(all.zipの中身)
上記のページの指示通りにインストールする.(インストールという言葉を聞いて,.exeを想像するかも知れませんが,使いません)
jxta\shell\shellディレクトリ)

3.jxta\shell\shellディレクトリに移動して、そこに、run1という名前のディレクトリをつくる。
4.作成した、jxta\shell\shell\run1ディレクトリに移動。
5.run1ディレクトリ内に、次のようなバッチファイルrun.batとrmfile.batを作成する。

(rub.bat)
JAVA_HOME」は自分の持っているjdkのパスを指します.「cl」は”D:\jxta\shell\lib”にあるjarを指しています.
(D:\jxta\shell\lib)
run.batを実行するとJXTA-Shellの初期設定画面になります.先のページを参照して設定して,JXTA-Shellを起動してください.
JXTA-Shell)

JXTAシェル・コマンドの作成

JXTA-Shell・コマンドを作成してみる.実行例はこんな感じになる.

サーバ側実行例

                                                                                                                                • -

JXTA>Shell -s
JXTA>receiver
Service advertisement was published
Waiting ......
receive message: Hello World!
Waiting ......
receive message: Hello World!
Waiting ......
receive message: Maruyama Fujio
Waiting ......
receive message: wakhok.ac.jp
Waiting ......

                                                                                                                                • -

クライアント側実行例

                                                                                                                                • -

JXTA>sender
searching for the Maruyama-1 Service advertisement
Message: "Hello World!" sent
JXTA>sender
searching for the Maruyama-1 Service advertisement
Message: "Hello World!" sent
JXTA>send Maruyama Fujio
send: cannot access Maruyama
JXTA>sender Maruyama Fujio
searching for the Maruyama-1 Service advertisement
Message: "Maruyama Fujio " sent
JXTA>sender wakhok.ac.jp
searching for the Maruyama-1 Service advertisement
Message: "wakhok.ac.jp " sent
JXTA>

                                                                                                                                • -

プログラムのソースを示す.
receiver.javaのソース

package net.jxta.impl.shell.bin.receiver; 

import net.jxta.impl.shell.ShellApp;
import net.jxta.discovery.Discovery;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.document.AdvertisementFactory;
import net.jxta.protocol.ServiceAdvertisement;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.pipe.Pipe;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.InputPipe;
import net.jxta.endpoint.Message;
import java.io.InputStream; 

public class receiver extends ShellApp {   

  private Discovery discovery; // 探索サービス
  private Pipe pipes; // パイプ・サービス
  private InputPipe msgPipe; // 入力用パイプ・サービス
  private Message message; // メッセージ
  private PeerGroupID gid; // ピア・グループID 

  public receiver() {
  }

  public int startApp (String[] args) { 
    try { 

 // パイプ・サービス告知を生成して、告知に必要なパラメータを設定する。
    PipeAdvertisement pipeAdv = (PipeAdvertisement) 
    AdvertisementFactory.newAdvertisement("jxta:PipeAdvertisement");
    // パイプ・サービスの名前の設定
    pipeAdv.setName("Pipe Maruyama-1"); 
 // ネット・ピア・グループのIDはユニークであることが保証されているので
 // それを使って、ユニークなパイプIDを生成し、設定する。
    pipeAdv.setPipeID(new PipeID(group.getID())); 


 // サービス告知を生成して、告知に必要なパラメータを設定する。
    ServiceAdvertisement serviceAdv = (ServiceAdvertisement)
    AdvertisementFactory.newAdvertisement
       ("jxta:ServiceAdvertisement");
    // サービスの名前の設定
    serviceAdv.setName("Maruyama-1"); 
    // サービスのプロバイダ名の設定
    serviceAdv.setProvider("wakhok.ac.jp"); 
    // サービスのバージョン設定
    serviceAdv.setVersion("Version 1.0"); 
 // サービス告知の中にパイプ・サービス告知を設定する。
    serviceAdv.setPipe(pipeAdv); 


 // サービス告知ができたので、これをローカル・キャッシュと
 // ネットワーク上に公開する。
    discovery = group.getDiscovery();
    // ローカル・キャッシュへの公開。
    discovery.publish(serviceAdv, Discovery.ADV);
     // ネットワーク上での公開。
    discovery.remotePublish(serviceAdv, Discovery.ADV);

 // ピア・グループから、パイプ・サービスを獲得し、先に作った
 // パイプ・サービス告知を利用して、入力用のパイプを生成する。
    println("Service advertisement was published" ); 
    pipes = group.getPipe();
    msgPipe = pipes.createInputPipe(pipeAdv);

    } catch (Exception ex) {
      ex.printStackTrace();
      System.err.println("receiver: Error publishing the service"); 
    } 

    // パイプからの入力の間、繰り返す。
    while (true) {
       println("Waiting ......");
    try {

    // メッセージがくるのを待つ。
    message = msgPipe.waitForMessage();
    } catch (Exception e) {
      System.err.println("Error listening");
      msgPipe.close(); return 1;
    }


  // メッセージの中身を取り出すためにストリームを作る。
  // そのとき、サーバとクライアントはタグ名を共有しなければ
  //ならない。今回は、"HelloTag"というタグである。
    try {
    // メッセージからタグ部分を取り出す。
    InputStream info = message.pop ("HelloTag"); 
    if (info != null) {
      byte[] msgbuffer = new byte [info.available()];
      int n = info.read (msgbuffer);
      println("receive message: " + new String(msgbuffer));
      info.close();
    } else
      System.err.println("receiver: no tag");
    } catch (Exception e) {
      System.err.println("receiver: error ");
    }

   }
 }

  public void stopApp () {
  } 

}

sender.javaのソース

package net.jxta.impl.shell.bin.sender;
import net.jxta.impl.shell.ShellApp;
import net.jxta.discovery.Discovery;
import net.jxta.peergroup.PeerGroup;
import net.jxta.document.AdvertisementFactory;
import net.jxta.endpoint.Message;
import net.jxta.pipe.Pipe;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.OutputPipe;
import net.jxta.id.ID;
import net.jxta.protocol.ServiceAdvertisement;
import net.jxta.protocol.PipeAdvertisement;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Enumeration; 

  public class sender extends ShellApp {
    private Discovery discovery; // 探索サービス
    private Pipe pipes; // パイプ・サービス
    private OutputPipe msgPipe; // 出力用パイプ
    private Message message; // メッセージ 

    public sender() {
    }
    public int startApp (String[] args) {
      try {
  // Shellコマンドの引数を連結してメッセージ文字列を作成する。
        String strings = "";
        if ((args == null) || (args.length < 1)) {
          strings = "Hello World!";
        } else {
          for( int i=0; i<args.length; i++ )
          strings += args[i] + " ";
        } 

  // サービス告知を見つけ出す探索サービスを、ピア・グループから獲得する。
        discovery = group.getDiscovery(); 

  // ほかのピアのサービス告知を見つけるまでループ。
        println(
           "searching for the Maruyama-1 Service advertisement");
        Enumeration enum = null;
        while (true) { 
          try { 

 // まず、ローカル・キャッシュでサービス告知を探索する。
 // 名前は、"Maruyama-1"。
            enum = discovery.getLocalAdvertisements(
                Discovery.ADV, "Name", "Maruyama-1");

 // ローカルに見つかれば成功。ループを抜ける.
            if ((enum != null) && enum.hasMoreElements()) break; 

 // ローカルに見つからなければ、ネットワーク上でサービス告知を
 // 探索する。リモートの探索は、非同期的に行われるので、
 // どれくらい時間がかかるかは分からない。
 // 適当に休んでいてよい。リモートの探索結果は、
 // ローカル・キャッシュに必ず反映される。
            discovery.getRemoteAdvertisements(
                null, Discovery.ADV, "Name", "Maruyama-1",1);
            try { Thread.sleep(2000); } catch (Exception e){} 
          } catch (Exception e){}
        }

 // 発見されたサービス告知の中から、パイプ・サービスの告知を取り出す。
        ServiceAdvertisement serviceAdv =
            (ServiceAdvertisement) enum.nextElement();
        PipeAdvertisement pipeAdv = serviceAdv.getPipe();

 // ピア・グループから、パイプ・サービスを獲得し、
 // 先に取り出したパイプ・サービスの告知を利用して、
 // ほかのピアに接続している「出力パイプ」と
 // 空のメッセージを生成する。
        pipes = group.getPipe();
        msgPipe = pipes.createOutputPipe(
            pipeAdv, Pipe.NonBlocking, 5000);
        message = pipes.createMessage(); 

 // メッセージ用文字列をストリームに変え、
 // "HelloTag"というタグを付けてメッセージ
 // に押し込んで、パイプに送り出す。
        ByteArrayInputStream info = 
        new ByteArrayInputStream (strings.getBytes());
        message.push ("HelloTag", info);
        msgPipe.send (message);
        println("Message: \"" + strings + "\" sent"); 

      } catch (Exception ex) {
        ex.printStackTrace();
        System.err.println("Error sending message"); 
      }
    return ShellApp.appNoError;
  } 

  public void stopApp () {
  } 

}

D:\jxta\shell\shell\以下にsender.javaとreceiver.javaを置いて,D:\jxta\shell\shell\classというディレクトリを作ります.
このソースをコンパイルするときはコマンドプロンプトから

D:\jxta\shell\shell\run1>javac -classpath ..\..\lib\jxta.jar;..\..\lib\jxtashell.jar -d ..\class ..\sender.java

D:\jxta\shell\shell\run1>javac -classpath ..\..\lib\jxta.jar;..\..\lib\jxtashell.jar -d ..\class ..\receiver.java

とタイプしてコンパイルする.
(こんな感じになってます)
次に上で作った”run.bat”の2行目にclassディレクトリを読み込むように設定する.

編集後,run.batを実行する.
これでJXTA-Shellから「receiver」,「sender」コマンドを実行できる.