www.fatihkabakci.com

Personal Website and Computer Science TUR EN

REMOTE METHOD INVOCATION(UZAK METOT CAGRISI)

Last update: 1/4/2015 7:34:00 PM

Yazan:Fatih KABAKCI

Java programlama dili, farklı sanal makineleri arasında ağ üzerinden çalışabilmeyi sağlayan, kısaca RMI olarak adlandırılan, Remote Method Invocation(Uzak Metot Çağrısı) yöntemini sağlar. RMI, bir Java Sanal Makinesi(Java Virtual Machine) üzerinde derlenmiş koda, başka bir Java Sanal Makinesi(Java Virtual Machine) üzerinde çalışan bir istemci uygulaması tarafından erişebilmesini sağlar. Bu önemlidir çünkü Javanın, çeşitli network uygulamalarında temel olarak sıklıkla kullanılan, istemci-sunucu(client-server) haberleşmesini ek bir kurulum yapmadan desteklediğini gösterir.

Bir RMI sistem tasarımında minimum gereksinim olarak aşağıda açıklanan 3 bileşen gerekir.

  1. java.rmi.Remote arabirimini(interface) genişleten(extends) bir arabirim tanımlamak. Bu arabirim hem server(sunucu) tarafının, hemde client(istemci) tarafının kullanacağı bir arabirim olacaktır.
  2. 1. adımda tanımlanan arabirimi uygulayan(implements), sunucu tarafında çalışan bir uygulama sınıfı oluşturmak. Bu sınıf sunucu tarafında çalışarak, istemciden gelen istekleri kabul edecek bir uygulama olacaktır.
  3. İstemci uygulaması yazmak. Bu uygulama, sunucuya gönderilecek istekleri betimler.

RMI

Java RMI API' si içerisinde, sunucu tarafında çalışan uygulama Registry yardımıyla RMI sunucusuna bir ad ile kayıt açar. Bu, istemcinin aynı isim uzayı ile bu kayda istekte bulunması gerektirir.

Örnek 1 - İki Tam Sayının RMI Üzerinde Toplamı

Konuya bir örnek ile devam edelim. İki tam sayı alan ve bu sayıların toplamını döndüren bir uygulamamızın olduğunu düşünelim. Amacımız bu uygulamayı RMI üzerinde çalıştırarak hizmet vermek olsun. Bu temel örnek ile bir RMI sistemi nasıl kullanılır adım adım inceleyelim.

Not: Aşağıda anlatılan örnekte, Windows işletim sisteminde D:\ dizini altında RMI adında bir dosya yaratılmıştır. Bu dosyanın içinde client ve server adında iki alt dosya daha oluşturulmuştur. Örnek sınıflar bu dosyalar altında derlenmektedir. Siz istediğiniz bir dosya yolu seçebilirsiniz.

1. Ortak Bir Çatı - Arabirim İnşa Etmek

RMI sisteminde öncelikli olarak bir arabirim inşa edilir. Bu arabirim java.rmi.Remote arabirimi extends eden ve yapılacak işlemi ihtiva eden bir interface' dir. Hatırlanacağı üzere, örneğimizde basitçe iki tam sayının RMI üzerinde toplamı yapılacaktır.

Interface Sum

package server;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * This interface defines remote interface that must be extended java.rmi.Remote
 * 
 * @author www.fatihkabakci.com
 */
public interface Sum extends Remote {
   public int sum(int number1, int number2) throws RemoteException;
}

RMI/server/ dizini altındaki Sum.java kaynak dosyası aşağıdaki gibi derlenerek JAR dosyası çıkarılır.

D:\RMI>javac server\Sum.java

D:\RMI>jar cvf sum.jar server\Sum.class
added manifest
adding: server/Sum.class(in = 192) (out= 153)(deflated 20%)

Yeni durumda sum.jar dosyası D:\RMI dizini altında oluşur. Bu JAR daha sonra, temsili olarak istemci ve sunucu tarafında çalışan programcılara uzak metot çağrısı yapma imkanı sağlayacaktır.

