\r\n\r\n

javarmiレジストリのすべてとその使用方法

javarmiはリモートメソッドコールの略で、他のコンピュータ上で動作しているオブジェクトのメソッドを呼び出すためのプロトコルです。javarmiレジストリについて、またその使用方法について説明します。

RMIはRemote Method Invocationの略で、その名の通り、Javaプログラムが他のコンピュータで動作しているオブジェクトのメソッドを呼び出すためのプロトコルである。あるプログラム(サーバーと呼ぶ)からオブジェクトをエクスポートし、別のプログラム(クライアントと呼ぶ)からそのオブジェクトのメソッドを呼び出すためのAPI(Application Programming Interface)を提供し、おそらく別のコンピュータで実行されている。

java-rmi-registry

javarmiレジストリはjavarmiシステムの重要なコンポーネントで、サーバーがサービスを登録し、クライアントがそれらのサービスを見つけるための一元化されたディレクトリを提供します。今回は、オブジェクトを公開するサーバーの実装方法と、サーバー上のメソッドを呼び出すクライアントの実装方法、およびRMIレジストリへのサービスの登録と検索方法について説明します。

how java rmi registry works

サーバーインターフェースの宣言

javarmiの仕組みの複雑さを理解するために、名前を受け取って挨拶を返すメソッドを提供する簡単なサーバオブジェクトを実装してみましょう。以下に、オブジェクトインタフェースの定義を示す。

import java.rmi.Remote;
java.rmi.RemoteExceptionをインポートしてください。
public interface Greeting extends Remote.
{
public String greet(String name) throws RemoteException;
}

このインターフェイスの名前は greet と呼ばれ,名前を受け取って適切な挨拶を返す greet() というメソッドを提供する.

このインターフェイスをエクスポート可能なものとしてマークするには、java.rmi.Remoteファイルインターフェイスを拡張する必要があります。このメソッドは、アプリケーション固有の例外に加えて、java.rmi.RemoteException例外を列挙するthrows節も宣言する必要があります。これにより、クライアントコードは、ホストが見つからない、接続失敗などのリモートメソッド呼び出しエラーを処理(または伝播)することができます。

サーバーオブジェクトの実装

クライアント側で使用する)インターフェースを宣言した後、図のようにサーバー側のオブジェクトを実装し、greet()メソッドを提供します。挨拶文の書式設定には、簡単な書式文字列を使用します。

public class GreetingObject implements Greeting
{
private String fmtString = "こんにちは、%s";
public String greet(String name)
{
return String.format(this.fmtString, name);
}
}

サーバーマスター方式

では、これらのピースを組み合わせて、サーバーのmain()メソッドを実装してみましょう。

  • まず、サーバーオブジェクトの実装を作成します。Greeting greeting = new GreetingObject();
  • 次に、RMIランタイムからサーバオブジェクトのスタブを取得する。スタブはサーバオブジェクトと同じインタフェースを実装している。しかし、このメソッドは、リモートサーバーオブジェクトとの必要な通信を実装しています。このスタブは、クライアントがサーバーオブジェクト上のメソッドを透過的に呼び出すために使用されます。Greeting stub = (Greeting)UnicastRemoteObject.exportObject(greeting, 0);
  • スタブを取得したら、このスタブをRMIレジストリに渡し、指定された名前のサービスにバインドする。以下では、静的メソッド LocateRegistry.getRegistry() を用いて、ローカルレジストリの参照先を取得しています。その後、rebind()メソッドを用いて、スタブに名前をバインドする。String name = "Greeting";レジストリ registry = LocateRegistry.getRegistry(port);registry.rebind(name, stub)。

完全マスター方式。

