Thiết lập môi trường triệu gọi từ xa

Để thực hiện được việc triệu gọi từ xa thì ta phải chạy chương trình ở trên cả hai máy, máy khách và máy chủ. Những thông tin cần thiết cũng phải được cài đặt tách biệt ở hai phía, máy khách và máy chủ. Tuy nhiên, không nhất thiết phải có hai máy tính riêng biệt. Nhờ có máy ảo Java, khi mở cửa sổ DOS-Prompt (môi trường DOS dưới Window) để chạy chương trình Java, chuông trình này được xem như chạy trên một máy (ảo) JVM độc lập. Do đó, nếu hai chương trình Java chạy ở trong hai cửa sổ riêng thì có thể xem như là chúng thực hiện trên hai máy khác nhau.

Ví dụ 2.1. Chúng ta hãy bắt đầu từ một ví dụ đơn giản, chương trình trên máy chủ tạo ra hai sản phẩm: lò nướng bánh và lò VI sóng thuộc lóp Product. Sau đó chạy một chương trinh trên máy khách để xác đinh thông tin về sản phẩm, giá bản của từng sản phẩm và in ra cho khách hàng.

Lưu ý: Những ví dụ này có thể chạy ờ trên một máy đơn cũng như trên từng cặp máy kết nối mạng. Chúng ta có thể thực hiện theo cả hai kịch bản. Nhưng ngay cả khi bạn chạy trên một máy, thì cũng cẩn phải đảm bảo rằng các dịch vụ mạng là sẵn sàng. Đặc biệt phải chắc chắn rằng TCP/IP được hỗ trợ.

1. Trên máy phục vụ (Server)

i) Thiết lập giao diện từ xa

Trong Java, đối tượng từ xa là thể hiện của một lóp cài đặt giao diện Remote . Tất cả các phương thức cùa các giao diện lừ xa phải được khai báo public để các máy JVM khác cỏ thể gọi được. Các giao diện từ xa phải đảm bảo những tính chất sau:

  • Giao diện tù xa phải khai báo
  • Giao diện từ xa kế thừa j ava. rmi . Remote .

“ Mọi phương thức phải khai bảo với mệnh đề throws để kiềm soát các ngoại lệ

java.rmi.RemoteException.

  • Kiểu dữ liệu của các đối tượng từ xa được truyền đi và giá trị nhận về phải được khai báo như là kiểu giao diện Remote, không phải là lớp.

Chúng ta trờ lại ví dụ cần tạo ra một cặp đối tượng sản phẩm tại máy chủ (máy phục vụ) và máy khách. Chương trình trên máy khách cũng phải biết được nó cần cái gì ờ những đối tượng trên máy phục vụ. Điều này thực hiện được nểu cả hai máy chia sẻ với một giao diện từ xa.

interface Product //Chia sẽ bởi Client và Server

extends Remote{ public String getDescription() throws RemoteException; public double getPriceO

throws RerrioteException;

}

Tất cả các phương thức của giao diện từ xa phải khai báo với throws RemoteExceptlon vì khi triệu gọi từ xa sẽ có rất nhiều nguyên nhân làm cho nó thất bại, ví dụ, máy chủ, kết nối mạng không sẵn sàng, và nhiều vấn đề không binh thường, ngoại lệ khác gập phải trên mạng.

(ii) Xây dựng các lớp cài đặt các giao diện từ xa

Ở phía máy chủ, chúng ta phải xây dựng lớp cài đặt các phương thức được khai báo trong giao diện từ xa.

Nói chung, các lớp các cài đặt đối tượng tù xa cần phải:

  • Khai báo rằng nó cài đặt ít nhất một giao diện từ xa
  • Đinh nghĩa toán tử tạo lập đối tượng từ xa
  • Cài đặt các phương thức đề có thể triệu gọi được từ xa.

public class Productlmpl //Server

extends UnicastRemoteObject implements Product! public Productlmpl (String s, double p) throws RsnoteException { descr = s; price = p;

}

public String getDescription() throws RemoteException { return descr ;

}

public double getPrice() throws RemoteException { return price ;

}

private string descr; private double price;

Lớp Productlmpl cài đặt hai hàm getDescription (), getPriceO cho phép gọi được từ xa trong chương trình khách.

Tất cả các lớp ở Server phải kể thừa từ lớp RemoteServer có ở trong gói java, mi . server. Nhưng RemoteServer là lớp trừu tượng, nó định nghĩa các cơ chế cơ sở để trao đổi tin giữa các đối tượng dịch vụ và các đại diện của chúng từ xa. Lớp