2. Sunucu Sınıfını Tasarlamak

Sunucu(Server) sınıfları bazen direk UnicastRemoteObject sınıfından türetilerek nesne oluşturulması ile, bazen de bu sınıfın statik exportObject() metotları tarafından üretilen nesneler yardımıyla tasarlanır. Bu örnekte exportObject() metodu kullanılmıştır. Sunucu sınıfı, belirli bir port üzerinden kayıt açar. Bu kayıt, istemci tarafından gelen isteklere cevap verecek bir RMI kaydı olarak adlandırılır. Sunucu sınıfı ayrıca, ortak çatı olan arabirimi uygulayarak(implements) istemci hizmetini somut hale getirir. Özellikle distributed(dağıtık) uygulamalar için tasarlanan bu sınıflar genel olarak compute engine(hesaplama motoru) adını almaktadır.

Server Class SumComputeEngine

package server;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

/**
 * This class is remote object and it defines a concrete class that is extended from the class java.rmi.server.UnicastRemoteObject
 * and implements the interface type of java.rmi.Remote. The main rmi server rebinds own operation objects which are assigned for
 * specific works.
 * 
 * @author www.fatihkabakci.com
 */
public class SumComputeEngine implements Sum {

   public static void main(String[] args) {
      String name = "Sum";
      int port = 5000;

      try {
         Remote stub = UnicastRemoteObject.exportObject(new SumComputeEngine(), port);
         Registry registry = LocateRegistry.createRegistry(port);
         registry.rebind(name, stub);
         System.out.println("RMI Server is running now");
      }
      catch (RemoteException e) {
         e.printStackTrace();
      }
   }

   @Override
   public int sum(int number1, int number2) throws RemoteException {
      return number1 + number2;
   }
}

RMI/server/ dizini altındaki SumComputeEngine.java kaynak dosyası aşağıdaki gibi derlenerek JAR dosyası çıkarılır.

D:\RMI>javac -cp .:sum.jar; server\SumComputeEngine.java

D:\RMI>jar cvfe computeSum.jar server.SumComputeEngine server\SumComputeEngine.class
added manifest
adding: server/SumComputeEngine.class(in = 1098) (out= 646)(deflated 41%)

Yeni durumda computeSum.jar dosyası D:\RMI dizini altında oluşur. Bu JAR çalıştırıldığında, sunucu tarafında 'Sum' adlı bir RMI kaydı başlatır ve istemci tarafından çağrılacak olan sum() adlı metodun gerçek işlevini yapmasını sağlar. Bunu nasıl yaptığına değinirsek, exportObject() statik metodu ile bir stub oluşturulur. Stub, uzak nesneyi(remote object) temsil eden Remote referansları olarak adlandırılır. createRegistry() statik metodu RMI kaydını başlatacak olan bir kayıtçısı oluşturur. Bu kaydedici, 'Sum' adlı bir RMI başlığına, oluşturulan stub referansını bağlar(bind).

3. İstemci Sınıfını Tasarlamak

İstemci(Client) sınıfları, bir RMI URL' i kullanarak RMI kayıt sunucusundan bir nesne referansı alır. Elde ettiği bu nesne referansı sayesinde, sunucu tarafında çalışan ilgili metoda çağrıda bulunmuş olur. İstemciler, RMI kayıt sunucularına lookup denilen bir çağrı ile ulaşır.

Client Class DoSum

package client;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import server.Sum;

/**
 * This class describes client' s behaviour. The client application retrieves three input from the user. The first input is server
 * IP address and the other two input are data will be used for collecting operation. The client application does look up calling to
 * the server with server's url. It is able to calculate the collected value using an interface reference of the server. The last,
 * it writes the total sum value on console output.
 * 
 * @author www.fatihkabakci.com
 */
