Java RMI

Java RMI (Remote Method Invocation - Uzak Metod Yürütme) programcının dağıtık Java uygulamaları yaratmasını sağlar. Remote java nesnelerindeki metodlar diğer Java sanal makinelerinden çağrılabilir (farklı sunuculardan da). RMI nesne serileştirme kullanarak gerçek nesne yönelimli çokbiçimliliğini destekleyerek parametrelerin aktarımını sağlar. Java RMI Java SE ile varsayılan olarak gelmektedir.
RMI bir arayüz, bir sunucu (arayüzün gerçekleştirimi) ve bir istemciden oluşur. Bizim örnek RMI projemiz çok basit olacak, basit bir toplama işlemi yapacak.

Arayüz sınıfımız aşağıdaki şekildedir:

Sunucu sınıfımız yukarıda gösterdiğimiz arayüzü gerçekleştirecektir. Böylece arayüz içerisinde tanımladığımız hizmetleri (metodlar) sağlamış olacaktır. Sunucu sınıfımız aşağıdaki şekildedir:

Ve bu sunucudaki hizmeti kullanabilmek için basit bir istemci yazalım. Bu istemci sadece RMI registry'e kaydetmiş olduğumuz sunucunun hizmetini talep edecek. İstemci sınıfımız aşağıdaki şekildedir:


Yukarıdaki sınıfları yazdıktan sonra çalıştırma işlemleri biraz karışık olabiliyor. Aşağıdaki aşamaları takip ederek deneyebilirsiniz.

Çalıştırma Aşamalar:
  1. Sınıf kodlarının olduğu dizine gidelim (cd c:\KodDizini\)
  2. Classpath ayarlayalım. (SET CLASSPATH=.)
  3. İlk önce sınıflarımızı derleyelim. (javac *.java)
  4. Sunucu sınıfımızın stub dosyasını oluşturalım (rmic -v1.2 ToplamaImpl). Bu stub dosyası istemci tarafında kullanılacaktır.
  5. rmiregistry sunucusunu çalıştıralım (rmiregistry &). Windowsta başka bir command promptta çalıştırmalısınız.
  6. Yazdığımız ToplamaImpl sunucumuzu başlatıp RMI Registry'e kaydedelim(java -Djava.rmi.server.logCalls=true ToplamaImpl localhost).
  7. Şimdi istemciyi çalıştıralım (java -classpath . Istemci localhost 15 25) .(Classpath ayarlaması ile daha önceden rmic komutu ile ürettiğimiz sunucu stub dosyasını nerede bulacağını gösteriyoruz)
  8. Ekran çıktısı şu şekilde olmalıdır: 15+25=40
Kaynak kodlar

Bu çok basit bir RMI örneğidir. Proje büyüdükçe ve paketler, sınıflar arttıkça çalıştırmak için daha farklı yollar denemek gerekiyor. Örnek olarak benim Distributed Systems dersinde yaptığım ödev projesinin kaynak kodunu inceleyebilirsiniz. İçerisinde yorum yok ancak kodları ve calistir.sh (linux için yazılmış) betiğini inceleyerek paketler, classpath ve codebase'ler yardımıyla çalıştırmayı görebilirsiniz. Daha ayrıntılı RMI bilgisi için aşağıdaki kaynak bağlantılarını kullanabilirsiniz. (Biterken The Clash - Should i stay or should i go çalıyordu.)

Kaynaklar:
http://bornova.ege.edu.tr/~erdur/SYT_2005_RMI.zip
http://ube.ege.edu.tr/%7Ecinsdiki/2006-UBI511/Geylani-Sunum.ppt
http://ube.ege.edu.tr/%7Ecinsdiki/2006-UBI511/JavaRMI.rar
http://java.sun.com/javase/technologies/core/basic/rmi/index.jsp
http://java.sun.com/docs/books/tutorial/rmi/
http://www.javacoffeebreak.com/articles/javarmi/javarmi.html
http://java.sun.com/j2se/1.4.2/docs/guide/rmi/
http://java.sun.com/docs/books/tutorial/rmi/running.html

3 yorum:

hakdogan dedi ki...

Merhaba.

Öncelikle bu güzel makale için teşekkür ederim. Burada anlattığınız basit RMI uygulamasını aynen gerçekleştirmeye çalıştım, sadece ToplamaImpl class'ındaki

private static final long serialVersionUID = lL;

satırını kaldırdım, zira kod içinde lL değişkeni yoktu, bende kafadan bir rakam koymak istemedim.

Bütün adımları uygulayıp en son aşamada konsolda

java Istemci localhost 15 25

dediğimde

'Istemci' is not recognized as an internal or external command, operable program or bath file.

şeklinde bir hata alıyorum.

Sebep ne olabilir...

hakdogan dedi ki...

Usta tamamdır, ufak bir detayı atlamışım.

Paylaşım için teşekkürler...

Adsız dedi ki...

Uygulama oldukça anlaşılır fakat eksik. Bu kodlarla client'i serverden ayrı başka bir ps'de çalıştıramazsınız