UnicastRemoteOb j ect là lớp con cùa RemoteServer .

Lớp UnicastRemoteObj ect được sử dụng để tạo ra các đối tượng ờ trên mảy chủ. Đây là lóp cơ sở để xây dụng các lớp ứng dụng trao đổi thông tin từ xa trên máy chù. Ngoài ra, ta có thể sử dụng lóp cơ sờ MulticastRemoteOb j ect để kế thừa, tạo ra những lóp ứng dụng chạy trên nhiều máy chủ đồng thời.

Lưu ý: Khi sử dụng RMI, vẩn đề đặt tên cho các lóp, giao diện là cần phải cẩn trọng. Để cho phù hợp, ta nên thực hiện theo những qui ước đặt tên như sau:

Bởi vì đối tượng xuất ra thường gặp phải ngoại lệ java, rmi . RemoteExcept ion, nên ta phải định nghĩa toán tử tạo lập với mệnh đề throws RemoteException, thậm chí cả khi toán tử tạo lập không làm gì. Nếu ta quên toán tử tạo lập thì chương trình dịch javac sẽ thông báo Lỗi.

(iii) Cài đặt các phương thức từ xa

Lớp cài đặt các đối tượng từ xa phải cài đặt tất cả các phương thức đã dược khai báo trong giao diện từ xa. Ở ví dụ của chúng ta, phương thức từ xa phải cài đặt là:

public String getDescription()

throw? RemoteException{ return descr;

}

public double getPriced

throws RemoteException{ return price;

}

Các tham số, các giả trị trả lại của phương thức tù xa có thể là kiểu dữ liệu bất kỳ của Java, kể cà các đối tượng.

Lưu ý: Một lớp có thể định nghĩa những phương thức không được khai báo trong giao diện từ xa, được gọi là phương thức cục hộ. Những phương thức cục bộ chì được gọi trong cùng một ứng dụng (cùng một JVM), không triệu gọi từ xa được.

Sau khi hoàn tất lớp cài đặt, ta cần tạo ra các đại diện của lớp ProductImpl để mã hoá các tham số và nhận lại các kết quả của các lần triệu gọi phương thức từ xa. Người lập trình không sử dụng những lớp này trực tiếp và vì vậy cũng không phải tự viết chúng. Bộ công cụ rmic sẽ sinh ra chúng một cách tự động, ví dụ

C:\j2sdkl.4.0\bin>rmic -vl.2 ProductImpl

Kết quả là hai tệp lớp: ProductImpl_Stub.class và ProductImplJBke 1 .class đuọc sinh ra. Đối với Java 2 SDK thì tệp thứ hai không còn cần thiết nữa. Nếu lớp đặt trong một gói thì gọi rmi c với tên của gói đó.

(iv) Xác định các đối tượng dịch vụ

Để truy cập được đối tượng từ xa trên máy phục vụ, khách hàng cần có được đối tượng đại diện tại nơi đó. Khách yêu cầu đối tượng đó như thế nào? Phương thức chung là gọi phương thức từ xa của một đối tượng phục vụ và tạo ra một đối tượng đại diện để nhận kểt quả trả lời.

Hệ thống RMI cung cấp một bộ đãng ký (RMI registry) đối tượng từ xa để ta kết hợp với tên được thiết lập theo URL dạng “//host/objectname” giúp ta xác định được đối tương phục vụ. Tên gọi là dãy các ký tự (xâu) xác định duy nhất.

// Server

Productlmpl pl = new ProductImpl(“Lò nướng bánh”, p); Naming. bind (“teaster”) ;

Đối tượng pl được ghi danh với tên gợi nhớ “teaster” bằng hàm Naming. bind () , hoặc hàm Naming. rebind () .

java.rmi.server.Naming                                                                                              API

  • static Remote lookup(String url)

Tìm đến đối tượng từ xa theo địa chỉ url. Nếu chưa có đối tượng được đăng ký thi phát sinh ngoại lệ NotBoundException.

  • static void bind(String name, Remote obj)

Ghép (đóng gói) name với đối tượng từ xa ob j. Nếu đối tượng đó đã có trong gói thì phát sinh ngoại lệ AlreadyBoundException.

  • static void unbind(String name)

Mở để lấy name ra khỏi gói. Nếu name không có trong gói thì phát sinh ngoại lệ