public class DoSum {
   public static void main(String[] args) {
      System.out.println("Enter the server ip and two integer data sequentially please");
      
      if (args.length < 3) {
         System.err.println("The server ip and numeric values must be required to run the program RMIClient");
         System.exit(0);
      }

      try {
         int number1 = Integer.parseInt(args[1].toString());
         int number2 = Integer.parseInt(args[2].toString());

         String serverURL = "rmi://" + args[0] + "/Sum";

         Sum stub = (Sum) Naming.lookup(serverURL);
         int result = stub.sum(number1, number2);
         System.out.println("Result:" + result);
      }
      catch (NumberFormatException e) {
         System.err.println("The numeric values must be an integer");
      }
      catch (MalformedURLException e) {
         System.err.println("The URL is invalid");
      }
      catch (RemoteException e) {
         System.err.println("Remote error:" + e.getMessage());
      }
      catch (NotBoundException e) {
         System.err.println("The server' s stub is not bound");
      }
   }
}

RMI/client/ dizini altındaki DoSum.java kaynak dosyası aşağıdaki gibi derlenerek JAR dosyası çıkarılır.

D:\RMI>javac -cp .:sum.jar; client\DoSum.java

D:\RMI>jar cvfe doSum.jar client.DoSum client\DoSum.class
added manifest
adding: client/DoSum.class(in = 1663) (out= 986)(deflated 40%)

Yeni durumda doSum.jar dosyası D:\RMI dizini altında oluşur. Bu JAR çalıştırıldığında, istemci tarafında 'Sum' adlı RMI kaydına lookup çağrısı yapar. Bu çağrıdan elde ettiği Sum referansı ile, kullanıcıdan aldığı komut satırı argümanlarını sunucuyu gönderir. Sunucu bu işlemi hesaplar ve istemciye işlemin sonucunu gönderir. İstemci bu sonucu sunucudan alır ve JAR' ın çalıştırıldığı konsol ekranına basar.

4. Sunucuyu Başlatmak

Sunucu aşağıdaki şekilde başlatılarak, 5000 portu üzerinde Sum adlı bir RMI kaydı başlatır.

D:\RMI>java server.SumComputeEngine
RMI Server is running now

5. İstemciyi Başlatmak

İstemci, kullanıcıdan bir IP adresi veya sunucu adı, toplanacak iki tane tam sayı olmak üzere, toplamda 3 adet girdi isteyerek, RMI kayıt sunucusuna lookup çağrısı yapar. İstemci programı sunucu programı başladıktan sonra çalıştırılmalıdır. Aksi halde NotBoundException, ConnectionRefused ve StubClassNotFoundException gibi hatalar alınabilir. İstemci uygulaması aşağıdaki gibi başlatılır. Aşağıda, sunucu çalıştığı sırada çeşitli sorgular yapılmaktadır.

D:\RMI>java client.DoSum 127.0.0.1:5000 2 3
Enter the server ip and two integer data sequentially please
Result:5

D:\RMI>java client.DoSum 127.0.0.1:5000 2 1
Enter the server ip and two integer data sequentially please
Result:3

D:\RMI>java client.DoSum 127.0.0.1:5000 2
Enter the server ip and two integer data sequentially please
The server ip and numeric values must be required to run the program RMIClient

D:\RMI>java client.DoSum 127.0.0.1:4000 2 3
Enter the server ip and two integer data sequentially please
Remote error:Connection refused to host: 127.0.0.1; nested exception is:
        java.net.ConnectException: Connection refused: connect

D:\RMI>java client.DoSum
Enter the server ip and two integer data sequentially please
The server ip and numeric values must be required to run the program RMIClient

Yukarıdaki sorgularda, dikkat edilirse 5000 portu dışında yapılan sorgularda bir Remote error hatası alındığı gözlemlenmektedir. Burada anlatılan uygulamlar localhost üzerinde çalıştırılarak test edilmiştir. Gerçek uygulamalarda ise, uzak metot çağrıları açık bir ağ paylaşımı üzerine koyulan JAR dosyaları üzerinden gerçekleştirilir.

Örnek 2 - Girilen Bir Sayının RMI Üzerinde Mutlak Değerinin Hesaplanması

