บทที่ 3
Java RMI เบื้องต้น
Java RMI ( Remote Method Invocation ) คือระบบวัตถุแบบกระจาย ( Distributed Object
System ) เบื้องต้น ก่อนจะพัฒนาไปสู่ง Jini Network ตามแนวทางปรัชญาของ Linda Systems ที่วางไว้ตั้งแต่ปี 1982
ซึ่งพัฒนาโดยบริษัท Sun Microsystems คำว่า ออบเจ็กต์แบบกระจายนั้น หมายถึงว่า
ออบเจ็กต์ที่ทำงานอยู่เป็นระบบหนึ่งนั้น สามารถกระจายอยู่ตามที่ต่าง ๆ บนเครือข่าย
( บน Java Virtual Machine ในที่ต่าง ๆ ในระบบเครือข่าย )
ซึ่งออบเจ็กต์ที่ถูกสร้างที่อยู่ต่าง Virtual Machine กัน( แม้เครื่องเดียวกันก็ได้ )
สามารถเรียกใช้ Method ระหว่างกันได้โดยผ่านทางกระบวนการของ Java RMI
ซึ่งในฝั่งผู้เรียกใช้ออบเจ็กต์ นั้นจะเรียกใช้ Object นั้น ได้เหมือนกับว่า Object
นั้นอยู่ใน Address Space เดียวกัน ซึ่งมีลักษณะที่คล้ายกับระบบออบเจ็กต์แบบกระจาย
แบบอื่น ๆ เช่น CORBA หรือ RPCs แต่แตกต่างกันที่ Java RMI นั้นถูกพัฒนามาให้ใช้กับ
ภาษาจาวาเท่านั้น แต่ CORBA หรือ RPCs นั้น สามารถใช้กับภาษาใด ๆ ก็ได้
3.1 ข้อแตกต่างระหว่าง Java RMI กับ CORBA
-
CORBA เป็นมาตรฐานที่ไม่ขึ้นอยู่กับภาษาใด ๆ ทำงานได้กับภาษาเชิงออบเจ็กต์
ได้เกือบจะทุกภาษา
-
CORBA มีกระบวนการต่าง ๆ อีกหลายอย่างที่เป็นมาตรฐาน( เช่น TP Monitor )
ซึ่งไม่มีใน Java RMI
-
ไม่มีการพูดถึง Object Request Broker ใน Java RMI
แต่ ในปัจจุบัน Java RMI ได้ถูกพัฒนาเพื่อเชื่อมต่อกับกับมาตรฐานของ CORBA
ผ่าน IIOP ( Internet Inter-ORB Protocol ) หรือเรียกชื่อใหม่ว่า RMI/IIOP ( RMI Over IIOP )
3.2 สถาปัตยกรรมของ Java RMI
การออกแบบ Java RMI นั้นทำขึ้นโดยมีเป้าหมายที่ว่าเพื่อจะสร้างระบบ
ออบเจ็กต์แบบกระจายที่สามารถเข้ากันได้กับภาษาจาวา
โดยที่ยังคงวิธีการเหมือนกับการเรียกใช้ Local Object
ซึ่ง Java RMI ก็สามารถทำได้เป็นอย่างดี โดยส่วนประกอบที่เป็นพื้นฐานของสถาปัตยกรรมของ Java RMI มีดังต่อไปนี้
3.2.1 Interface : หัวใจหลักของ Java RMI
สถาปัตยกรรมของ Java RMI มีหลักการสำคัญอยู่ 1 อย่างก็คือ
การสร้างส่วนอธิบายวิธีการปฏิบัติการของออบเจ็กต์ ( Object Operation Definition )
หรือสามารถเรียกอีกอย่างได้ว่า Method Definition ของออบเจ็กต์
และการสร้างวิธีการปฏิบัติการของออบเจ็กต์ ( Object Operation Implementation )
ซึ่งส่วนที่ใช้อธิบายวิธีการปฏิบัติการของออบเจ็กต์ เราเรียกว่า Interface นั่นเอง
ซึ่งทั้งสองส่วนนี้สามารถทำงานแยกกันในต่าง Virtual Machine ได้
ซึ่งหลักการนี้เข้ากันได้ดีกับหลักการของ ระบบออบเจ็กต์แบบกระจาย คือ ฝัง
Client สามารถเรียกใช้ Method ผ่าน Interface ส่วน Server
ก็มุ่งไปที่การให้บริการออบเจ็กต์
ซึ่งการสร้างส่วนที่อธิบาย Operation ของออบเจ็กต์นั้น
ในการเขียนโปรแกรมภาษาจาวาใช้ Interface ของภาษาจาวาในการสร้าง ส่วนการสร้าง
ส่วนปฏิบัติการณ์ของออบเจ็กต์ ( Remote Service ) นั้น ใช้คลาสของจาวาในการสร้าง
ดังนั้นหลักการสำคัญของ Java RMI ที่จะต้องรู้ก็คือ Interface
อธิบายวิธีปฏิบัติการของออบเจ็กต์ ส่วน คลาสอธิบายการสร้างและการทำงานของออบเจ็กต์
โดย Client รู้จักเพียง Interface ส่วน Server ทำงานกับ คลาส
รูปที่ 3-1 ระบบ Interface และอิมพลีเมนเทชัน
ส่วนของ
โค้ดที่เอ็กซิคิวต์ได้นั้น จะไม่มีอยู่ในส่วนของ Interface แต่ Java RMI จะรองรับ
2 คลาส ซึ่งสร้างจาก Interface เดียวกันโดย คลาสแรกทำหน้าที่เป็น Service Implemantation ในฝั่ง Server
ส่วนคลาสที่สองทำหน้าที่เป็น Service Proxy สำหรับการ Remote Service จาก Client ดังที่แสดงในรูปต่อไปนี้
รูปที่ 3-2 การคุยกันระหว่าง Service Proxy และ Service Implemantation
โปรแกรม
Client จะเรียกใช้ Method จาก Service Proxy จากนั้น Java RMI จะทำการส่งคำร้องขอ
ไปยัง Service ที่ฝั่ง Server ผ่าน Service Implemantation โดยฝัง Server
จะทำการประมวลผลและถ้าหากมีผลลัพธ์ ผลลัพธ์นั้นก็จะถูกส่งกลับไปให้กับ Service Proxy
และส่งคืนให้กับโปรแกรม Client ที่เรียกใช้ Method นั้น
3.2.2 ชั้นของสถาปัตยกรรมของ Java RMI
เมื่อเข้าใจหลักการทำงานของ Java RMI ในภาพรวมแล้วก็ลองมาดูเบื้องหลังในส่วนที่อธิบายการทำงานของ Java RMI ว่าทำอย่างไร ถึงจะทำเช่นที่กล่าวมาในข้างต้นได้
การทำงานของ Java RMI นั้น ถูกสร้างขึ้นมาจาก 3 Abstract Layer เลเยอร์ส่วนแรกคือ
Stub & Skeleton Layer ส่วนที่สองคือ Remote Referance Layer ซึ่งอธิบายการเชื่อมต่อของ Java RMI
รวมทั้งยังทำหน้าที่ในการดาวน์โหลด Java Byte Code ของ Class หรือ Object ที่ถูกอ้างถึง เพื่อมาประมวลผลทั้งฝัง
Client และ Server ทำให้ทุกวันนี้ มีเพียง Java RMI เท่านั้น ที่ได้ชื่อว่า Object Network อย่างแท้จริง
และส่วนที่ 3 คือ Transport Layer ซึ่งสร้างการเชื่อมต่อระหว่าง Java Virtual Machine ด้วย TCP/IP
ซึ่งเลเยอร์ที่เราจะพิจารณาเพื่อความเข้าใจในโครงการนี้ เราจะสนใจเฉพาะแค่ Stub & Skeleton Layer เท่านั้น
รูปที่ 3-3 เลเยอร์ของสถาปัตยกรรมของ Java RMI
3.2.3 Stub & Skeleton Layer
การทำงานของ Layer นี้จะเป็นกระบวนการที่ผู้พัฒนาไม่จำเป็นต้องมาเกี่ยวข้อง
ซึ่งทำหน้าที่รับการเรียกใช้ Method มาจาก Client และส่งการเรียกนี้ ( Remote
Service ) ไปยังฝั่ง Server
ใน Layer นี้ Java RMI ได้ใช้ดีไซน์แพทเทิร์นคือ
พรอกซี่แพทเทิร์นซึ่งในพรอกซี่แพทเทิร์นนั้น
ออบเจ็กต์ที่อยู่ในสิ่งแวดล้อมของระบบหนึ่งสามารถถูกแสดงแทนในอีกระบบหนึ่งด้วยออบเจ็กต์
อีกออบเจ็กต์ หนึ่งที่เรียกว่าพรอกซี่ดังคลาสไดอะแกรมด้านล่างนี้
รูปที่ 3-4 ดีไซน์แพทเทิร์นแบบพรอกซี่
Class ของ Stub และ Skeleton ถูกสร้างขึ้นใน Java RMI โดยสร้างจาก Base Class ที่ทำหน้าที่เป็น
Remote Service ซึ่งวิธีการสร้างนั้นจะกล่าวถึงอีกทีในบทนี้
Stub Class ทำหน้าที่เป็น Service Proxy และ Object ที่สร้างเป็น Remote Service
ทำหน้าที่เป็น Real Subject ส่วน Skeleton Class ทำหน้าที่เป็น Service Implemantation
จะอ่านค่า Parameter ที่เรียกใช้ Method นั้น แล้วทำการเรียกต่อไปยัง Service Object
แล้วรอรับค่าที่ส่งกลับมา จากนั้นจึงจะส่งค่านั้นกลับไปยัง Stub Class
ตั้งแต่ Java 2 Platform, Standard Edition ( J2SE 1.2 ) ทางบริษัท Sun Microsystems
ได้มีการพัฒนา Java RMI ใหม่ โดยไม่ต้องใช้ Skeleton Layer อีกต่อไป ดังนั้นเราสนใจ
Skeleton Layer หรือ Skeleton Class เฉพาะพัฒนา Java RMI กับ JDK 1.0
และ 1.1 เท่านั้น
รูปที่ 3-5 การทำงานของสตับและสเกลเลตัน
3.3 การค้นหา Remote Service
จากกระบวนการต่าง ๆ ที่กล่าวมาในข้างต้น ยังคงมีปัญหาที่ว่า Client นั้น สามารถค้นหา
Remote Service ได้อย่างไร รู้ได้อย่างไรว่า Remote Service
นั้นอยู่ที่ไหนบนเครือข่าย
ทางแก้ของปัญหานี้ก็คือ Java RMI ได้มีการใช้ Naming and Directory Service ( เป็น
Service ที่ทำการเก็บรักษาออบเจ็กต์ หรือ อ้างอิงออบเจ็กต์ไว้ โดยการอ้างอิงด้วยชื่อ ) ในการเก็บตัวอ้างอิงออบเจ็กต์ของ
Remote Service ซึ่ง Client นั้น จะต้องทำการเรียกใช้งาน Naming and Directory Service นี้
ซึ่งก็ทำให้เกิดปัญหาตามมาอีกว่า Client จะรู้ได้อย่างไรว่า
Naming and Directory Service นี้อยู่ที่ใด คำตอบก็คือ Naming ane Directory Service นี้
จะทำงานอยู่บน Host และ Port ที่เป็นที่รู้จัก หมายความว่า Client
จะต้องรู้ว่ามี Naming and Directory Service นั้นทำงานอยู่ที่ไหน
และสามารถเรียกใช้บริการของ Naming and Directory Service นั้นได้โดยตรง
การทำงานของ Server ผู้ให้บริการ Remote Service นั้น Server
จะต้องทำการสร้าง Local Object จาก Class ซึ่งสร้างจาก Remote Service Interface
จากนั้นจึงทำการ Export Object นั้นออกไปยัง Java RMI ( การเอ็กซ์พอร์ตทำได้โดย extends
UnicastRemoteObject หรือ เรียกใช้ Method ชื่อ exportObject() )
แล้วจึงทำการลงทะเบียนตัวเองเข้ากับ Naming Service ด้วย Public Name ( ชื่อที่ Client รู้จัก )
เพื่อให้ Client สามารถค้นหา Server หรือ Service นั้นจาก Naming Service เจอได้
หลังจากนั้น Client จึงร้องขอใช้บริการ Remote Server
Client นั้น สามารถเรียกใช้บริการของ Naming Service ได้ผ่านทาง Method ชื่อ
lookup() ซึ่งเป็นสแตติก Method ของคลาส Naming ซึ่ง Client
จะใช้ Method นี้ ในการค้นหาไปยัง Naming Service ว่ามี Remote Service
ที่ต้องการอยู่หรือไม่ โดย Method นี้จะอ้างไปยัง Naming Service โดยผ่านทาง
ชื่อโฮสต์, พอร์ต และชื่อของ Remote Service ที่ต้องการค้นหา ถ้าหากพบ Method นี้
จะคืนค่า Remote Reference ไปยัง Remote Service ซึ่ง Client สามารถ
เรียก Method ผ่านไปทาง Reference นั้น URL ที่ Client
ใช้ในการติดต่อไปยัง Java RMI รีจีสทรี จะอยู่ในรูปแบบดังนั้น
rmi://<host_name>[:<name_service_port>]/<service_name>
โดย host_name คือ Computer Name หรือชื่อที่ DNS ( Domain Name Service ) ในระบบอินเตอร์เน็ตรู้จัก
ส่วน name_service_port จำเป็นต้องระบุในกรณีที่ Naming Service นั้นทำงานอยู่บน Port อื่น ๆ นอกจาก Port 1099 ซึ่งเป็นค่า Default
3.4 การสร้างระบบของ Java RMI
ในหัวข้อนี้จะแสดงตัวอย่างการสร้างระบบออบเจ็กต์แบบกระจายด้วย Java RMI ที่ชื่อว่า
Converter Service เป็น Service จะทำการแปลง Integer ที่ Client ส่งมาให้
ให้กลายเป็น String แล้วส่งคืนกลับไปยัง Client และสร้างตัวอย่างของ Client ในการเรียกใช้ Service ดังกล่าว
การสร้างระบบ ออบเจ็กต์แบบกระจายด้วย Java RMI ตามระบบตัวอย่างที่กล่าวมานั้น มีขั้นตอนค่างๆที่ต้องทำดังต่อไปนี้ คือ
- สร้าง Interface สำหรับ Service
- สร้าง Remote Service จาก Interface ที่สร้างมา
- สร้าง Stub & Skeleton Class
- สร้าง Service Object ฝัง Server
- สร้างโปรแกรมสำหรับเป็น Client
- ติดตั้ง Service ไปยัง Java RMI และรันโปรแกรมเพื่อทดสอบ
การเตรียมการสำหรับตัวอย่างนี้คือสร้าง Folder ไว้สอง Folder สำหรับ
Source Code สองส่วน ส่วนแรกสำหรับ Server และส่วนที่สองสำหรับ Client โดยจะมี
ไฟล์หนึ่งเป็น Interface ที่จำเป็นต้องใช้สำหรับทั้ง Client และ Server
โดยที่เพื่อให้ง่าย ในขั้นตอนนี้เราจะใช้การ ก๊อบปี้ไฟล์ นั้นไปทั้งสอง Folder
3.5 ตัวอย่าง : การสร้างแอพพลิเคชั่น Java RMI เบื้องต้น
| คลาสที่ใช้สำหรับตัวอย่างนี้ |
| Common Classes |
ConvertService |
| Server Classes |
ConvertServer ConvertServiceImpl |
| Client Classes |
ConvertClient |
ตารางที่ 3-1 แสดงคลาสที่ใช้สร้างแอพพลิเคชั่น Java RMI เบื้องต้น
3.5.1 Remote Interface
Interface
นี้เป็นคอมมอน Interface ซึ่งทั้ง Client และ Server จะต้องเรียกใช้ได้ จึงต้องมี
คลาสนี้สำหรับ ทั้ง Client และ Server โดยที่ Server ที่ทำการแปลงอินทีเจอร์ เป็น
สตริงก์ควรจะมี Interface ดังนี้
import java.rmi.*;
public interface ConvertService extends Remote {
public String convert( int i ) throws RemoteException
}
แล้วทำการ คอมไพล์ Interface นี้ให้เป็น คลาสไฟล์ด้วยคำสั่ง
> javac ConvertService.java
ใน Interface นี้มีสิ่งที่น่าสนใจคือ
- จะต้อง extends java.rmi.Remote เพื่อบอกถึงการเป็น Remote Object สำหรับ Java RMI
- ในทุก ๆ Method ใน Interface จะต้อง throws จาก java.rmi.RemoteException
3.5.2 การสร้าง Remote Service
Remote
Service ก็คือออบเจ็กต์ ซึ่ง สร้างจาก Remote Interface ที่สร้างไว้นั่นเอง
ซึ่งการแยกส่วนระหว่าง Interface และส่วนอิมพลีเมนเทชันนั้น
สำคัญมากสำหรับทั้ง Java RMI และ Jini
มีหลายวิธีที่จะสร้าง Remote Service แต่วิธีที่ง่ายที่สุดน่าจะเป็นการ extends
คลาสนั้นด้วยคลาส java.rmi.server.UnicastRemoteObject ซึ่ง
คลาสนี้นั้นจะดูแลเรื่องการส่ง รีเฟอร์เรนซ์ของรีโมตออบเจ็กต์ไปยัง Server และ
Client และการเรียกใช้ Method ระหว่างสองส่วนนั้น
หรืออีกวิธีหนึ่งที่สามารถใช้ได้ก็คือการเรียกใช้ สแตติก Method ที่ชื่อ
exportObject() ของคลาส UnicastRemoteObject ตัวอย่าง การสร้าง Remote Service คือ
import java.rmi.*;
import java.rmi.server.*;
public class ConvertServiceImpl extends UnicastRemoteObject implements ConvertService {
public ConvertServiceImpl() {
}
//Called by the RMI infrastructure when the client
//invokes the remote method
public String convert( int i ) throws RemoteException {
return new Integer(i).toString();
}
}
แล้วทำการคอมไพล์คลาสนี้ให้เป็นคลาสไฟล์ด้วยคำสั่ง
> javac ConvertServiceImpl.java
ในคลาสนี้มีสิ่งที่น่าสนใจคือ
-
คอนสตรักเตอร์ Method ของ UnicastRemoteObject มีการ throws RemoteException
ด้วยดังนั้นคอนสตรักเตอร์ Method ของ ConvertServiceImpl จึงต้อง throw
RemoteException ด้วย
-
ออบเจ็กต์และ Method ของคลาสนี้ทำงานอยู่บน Server เพราะฉะนั้นรีซอร์สต่าง ๆ ที่ Server
ต้องการจะต้องมีให้ด้วย (เช่นคลาส Interface )
-
หากมี Client หลายโปรแกรมที่มาเรียกใช้ Method ชื่อ convert()
Client แต่ละตัวนั้นจะเชื่อมต่อเข้ามาในเธรดที่แยกจากกันเพราะฉะนั้น Method นี้
จะถูกเรียกให้ทำงานพร้อมกันจากหลาย Client ถ้าหาก Service
ที่ต้องการจะสร้างไม่ต้องการให้มีการทำงานที่ซ้อนกันจะต้องใช้ การทำ
ซิงโครไนเซชันเข้ามาช่วย
3.5.3 การสร้างสตับและสเกลเลตัน
การสร้างสตับและสเกลเลตันสำหรับ Remote Service
นี้ทำได้โดยการใช้ Java RMI คอมไพเลอร์ ซึ่งมีมาให้กับชุดของ JDK ที่ชื่อ rmic
เพื่อใช้ในการสร้างสตับและสเกลเลตันไฟล์ซึ่ง คอมไพเลอร์นี้จะใช้ในการ
คอมไพล์คลาสไฟล์ของ Remote Service ด้วยคำสั่ง
> rmic ConvertServiceImpl ( สำหรับ JDK 1.0 ขึ้นไป )
> rmic -v1.2 ConvertServiceImpl ( สำหรับ J2SE 1.2 ขึ้นไป )
ซึ่งคำสั่งนี้จะทำการสร้างไฟล์ที่ชื่อ ConvertServiceImpl_Stub.class ( Stub Class ) และ ConvertServiceImpl_Skel.class ( Skeleton Class แต่ไม่จำเป็นสำหรับ Java RMI ตั้งแต่ J2SE 1.2 ขึ้นไป )
3.5.4 การสร้าง Server สำหรับ Remote Service
Service ของ Java RMI จะต้องถูกสร้างขึ้นมาในโพรเซสของ Server จากนั้นจึงทำการ ลงทะเบียน
Service ไปที่ Naming Service เพื่อให้ Client สามารถเรียกใช้ได้ ด้วยสแตติก Method ชื่อ
rebind() ของคลาส Naming ซึ่งพารามิเตอร์เป็น URL สำหรับ Naming Service
และออบเจ็กต์ที่จะลงทะเบียน ตัวอย่างของ Server มีดังนี้
import java.rmi.*;
public class ConvertServer {
public ConvertServer() {
try {
ConvertService c = new ConvertServiceImpl();
Naming.rebind(rmi://localhost:1099/ConvertService,c);
}
catch( Exception ex ) {
System.out.println( Troble: + ex );
}
}
public static void main( String[] args ) {
new ConvertServer();
}
}
แล้วทำการคอมไพล์คลาสนี้ให้อยู่ในรูปของคลาสไฟล์ด้วยคำสั่ง
> javac ConvertService.java
3.5.5 การสร้างโปรแกรมสำหรับ Client
สิ่งที่
Client โปรแกรมจะต้องทำมีสองอย่างคือ ค้นหาออบเจ็กต์ของ Remote Service ที่ต้องการ
แล้วทำการเรียกใช้ Method ของ Remote Service นั้น การค้นหาออบเจ็กต์ของ Remote
Service นั้นสามารถทำได้อย่างง่ายๆโดยเรียกใช้ สแตติก Method ที่ชื่อ lookup()
ซึ่งเป็นของ คลาส Naming
ส่วนการเรียกใช้ Method ของรีโมตออบเจ็กต์นั้นก็สามารถทำได้เหมือนกับการเรียกใช้ Method ของโลคอลออบเจ็กต์ธรรมดา
ตัวอย่างของ Client คือ
import java.rmi.*;
public class ConvertClient {
public static void main( String[] args ) throws Exception {
ConvertService cs = (ConvertService)Naming.lookup(ConvertService);
try {
System.out.println(The result is +cs.convert(152));
}
catch( RemoteException ex ) {
System.out.println( Cant convert integer + ex );
}
}
}
ในการที่ Client จะสามารถทำงานกับรีโมตออบเจ็กต์ใด ๆ Client
จะเรียกการทำงานผ่านไปทางสตับของ รีโมตออบเจ็กต์นั้น ซึ่งจากตัวอย่าง เราจะต้อง
ก๊อบปี้ไฟล์ที่เป็นสตับของ ConvertServiceImpl ที่ชื่อ
ConvertServiceImpl_Stub.class มาใส่ไว้ใน classpath ของ Client ด้วย Client
จึงจะทำงานได้ แต่ในส่วนของการคอมไพล์นั้น Client ต้องการเพียง Interface
คลาสในการคอมไพล์เท่านั้น จึงต้องนำคลาส Interface มาใส่ไว้ที่ Directory ของ
Client ด้วยจากนั้นจึง คอมไพล์ Client ด้วยคำสั่ง
> javac ConvertClient.java
3.5.6 การเริ่มการทำงานของระบบ Java RMI
จากการที่ได้เตรียมการไว้ในตอนแรกว่าให้แยก ไดเรกทอรี่ระหว่างซอร์สโค้ดของ Client
กับซอร์สโค้ดของ Server ก็เพื่อจำลองสภาวะแวดล้อมให้เหมือนกับการอยู่ต่างที่กันใน
ระบบเครือข่ายโดยที่
ในส่วนของ Server จะต้องมีคลาสดังต่อไปนี้
- Conass เป็น Remote Service
- ConvertServiceImpl.class เป็นตัว Remote Service
- ConvertServiceImpl_Stub.class เป็นสตับของ Remote Service
- ConvertServiceImpl_Skel.class เป็นสเกลเลตันของ Remote Service
- ConvertServer.class เป็น Server ของ Remote Service
ส่วนในฝั่งของ Client จะต้องมีคลาสดังต่อไปนี้
-
ConvertService.class เป็น Remote Service
-
ConvertServiceImpl_stub.class เป็นสตับของ Remote Service ใช้ในการคุยกับ Service
-
ConvertClient.class
-
vertService.class ทำหน้าที่เป็น Client ที่เรียกใช้ Remote Service
วิธีการในการ เริ่มการทำงานของ Remote Service คือ
- เริ่มการทำงานของ Naming Service ที่ชื่อ rmiregistry ที่ฝั่ง Server
ที่ดีฟอลต์พอร์ต 1099 ด้วยคำสั่ง
server > rmiregistry
- เริ่มการทำงานของ Server ด้วยคำสั่ง
server > java ConvertService
- เริ่มการทำงานของ Client ด้วยคำสั่ง
client > java ConvertClient
ถ้าหากการทำงานไม่มีปัญหาอะไรก็จะได้ Output ดังนี้
client > The result is 152
3.6 การกระจายคลาสไฟล์โดยอัตโนมัติ
จากตัวอย่างที่ได้แสดงไว้ข้างต้นจะเห็นได้ว่า จะต้องมีคลาสที่ใช้สำหรับทั้ง Client
และ Server และ Client ก็ยังต้องการ คลาสบาง คลาสที่สร้างโดย Server อีกด้วย
ซึ่งวิธีการที่ใช้ในตัวอย่างนี้เราใช้การก๊อบปี้คลาสไปยังไดเรกทอรี่ที่ต้องการซึ่งวิธีนี้ก็สามารถทำได้
แต่ว่าในการนำไปใช้จริง คงจะเป็นเรื่องยากที่จะต้องคอย ก๊อบปี้ไฟล์ของ Server
ส่งไปยัง Client ถ้าหาก Client กับ Server อยู่ห่างไกลกัน ทาง
ผู้ออกแบบ Java RMI จึงได้ออกแบบส่วนขยายของ การทำ คลาสโหลดดิ้ง
โดยเพิ่มส่วนที่ทำให้สามารถ ดาวน์โหลดคลาสผ่านทาง FTP Server หรือ HTTP Server ได้
RMI
สามารถรองรับการทำ การโหลดคลาสระยะไกลโดยผ่านทาง RMIClassLoader ถ้าหาก Client
ทำงานอยู่บนระบบของ Java RMI แล้วระบบพบว่าจำเป็นต้องมีการ โหลดคลาสผ่านทาง
รีโมตโลเคชัน ระบบก็จะทำการเรียกไปยัง RMIClassLoader เพื่อทำการ โหลดคลาส
การโหลดคลาสของ Java RMI จะถูกควบคุมด้วย ค่าพารามิเตอร์จำนวนหนึ่งซึ่ง
พารามิเตอร์ต่าง ๆ เหล่านี้สามารถถูกตั้งค่าได้เมื่อ JVM
แต่ละตัวเริ่มทำงานด้วยคำสั่ง
> java [ -D<PropertyName>=<PropertyValue> ] + <ClassFile>
โดยที่ พารามิเตอร์ java.rmi.server.codebase นั้นถูกใช้สำหรับบอก URL ที่
RMIClassLoader ใช้ในการโหลดคลาสซึ่ง URL นี้จะชี้ไปยัง file:, ftp:, http:
ที่มีคลาสนั้นให้บริการอยู่ซึ่งออบเจ็กต์
อื่น ๆ ใช้ในการโหลดคลาสสำหรับออบเจ็กต์ที่ได้รับมาจาก JVM นั้น (ใช้กับการทำ
คลาสแคสท์ (Class Cast) สำหรับกระบวนการดีซีเรียลไลเซชัน)
หรือใช้สำหรับเรียกคลาสที่ต้องการมาใช้ เช่น Client จะเรียกใช้สตับคลาสของ Server
ก็สามารถทำโดยผ่าน RMIClassLoader ได้เช่นเดียวกัน
ตัวอย่างวิธีการใช้งาน RMIClassLoader เราสามารถทำได้โดยการ
-
เริ่มการทำงานของ Web Server (http server) ที่พอร์ตที่ต้องการ เช่น 8080
-
นำ คลาสที่ต้องการจะทำการ โหลดผ่าน RMIClassLoader ไปใส่ไว้ที่ Web Server
-
การเริ่มการทำงานของ JVM ที่จะต้องการให้ใช้ RMIClassLoader
โดยกำหนดพารามิเตอร์ให้กับ JVM ดังนี้
server > java Djava.rmi.server.codebase=http://your_host:8080 ConvertService
หากเรานำ คลาส ConvertServiceImpl_Stub.class ไปใส่ไว้ที่ http://your_host/
เราก็ไม่จำเป็นจะต้องก๊อบปี้คลาสนั้นไปใส่ไว้ในไดเรกทอรี่เดียวกับ ConvertService
โดยที่ RMIClassLoader จะทำการโหลดคลาส ConvertServiceImpl_Stub.class
มาให้เองโดยอัตโนมัติ
Last update : June 17, 2009 17:00 ( Thailand )
Apple, Mac, iMac, iPhone and iPod are trademarks of Apple, Inc.
Jini, Java and all Java-based are trademarks of Sun Microsystems, Inc.
JiniSoft Corporation
Copyright @ 1990 - 2009 Mr. Roongroj Rojanapo ( )
99/2 Soi Ramindra 14, Ramindra Road, Bangkane, Bangkok 10230, Thailand
|