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

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

RMI を意味する リモートメソッド呼び出し そして、その名前が示すように、Javaプログラムが別のコンピューターで実行されているオブジェクトのメソッドを呼び出すためのプロトコルです。これは、あるプログラム(サーバーと呼ばれる)からオブジェクトをエクスポートし、別のコンピューター(クライアントと呼ばれる)からそのオブジェクトのメソッドを呼び出すためのAPI(アプリケーションプログラミングインターフェイス)を提供します。





Java RMIレジストリ はJavaRMIシステムの主要コンポーネントであり、サーバーがサービスを登録し、クライアントがこれらのサービスを検索するための集中ディレクトリを提供します。この記事では、サーバーを実装してオブジェクトを公開し、クライアントを実装してサーバー上のメソッドを呼び出す方法と、RMIレジストリでサービスを登録および検索する方法について説明します。





ラップトップ用のLinuxの最高のバージョン

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

Java RMIシステムがどのように機能するかの複雑さを学ぶために、名前を受け入れて挨拶を返すメソッドを提供する単純なサーバーオブジェクトを実装しましょう。オブジェクトインターフェイスの定義は次のとおりです。





import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Greeting extends Remote
{
public String greet(String name) throws RemoteException;
}

インターフェイスの名前は呼ばれます 挨拶 。それはと呼ばれる単一のメソッドを提供します 挨拶() 名前を受け入れ、適切な挨拶を返します。

このインターフェースをエクスポート可能としてマークするには、 java.rmi.Remote インターフェース。また、メソッドは宣言する必要があります 投げる 条項リスト java.rmi.RemoteException アプリケーション固有の例外に加えて。これは、クライアントコードが次のようなリモートメソッド呼び出しエラーを処理(または伝播)できるようにするためです。 ホストが見つかりません接続障害 、 NS。



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

(クライアントが使用する)インターフェイスを宣言した後、サーバー側オブジェクトを実装し、 挨拶() 示されている方法。あいさつをフォーマットするために単純なフォーマット文字列を使用します。

public class GreetingObject implements Greeting
{
private String fmtString = 'Hello, %s';
public String greet(String name)
{
return String.format(this.fmtString, name);
}
}

サーバーのメインメソッド

これらすべての要素をまとめて実装しましょう。 主要() サーバーのメソッド。関連する各ステップを実行してみましょう。





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

完全なメインメソッド。

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
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++]);
String name = 'Greeting';
Greeting greeting = new GreetingObject();
Greeting stub = (Greeting)UnicastRemoteObject.exportObject(greeting, 0);
Registry registry = LocateRegistry.getRegistry(port);
registry.rebind(name, stub);
System.out.println('Greeting bound to '' + name + ''');
}
}

サーバーの構築

サーバーの構築について見てみましょう。簡単にするために、Mavenなどのビルドツールを使用するのではなく、Linuxのコマンドラインを使用してビルドします。





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

rm -rf target
mkdir target
javac -d target 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 registry = LocateRegistry.getRegistry(host, port);
  • 次に、レジストリでサービスを検索します。 NS 調べる() メソッドは、サービスの呼び出しに使用できるスタブを返します。 Greeting greeting = (Greeting) registry.lookup(name);
  • そして、必要な引数を渡してメソッドを呼び出します。ここでは、名前を渡して印刷することで挨拶をします。 System.out.println(name + ' reported: ' + greeting.greet(myName));

完全なクライアントコード:

package client;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import server.Greeting;
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;
String host = args[index++];
int port = Integer.parseInt(args[index++]);
String myName = args[index++];
String name = 'Greeting';
Registry 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
Exception in thread 'main' java.rmi.ConnectException: Connection refused to host: xxx; nested exception is:
java.net.ConnectException: Connection refused

とは この例外接続拒否

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

解決策は、RMIレジストリを実行することです。 RMIレジストリは、Java仮想マシンに付属しているプログラムであり、 rmir​​egistry 。に配置する必要があります 午前 Java仮想マシンインストールのディレクトリ。実行は次のように簡単です。

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

デフォルトでは、レジストリはポート1099でリッスンします。別のポートでリッスンするには、次のようにポート番号を指定します。

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

指定されたポートにリスナーが実際に存在することを確認します。 netstatコマンド

USBフラッシュドライブがWindows10に表示されない
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 unmarshalling arguments
...
Caused by: java.lang.ClassNotFoundException: server.Greeting
...

再び例外!今回は何ですか?

サーバーがインターフェイスクラスを読み込めません server.Greeting 。これは、RMIレジストリが必要なクラスをロードできないために発生します。したがって、必要なクラスの場所を指定する必要があります。これを行う1つの方法は、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 bound to 'Greeting'

これでサーバーが実行されます。

クライアントの実行

すべてのパーツが組み立てられて実行されたら、クライアントの実行は簡単です。実行には適切なJARが必要です。これらには、 主要() メソッド、およびインターフェイスクラス。 RMIレジストリが実行されている場所を示す引数と、グリーティングの名前を受け入れます。

java -cp target/rmi-client.jar:target/rmi-lib.jar client.Client localhost 1100 Peter
# prints
Greeting reported: Hello, Peter

概要

Java RMIは、リモートコード実行を容易にするAPIとツールを提供します。サービスオブジェクトをJavaRMIレジストリに登録するサーバーを実装できます。クライアントはレジストリにクエリを実行し、サービスメソッドを呼び出すためのサービスオブジェクトスタブを取得できます。この例が示すように、それはすべて非常に単純です。

プロジェクトでJavaRMIを使用していますか?あなたの経験は何ですか?調査した代替案はありますか?以下のコメントでお知らせください。

共有 共有 つぶやき Eメール スピーチをアニメーション化するためのビギナーズガイド

スピーチのアニメーション化は難しい場合があります。プロジェクトにダイアログを追加する準備ができたら、プロセスを分解します。

次を読む
関連トピック
  • プログラミング
  • Java
著者について ジェイ・スリダール(17の記事が公開されました) JaySridharのその他の作品

ニュースレターを購読する

ニュースレターに参加して、技術的なヒント、レビュー、無料の電子書籍、限定セールを入手してください。

購読するにはここをクリックしてください