İkinci örneğimizde, yine yukarıdaki örnekteki 5 adımı kullanarak bir RMI uygulaması yapalım. Bu örnekte, girilen bir sayının RMI üzerinde mutlak değeri hesaplanacaktır.

Absolute Arabirimi

package server;

/**
 * This interface defines remote interface that must be extended java.rmi.Remote
 * 
 * @author www.fatihkabakci.com
 */
public interface Absolute<T extends Number> extends java.rmi.Remote {
   public T absolute(T number) throws java.rmi.RemoteException;
}

Yukarıda tanımlanan Absolute arabirimi, sayısal verileri kabul ederek, özet bir metot tanımlar.

Sunucu Uygulaması olan AbsoluteComputeEngine Sınıfı

/**
 * 
 */

package server;

import static java.lang.Math.abs;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

/**
 * This class is remote object and it defines a concrete class that is extended from the class java.rmi.server.UnicastRemoteObject
 * and implements the interface type of java.rmi.Remote. The main rmi server rebinds own operation objects which are assigned for
 * specific works.
 * 
 * @author www.fatihkabakci.com
 */
public class AbsoluteComputeEngine extends UnicastRemoteObject implements Absolute<Number> {

   private static final long serialVersionUID = 1L;

   protected AbsoluteComputeEngine() throws RemoteException {
      super();
   }

   @Override
   public Number absolute(Number number) {
      Class<?> cls = number.getClass();

      if (cls.isAssignableFrom(Double.class)) {
         return abs(number.doubleValue());
      }

      else if (cls.isAssignableFrom(Float.class)) {
         return abs(number.floatValue());
      }

      else if (cls.isAssignableFrom(Long.class)) {
         return abs(number.longValue());
      }

      else if (cls.isAssignableFrom(Integer.class)) {
         return abs(number.intValue());
      }

      else if (cls.isAssignableFrom(Short.class)) {
         return abs(number.shortValue());
      }

      else if (cls.isAssignableFrom(Byte.class)) {
         return abs(number.byteValue());
      }

      else {
         return null;
      }
   }

   public static void main(String[] args) {

      String name = "Absolute";
      int port = 4000;

      try {
         AbsoluteComputeEngine stub = new AbsoluteComputeEngine();
         Registry registry = LocateRegistry.createRegistry(port);
         registry.rebind(name, stub);
         System.out.println("RMI Server is running now");
      }
      catch (RemoteException e) {
         System.err.println(e.getMessage());
      }
   }
}

Yukarıdaki AbsoluteComputeEngine uygulama sınıfı, bir önceki toplama örneğinden farklı olarak, sınıfın UnicastRemoteObject sınıfından türetilmesidir. Bu zorunlu değildir ancak sunucu sınıfları bazı uygulamalarda bu şekilde tasarlanır. Bir UnicastRemoteObject sınıfı olan AbsoluteComputeEngine sınıfı, main içerisinde doğrudan oluşturularak, RMI kayıt sunucusuna bağlanır.

İstemci Uygulaması olan ComputeAbsolute

/**
 * 
 */

package client;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import server.Absolute;

/**
 * This class describes client' s behaviour. The client application retrieves the two input from the user. The first input is server
 * IP address and the second input is data will be used for absolute operation. The client application does look up calling to the
 * server with server' s url. It is able to calculate the absolute value using an interface reference of the server. The last, it
 * writes the absolute value on console output.
 * 
 * @author www.fatihkabakci.com
 */
public class ComputeAbsolute {
   public static void main(String[] args) {
      if (args.length < 2) {
         System.err.println("The server ip and numeric value must be required to run the program RMIClient");
         System.exit(0);
      }

      Number number = null;
      try {
         number = Number.class.cast(args[1]);
      }
      catch (ClassCastException cce) {
         System.err.println("The value was entered must be in a number format");
         System.err.println(cce.getMessage());
         System.exit(0);
      }

      String serverURL = "rmi://" + args[0] + "/Absolute";
      try {
         Absolute<Number> abs = (Absolute<Number>) Naming.lookup(serverURL);
         Number absoluteNumber = abs.absolute(number);
         System.out.println("Absolute value:" + absoluteNumber);
      }
      catch (MalformedURLException e) {
         e.printStackTrace();
      }
      catch (RemoteException e) {
         e.printStackTrace();
      }
      catch (NotBoundException e) {
         e.printStackTrace();
      }
   }
}