import java.rmi.registry.LocateRegistry;
java.rmi.registryをインポートします。
java.rmi.server.UnicastRemoteObject.Import java.rmi.server.UnicastRemoteObject.Inc;
public class Main
{
static public void main(String[] args) throws Exception
{
if ( args.length == 0 ) {.
System.err.println("usage: java Main port#");
System.exit(1);
}
int index = 0;
int port = Integer.parseInt(args[index++])とする。
文字列名 = "挨拶";
Greeting greeting = new GreetingObject();
Greeting stub = (Greeting)UnicastRemoteObject.exportObject(greeting, 0);
レジストリ registry = LocateRegistry.getRegistry(port);
registry.rebind(name, stub);
System.out.println("Greeting bound to \" + name + "˶ˆ꒳ˆ˵")。
}
}

ビルドサーバー

では、サーバーを構築する方法を説明します。簡単のために、LinuxではMavenのようなビルドツールではなく、コマンドラインでのビルドを使用することにします。

以下は、ソースファイルをターゲットディレクトリにあるクラスファイルにコンパイルするものです。

rm -rf target
mkdir ターゲット
javac -d ターゲット src/server/*.java

クラスファイルをJARファイルに集めて実行する。

jar cvf target/rmi-server.jar -C target server

また、クライアントをライブラリJARにコンパイルするために必要なインターフェイスファイルも収集しています。

jar cvf target/rmi-lib.jar -C target server/Greeting.class

クライアントを実装する

では、サーバーオブジェクトのメソッドを呼び出すために使用されるクライアントをどのように実装するか見てみましょう。

  • サーバーと同様に、レジストリが稼働しているホスト名とポート番号を指定して、レジストリへの参照を取得します。レジストリ registry = LocateRegistry.getRegistry(host, port);
  • 次に、レジストリでサービスを検索します。lookup() メソッドは、サービスを呼び出すために使用できるスタブを返します。Greeting greeting = (Greeting) registry.lookup(name);
  • そして、必要な引数を渡してメソッドを呼び出す。ここでは、名前を渡すことで挨拶を取得し、それをプリントアウトしています。System.out.println(name + " reported:" + greeting.greet(myName));

フルクライアントコード

package client;
java.rmi.registry.LocateRegistry をインポートします。
java.rmi.registryをインポートします。
インポートサーバー
public class Client
{
static public void main(String[] args) throws Exception
{
if ( args.length != 3 ) {.
System.err.println("usage: java Client host port myName");
System.exit(1);
}
int index = 0;
文字列ホスト = args[index++];
int port = Integer.parseInt(args[index++])とする。
文字列 myName = args[index++];
文字列名 = "挨拶";
レジストリ registry = LocateRegistry.getRegistry(host, port);
Greeting greeting = (Greeting) registry.lookup(name);
System.out.println(name + " reported:" + greeting.greet(myName));
}
}

RMIレジストリ

では、サーバープログラムを実行して、リクエストの処理を開始させましょう。

java -cp target/rmi-server.jar server.Main 1099
# throws
スレッド「main」での例外 java.rmi.ConnectException:ホスト: xxx への接続が拒否されました。
java.net.ConnectException: 接続が拒否されました。

その例外とは?

この例外が発生する理由は、サーバーのコードから、ポート1099でローカルレジストリに接続しようとすることに注目してください。失敗すると、このような例外が発生します。

解決策は、RMIレジストリと呼ばれるJava仮想マシンに付属するプログラムを実行することです。Java Virtual Machineのインストール先のbinディレクトリにあるはずです。実行はとても簡単です。

/usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry

デフォルトでは、レジストリは1099番ポートをリッスンします。

/usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry 1100

指定したポートにリスナーが存在するかどうかは、netstatコマンドで確認します。

netstat -an -t tcp -p | grep LISTEN
...
tcp6 0 0 :::1100 :::* LISTEN 23450/rmiregistry

稼働中のサーバー

では、もう一度サーバーを動かしてみましょう。

java -cp target/rmi-server.jar server.Main 1100
# throws
java.rmi.UnmarshalException: error unmarshall arguments.
...
原因:java.lang.ClassNotFoundException: server.
...

今回も例外!?

サーバーはインターフェイスクラスサーバーをロードすることができませんでした。ごあいさつこれは、RMIレジストリが必要なクラスを読み込むことができなかったためです。そのため、必要なクラスの場所を指定する必要があります。環境変数CLASSPATHを指定するのも一つの方法です。

CLASSPATH=../../junk/target/rmi-lib.jar /usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry 1100

再度サーバーを起動しようとすると、以下のようになりました。

java -cp target/rmi-server.jar server.Main 1100
# prints
"Greeting "にバインドされている

これでサーバーが起動しました。

クライアントを実行する

すべてのパーツを組み立てて実行した後、クライアントを実行するのは簡単です。実行するためには、適切なジャーが必要です。これには、main()メソッドを含むクラスとインターフェースクラスが含まれます。RMIレジストリを実行する場所と、挨拶文の名前を示すパラメータを受け取ります。

java -cp target/rmi-client.jar:target/rmi-lib.jar client.Client localhost 1100 Peter
# prints
ごあいさつ:こんにちは、ピーターさん

概要

javarmiは、リモートコードの実行を簡略化するためのAPIとツールを提供します。javarmiレジストリにサービスオブジェクトを登録するサーバーを実装することができます。クライアントはレジストリに問い合わせてサービスオブジェクトのスタブを取得し、サービスメソッドを呼び出すことができる。この例のように、全てはとてもシンプルです。

あなたのプロジェクトでjavarmiを使用していますか、あなたの経験は何ですか、代替手段をお持ちですか、以下のコメントでお知らせください。

あなたが興味を持っているかもしれない記事

匿名者
匿名者

0 件の投稿

作家リスト

  1. admin 0 投稿
  2. 匿名者 0 投稿

おすすめ