Java 11: RMI over IIOP を IIOP を使わないよう書き換える

(2019.9)

Java 11で CORBA がごっそり削除された。それに伴い, RMI over IIOP も削除された。

IIOP を使わないように書き換える。先祖返り。

インタフェイス

この例では、派生クラスが使えるかも試してみる。

IIOP を使うかどうか、特に変更はない。

Counter.java

Java
[RAW]
  1. import java.rmi.Remote;
  2. import java.rmi.RemoteException;
  3. public interface Counter extends Remote {
  4. public short getValue() throws RemoteException;
  5. public void incr() throws RemoteException;
  6. public void decr() throws RemoteException;
  7. public String name() throws RemoteException;
  8. };

メソッドを追加しないので、派生したインタフェイスを定義するだけ。

ReverseCounter.java

Java
[RAW]
  1. public interface ReverseCounter extends Counter
  2. {
  3. };

サーバ

まずはインタフェイスを実装する部分.

IIOP のときは javax.rmi.PortableRemoteObject から派生させていたが、削除されたため、書いてはならない.

server.java

Java
[RAW]
  1. import java.rmi.RemoteException;
  2. // module java.naming; package javax.naming
  3. //import javax.naming.InitialContext;
  4. //import javax.naming.Context;
  5. import java.rmi.registry.LocateRegistry;
  6. import java.rmi.registry.Registry;
  7. import java.rmi.server.UnicastRemoteObject;
  8. // UnicastRemoteObject -> PortableRemoteObjectから派生
  9. // Java 11: error: package javax.rmi は存在しない.
  10. // extends javax.rmi.PortableRemoteObject はもはや書いてはならない.
  11. class CounterImpl implements Counter
  12. {
  13. protected short value;
  14. public CounterImpl() throws RemoteException {
  15. super();
  16. value = 0;
  17. }
  18. public void incr() throws RemoteException { value++; }
  19. public void decr() throws RemoteException { value--; }
  20. public String name() throws RemoteException { return "Counter"; }
  21. public short getValue() throws RemoteException { return value; }
  22. };
  23. class ReverseCounterImpl extends CounterImpl implements ReverseCounter
  24. {
  25. public ReverseCounterImpl() throws RemoteException {
  26. super();
  27. value = 1000;
  28. }
  29. public void incr() throws RemoteException { value--; }
  30. public void decr() throws RemoteException { value++; }
  31. public String name() throws RemoteException { return "ReverseCounter"; }
  32. };

サーバクラス。名前解決の部分が変更になる。昔に戻って, レジストリにオブジェクトを登録する。

Java
[RAW]
  1. public class server
  2. {
  3. public static void main(String[] args)
  4. {
  5. try {
  6. Counter counter = new CounterImpl();
  7. Counter reverse = new ReverseCounterImpl();
  8. // レジストリに登録.
  9. Registry registry = LocateRegistry.getRegistry();
  10. // You have to set "java.naming.factory.initial".
  11. //Context initialNamingContext = new InitialContext();
  12. //initialNamingContext.rebind("q.Counter", counter);
  13. //initialNamingContext.rebind("q.ReverseCounter", reverse);
  14. registry.bind("q.Counter",
  15. UnicastRemoteObject.exportObject(counter, 0));
  16. registry.bind("q.ReverseCounter",
  17. UnicastRemoteObject.exportObject(reverse, 0));
  18. System.out.println("Server ready.");
  19. }
  20. catch (Exception e) {
  21. System.err.println("Server exception: " + e.toString());
  22. e.printStackTrace(System.err);
  23. }
  24. }
  25. };

クライアント

こちらも名前解決の部分が変更になる。

client.java

Java
[RAW]
  1. //import javax.naming.InitialContext;
  2. //import javax.naming.Context;
  3. // Java11: javax.rmi パッケージは削除された.
  4. //import javax.rmi.PortableRemoteObject;
  5. import java.rmi.registry.LocateRegistry;
  6. import java.rmi.registry.Registry;
  7. class client
  8. {
  9. // @param args args[0] hostname
  10. public static void main(String[] args)
  11. {
  12. String host = args[0];
  13. try {
  14. // サーバーオブジェクトの取得
  15. // 2000.11.03 rmi-iiop化では,java.rmi.Naming#lookup()を
  16. // javax.naming.InitialContext#lookup()に書き換える
  17. //Context initialNamingContext = new InitialContext();
  18. // レジストリに問い合わせ
  19. Registry registry = LocateRegistry.getRegistry(host);
  20. Counter[] counter = new Counter[4];
  21. //counter[0] = (Counter) initialNamingContext.lookup("q.Counter");
  22. //counter[1] = (Counter) initialNamingContext.lookup("q.ReverseCounter");
  23. //counter[2] = (Counter) initialNamingContext.lookup("q.Counter");
  24. //counter[3] = (Counter) initialNamingContext.lookup("q.ReverseCounter");
  25. counter[0] = (Counter) registry.lookup("q.Counter");
  26. counter[1] = (Counter) registry.lookup("q.ReverseCounter");
  27. counter[2] = (Counter) registry.lookup("q.Counter");
  28. counter[3] = (Counter) registry.lookup("q.ReverseCounter");

使う部分は、特に変更にならない。

Java
[RAW]
  1. for (int k = 0; k < counter.length; k++) {
  2. System.out.println(counter[k].name());
  3. for (int i = 0; i < 10; i++) {
  4. counter[k].incr();
  5. System.out.print(counter[k].getValue() + " ");
  6. }
  7. System.out.println(".");
  8. for (int i = 0; i < 5; i++) {
  9. counter[k].decr();
  10. System.out.print(counter[k].getValue() + " ");
  11. }
  12. System.out.println(".");
  13. }
  14. }
  15. catch (Exception e) {
  16. System.err.println("Client exception: " + e.toString());
  17. e.printStackTrace(System.err);
  18. }
  19. }
  20. };

実行結果

名前解決を行うレジストラを起動しておくこと。

$ rmiregistry &

クライアントを実行すると, こういう出力になる。サーバ側で状態が保持されている。

Counter
1 2 3 4 5 6 7 8 9 10 .
9 8 7 6 5 .
ReverseCounter
999 998 997 996 995 994 993 992 991 990 .
991 992 993 994 995 .
Counter
6 7 8 9 10 11 12 13 14 15 .
14 13 12 11 10 .
ReverseCounter
994 993 992 991 990 989 988 987 986 985 .
986 987 988 989 990 .