Yukarıdaki istemci uygulaması 4000 portu üzerinden RMI sunucuna bağlanarak lookup çağrısı yapar. Kullanıcıdan aldığı sayısal veriyi RMI sunucuna göndererek uzak metot çağrısı yapar.

D:\RMI>javac server\Absolute.java

D:\RMI>jar cfv absolute.jar server\Absolute.class
added manifest
adding: server/Absolute.class(in = 339) (out= 214)(deflated 36%)

D:\RMI>javac -cp .:absolute.jar; server\AbsoluteComputeEngine.java

D:\RMI>jar cfve compute.jar server.AbsoluteComputeEngine server\AbsoluteComputeEngine.class
added manifest
adding: server/AbsoluteComputeEngine.class(in = 2169) (out= 1171)(deflated 46%)

D:\RMI>javac -cp .:absolute.jar; client\ComputeAbsolute.java

D:\RMI>jar cfve compute.jar client.ComputeAbsolute client\ComputeAbsolute.class
added manifest
adding: client/ComputeAbsolute.class(in = 1707) (out= 986)(deflated 42%)

D:\RMI>java client.ComputeAbsolute
The server ip and numeric value must be required to run the program RMIClient

D:\RMI>java client.ComputeAbsolute 127.0.0.1:4000 3
Input:3
Absolute value:3.0

D:\RMI>java client.ComputeAbsolute 127.0.0.1:4000 -4
Input:-4
Absolute value:4.0

Özetle, RMI(Remote Method Invocation - Uzak Metot Çağrısı), uzak bir makine üzerinde tanımlanan metotlara, başka bir makine üzerinden erişilerek çağrı yapılma işlemine denir. RMI tipik bir istemci/sunucu uygulaması olarak çalışır. Dağıtık uygulamalar(Distributed applications) için kullanılan uzak metot çağrıları, dinamik kod yükleme özelliğiyle avantaj sağlar.

MemberCommentDate:
guest
Teşekkürler. 

metin

1/24/2017 10:56:00 AM

Name:


Question/Comment
   Please verify the image




The Topics in Computer Science

Search this site for





 

Software & Algorithms

icon

In mathematics and computer science, an algorithm is a step-by-step procedure for calculations. Algorithms are used for calculation, data processing, and automated reasoning.

Programming Languages

icon

A programming language is a formal constructed language designed to communicate instructions to a machine, particularly a computer. It can be used to create programs to control the behavior of a machine. Java,C, C++,C#

Database

icon

A database is an organized collection of data. The data are typically organized to model aspects of reality in a way that supports processes requiring information.

Hardware

icon

Computer hardware is the collection of physical elements that constitutes a computer system. Computer hardware refers to the physical parts or components of a computer such as the monitor, memory, cpu.

Web Technologies

icon

Web development is a broad term for the work involved in developing a web site for the Internet or an intranet. Html,Css,JavaScript,ASP.Net,PHP are one of the most popular technologies. J2EE,Spring Boot, Servlet, JSP,JSF, ASP

Mobile Technologies

icon

Mobile application development is the process by which application software is developed for low-power handheld devices, such as personal digital assistants, enterprise digital assistants or mobile phones. J2ME

Network

icon

A computer network or data network is a telecommunications network that allows computers to exchange data. In computer networks, networked computing devices pass data to each other along data connections.

Operating Systems

icon

An operating system is software that manages computer hardware and software resources and provides common services for computer programs. The OS is an essential component of the system software in a computer system. Linux,Windows

Computer Science

icon

Computer science is the scientific and practical approach to computation and its applications.A computer scientist specializes in the theory of computation and the design of computational systems.