NotBoundException.

  • static void rebind(String name)

Ghép (đóng gói) name với đối tượng từ xa obj. Cho phép thay thế những name đã được đóng gói.

  • static StringH list (String url)

Lẩy ra một danh sách các tên đối tượng (xâu) đã được đăng ký ờ địa chi url.

Chương trình khách truy cập đến đối tượng phục vụ bằng cách chi ra tên cùa dịch vụ và tên đối tượng, sau đó ép về kiểu cùa giao diện từ xa như sau:

// Client

Product p = (Product )Naming.lookup(“mii://yourserver. com/teaster”); Đối tượng p ở trên máy khách muốn triệu gọi phương thức từ xa cùa đối tượng có tên được đăng ký là “teaster’’ ờ máy phục vụ thì gọi hàm ISkráng.lookup0 để truy tìm tham chiếu tới đối tượng đó từ xa.

ÍM[ URL bắt đầu bằng “rmi:/” sau đó là Server, số hiệu cổng để lẳng nghe (tuỳ chọn), dấu 7’ và sau đó là tên gọi của đối tượng triệu gọi từ xa. Ví dụ:

nni: //localbost: 99/teaster Số hiệu cổng mặc định là 1099.

Chương trình ở máy phục vụ Server được viết đầy đủ như sau.

// Product.java: giao diện từ xa Product import j ava.rmi.*;

public interface Product extends Remote! public String getDescription() throws RemoteException; public double getPrice()

throws RemoteException;

>

// Productlmpl.java: cài đặt lóp ProductImpl ờ mảy Server import java.rmi.*; import java.rmi.server.*; public class Productlmpl extends

UnicastRemoteObj ect implements Product{ public Productlmpl(String s, double p) throws RemoteException{ descr = s; price = p;

1

public String getDescription() throws RemoteException{ return descr;

}

public double getPrice()

throws RemoteException{ return price;

}

private String descr; private double price;

}

// ProductServer.java: Chuơng trình phục vụ tạo ra 2 sản phẩm: Lò nướng bánh

// (có tên là teaster) và lò vi sóng (có tên là microwave).

import java.rmi.*;

import java.rmi.server;

import sun.applet.*;

public class Productserver{

public static void main(String args[]){

try [

System.out.printIn(“Cài đặt dịch vụ …”); Productĩmpl pl = new Productlmpl(“Lò nưóng bánh”, 200.5); Productlmpl p2 = new ProductImpl(“Lò vi sóng”, 350.2); System.out.println(“Đăng ký dịch vụ …”);

Naming.rebind(“teaster”, pi) ;

Naming.rebind(“microwave”, p2);

System.out.println{“Cho máy khách triệu gọi .-.”);

}catch(Exception e){

System.out.println(“Error:         ” + e);

}

}

Tất cả các giao diện, lớp trên có thể gộp vào thành một gói. Sừ dựng j avac để dịch chúng và tạo ra các tệp lóp ( class) tương ứng trên thư mục hiện thời.

(v) Bộ đăng ký RM1 registry

Chương trình dịch vụ của chúng ta hoàn toàn chưa sẵn sàng thực hiện, vấn đề chính cùa chúng ta là cài đặt đối tượng cùa Product Imp 1 trên một máy và ở một máy khác (chương trình khác) muốn gọi phương thúc getDescrìption() để biết được thông tin mô tả và giá bán của các sản phẩm có trên chương trình phục vụ. Như đã nói trước, ta không thể gọi trực tiếp hàm của Productlmpl mà phải thông qua các lóp trung gian stub và Skel (không cần thiết đối với Java 2 SDK). Ta thực hiện điều này nhờ trinh biên dịch rmic như đã nêu ở trên.

Hơn nữa, máy khách muốn triệu gọi được phương thức ờ xa thì trước tiên nó phải liên lạc được với bộ đăng ký RMT registry của máy ở xa đó. Các hàm giao diên cùa Java thực hiện nhiệm vụ này được gọi là các hàm giao diện API JNDI. Các hàm JNDI ở máy khách sẽ liên lạc với RMI registry của máy chủ để nhận tham chiếu của đối tương trong khi các hàm JNDI ờ máy chủ lại có nhiệm vụ đàng ký tên đối tượng với RMI registry. Để khới động RMI registry dưới nền Window 95 hoặc NT thì phải thực hiện

start rmiregistry [port]

ở cửa sổ lệnh của DOS Prompt hoặc ờ hộp thoại Run, trong đó port là số hiệu cổng giao diện để chờ phục vụ và trả lời kết quả. Và tất nhiên, khi thiết kế các đối tượng RMI, cụ thể là các đối tượng cài đặt chi tiết trên máy phục vụ, ta phải ghi nhớ lấy số hiệu cổng này cho khớp. Nếu không chỉ định số hiệu cổng thì RMI registry ngầm định lắng nghe ở Cổng 1099. Để khen động registry ờ một cổng khác, thì phải chì ra số hiệu cùa cổng đó trên dòng lệnh. Ví dụ, đăng ký ờ cổng 2001:

start rmiregistry 2001

Một vấn đề khác đáng quan tâm ở đây nữa là RMI registry không cho phép đăng ký hai đối tượng cùng tên. Muốn chình sửa lại hệ thống chưorng trình triệu gọi phương thức từ xa, ta phải, hoặc là khời động lại chương trình RMI Registry, hoặc là ngay từ đầu khi thiết kế chương trình Server cùa đối tượng, ta sử dụng phương thức rebind () thay vi phương thức bind () để đăng ký với RM ĩ registry của máy phục vụ.

(vi) Chi tiết về RMI registry và các cách tự đăng ký đối tượng

Bộ đăng ký RM1 RMI registry đã được đề cập trên đây như một dịch vụ tìm kiếm đổi tượng. Các đối tượng phục vụ muốn chương trình khách truy cập được từ xa thì phải đăng ký với RMI registry. Bộ đăng ký này là một chương trình dịch vụ chạy ờ hậu trường, lắng nghe ờ một cổng có số hiệu đã xác định. Hiện tại Java yêu cầu một máy ảo JVM chạy RMI registry và một máy JVM chạy chương trình Server (trên cùng một máy chủ).

Một dịch vụ RMI registry có thể tiếp nhận và quản lý cùng lúc nhiều đối tượng dịch vụ khác nhau. Java cho phép liên lạc với bộ đãng ký RMI registry để lấy về danh sách các đổi tượng chủ mà nó đang quản lý thông qua phương thức list () của đối tượng đã đãng ký như ví dụ dưới đây.

//ListReg.java

import java.rmi.registry, *;

public class ListReg {

public static void main(String[] args) throws Exception!

// Địa chì cùa máy nơi mà RMI Registry đang chạy

String hostName = “localhost”;

System.out.printIn(“Connecting registry…”);

// Kết nối với bộ đăng ký

Registry reg = LocateRegistry.getRegistry(hostName);

// Lay về danh sách các đối tượng do RM1 Registry đang quàn lý

String objListf] = reg.listO;

System.out.println(“Resgitry object: “);

for (int i = 0; ì < objLìst.length; i++)

System.out.prtinln(obj List [1]);

}

Java cho phép nhà lập trinh tự tạo bộ đãng ký cho riêng mình mà không cần dùng đển rmiregistry.exe. Để tạo bộ đăng ký và tự đăng ký đối tượng, ta sử dụng phưomg thức tĩnh createRegistry () của lóp LocateRegìstry.

//CalculatorSetup java

import i ava.rmi .server.*;

import j ava.rmi.*;

import java.rmi.registry.*;

public class ProductSetup {

public static void main(String[] args) throws Exception {

// Tạo bộ đăng ký registry

LocateRegistry.createRegistry(2510);

// Tạo đối tuợng

String name = “Máy in”; double p = 150.0;

Productlmpl product = new Productlmpl(name, p);

// Yêu cầu JVM nhận dạng product

UnicastRemoteObject.exportobject(product);

// Đãng ký product với dịch vụ truy cập

System.out .println (“registering object …”);

Naming.rebind(“rmi://localhost:2510/printer”, product);

System, out.println (“waiting for client request

}

}

Biên dịch và cho thực thi chưorng trinh. Khi chương trình hoạt động, nó tương đương với hai chương trình trước kia: rmiregistry.exe và Product Server.

2. Trên máy khách (Client)

Bây giờ ta hãy viết chương trình ở trên máy khách (chương trình khách) để yêu cầu chương trình phục vụ cung cấp những thông tin về các sản phẩm từ các đối tượng đã đăng ký.

Với Java, tất cả các thao tác kết nối và sao chép các tệp tin từ một máy tính về máy khách đều phả) thông qua lóp bảo vệ gọi là RMISecurityManager.

Ví dụ, nếu bạn muốn cho chương trình khách ProductClient có thể nạp tự động Product Imp l_s tub. class từ Webserver, thỉ phải thiết lập lại cơ chế bảo vệ an ninh ờ máy khách.

System. setSecurìtyManager (new PMISecurítỹManager 0 ) ;

Hệ thống an mnh RMISecurìtỵManager sẽ sử dụng các quyền được thiết lập trong tệp chính sách j re\lib\securityX j ava .policy để kiểm soát việc kết nối từ xa (j re là thu mục chứa các tài nguyên tạo nên môi trường thực thi của Java).

Để chương trình khách kết nối được với RMI registry và đối tượng phục vụ, ta cần sự hồ trơ của tệp chính sách (tệp thường cỏ đuôi .policy). Ở đây, tệp chính sách cho phép một chương trình ứng dụng tạo ra sự kết nối mạng qua các cổng có sổ hiệu ít nhất là 1024. Cổng RMI mặc định là 1099 và Server có thể sử dụng các cồng > 1024. Ta có thể soạn tệp cl ient.pol icy cho phép kết nối các cổng > 1024:

grant {

permission java.net.SocketPermissíon              1024-65535″, “connect”;

}

Khi thực hiện chương trình khách, ta phải sử dụng chính sách (client .policy) (chi tiết xem [2]).

java ProductClient -Djava.security.pollcy=client.policy Chương trình ở máy khách được viết như sau.

// ProductClient.java: lóp Productclient trên máy khách

import java.rmi.*; import j ava.rmi.server.* ; public class ProductClient{

public static void main(String args[]){

System.setSecurityManager(new RMISecurityManager() ) ; String url = “rmi:/Aocalhost/”;

String name = “”; double price = 0.0;

// Thay bang “rmd : //yourserver . com/”

// Khi Server chạy trên máy từ xa yourServer . com I try {

Product cl = (Product)Naming.lookup(url + “teaster”); Product c2 = (Product) Naming. lookup (url + “microwave”); name = cl.getDescription(); price = cl.getPrice();

System.out.println(name + “, giá bán; $ ” + price); price = c2.getPrice(); name = c2.getDescription();

price = c2.getPrice();

System.out.println(name + “, giá bán: $ ” + price);

}catch(Exception e){

System.out.printin(“Error ” + e) ;

}

System.exit(0);

}

Biển tuỳ chọn CODEBASE

Như ta đã biết, khi thực thi, một chương trình Java dựa vào biến môi trường CLASSPATH để tìm các tệp tin mã byte code : *.0103 3. cố nhiên, CLASSPATH giữa máy chủ và máy khách hoàn toàn có thể được thiết lập khác nhau. Ta phải biết rõ, các chưong trình trong hệ thống muốn thực thi được thì cần phải có CLASSPATH phù hợp, chinh xác hơn là cần cung cấp những tệp lớp class, tệp thực thi ớ thư mục nào, ờ đâu để có thể thực thi chúng.

Chẳng hạn, trong ví dụ của chúng ta, máy phục vụ cần phải có các tệp tin mã byte code ờ thư mục C:\server\product\Product.class,                                  ProductImpl.class,

ProductIrnpl_Stub. class, ProductIrrpl_Skel. class (tệp này không cần thiết ờ Java 2 SDK), và ProductServer. class. Trong khi đó, tại máy khách ta chi cần có hai tệp tin ở thư mục D:\Client\product\ProductClient.class và ProductImpl_Stub. class, còn bộ chương ừình JDK được cài đặt ở thư mục C:\j2sdkl.4.0\bin.

Thực tế, chúng ta thấy, cách làm việc ừên là chưa thể hiện rõ tính phân tán đối tượng một cách tnệt để. Thật vậy, khi mà lớp đối tượng tnệu gọi từ xa phải cập nhật thì các lớp giao diện trung gian Skel và stub cùa nó cũng phải được cập nhật theo. Tuy nhiên, ờ phía máy khách cũng phải cập nhật phiên bàn stub mới này, điểu này dẫu sao cũng gây nên ít nhiều bất tiện. Công nghệ Java cung cấp giải pháp cho phép tự động nạp lớp stub từ xa thông qua tùy chọn CODEBASE khi đăng ký đối tượng với RMI registry trên máy chù. Chẳng hạn, ta đăng ký ProductServer như sau:

c:\j2sdkl.4.0\bìn>java -Djava.rmì.server.codebase=

“http://192.168.0.9/rmi/product/” ProductServer

Khi đãng ký như vậy, Server cùa chúng ta (ỏ đây là máy có địa chì IP là 192.168,0.9), ngoài RMI registry đang hoạt động, cần phải chạy thêm dịch vụ Web, và phải bảo đảm là tại địa chị http://192.168.0,9/rmi/product/ thl luôn có tập tin mã byte code _Stub.class. Bằng cách này, nhà cung cấp đối tượng ứiệu gọi từ xa chi cần cung cấp tệp tin mã byte code của đối tượng mà thôi. Và, khi máy khách có yêu cầu RMI registry trả về tham chiếu của đối tượng, nếu máy khách chưa có lóp Stub thì RMI registry sẽ hướng dẫn máy khách tự động nạp lớp này từ địa chỉ xác định trong tùy chọn CODEBASE.

Trong ví dụ 2.1, ta giả sử tất cả các tệp Product*.* và client.policy được đặt ở D:\user\product, còn Java 2 SDKcài đặt ờ C: \ j 2sdkl .4.0. Ta thực hiện các bước lần lượt như sau:

  1. Dịch tất cả các tệp nguồn Java bắt đầu bằng Product

D:\user\product>C:\j2sđkl.4.0\bin\javac Product*.java

  1. Tạo ra các lóp trung gian

D:\user\product>C:\j2sdkl.4.0\bin\rmic -vl.2 Productlrnpl

  1. Khởi động bộ đăng ký RMI registry

D: \user\product>start C:\j2sdkl.4.0\bin\rmiregistry

  1. Bẳt đầu thực hiện chuông trinh phục vụ

D:\user\product>start C:\j2sdkl.4.0\bin\java ProductServer

  1. Thực hiện chương trình khách

D:\user\product>C:\j2sdkl.4.0\bín\java –

Dj ava.security.policy=client.policy ProducClient

Ket quà sẽ in ra:

Lò nướng bánh, giá bán: 200.5 $

Lò vi sóng, giá bán: 350.2 $

Lưu ỷ: Ta có thể thiết lập biển môi trường bằng cách đặt đường dẫn để khi thực hiện không cần phải chi định như trên, vi dụ

set classpath=D: \server\product; D: \client\prođuct; c: \j 2sdkl. 4. Q\bin

3. Triển khai ứng dụng Web

Triển khai một ứng dụng mà ta sử dụng RMI thì phải thận trọng vỉ nhiều vấn đề có thề nảy sinh. Các bước thực hiện ờ trên tạo ra nhiều tệp lớp (đuôi .class) tách biệt và chúng có thể được đặt ờ ba thư mục con: server, download và Client.

  • Thư mục server chứa tất cả các tệp cần thiết đế chạy chương trình ờ Server. Trong ví dụ nêu trên có các tệp lớp: ProductServer.class, Product.class, Productlmpl.class,ProductImpl_Stub.class.
  • Thư mục download chứa tất cả các tệp sẽ được nạp về máy khách cũng như những lóp phụ thuộc. Trong ví dụ ờ trên, ta cần bả sung Product. class, ProductImpl_stub.class vàothưmục
  • Cuối cùng ờ thư mục Client chứa tất cả các tệp cần thiết để bắt đầu chạy chương trình Trong ví dụ ờ trên, đó là các tệp lớp: ProductCllent.class, Product.class và client.policy.

Giả sử Web Server được khởi động trên máy tinh của bạn. Bạn cũng có thể nhận được dịch vụ đó từ ftp://iava.sun.com/pub/idkl .1/rmi/class-server. zip. Dịch vụ này tương đối dễ cài đặt và có đù các chức năng hỗ trợ các tệp lớp.

+ Trước tiên, chuyển thư mục download vào thư mục tư liệu của Web Server.

+ Sau đó, soạn thảo lại tệp client.policy. Nó phải cho phép chương trình khách những quyền sau:

  • Kết nối qua các cổng 1024, đến được với RMI registry và những cài đặt ở Server.
  • Kết nối với cổng HTTP (thường là 80) để nạp các tệp lớp trung gian
  • Tệp policy cấp quyền kết nối mạng, sau khi được thay đổi và có dạng:

grant{

permission java.net.SocketPermission 1024-65535″, “connect”; permission java.net.SocketPermission “*;80”, “connect”;

} ;