RMI Example A Remote Account Interface (filename: Account.java)

advertisement

RMI Example

A Remote Account Interface (filename: Account.java)

} import java.rmi.Remote; import java.rmi.RemoteException; public interface Account extends Remote {

public String getName() throws RemoteException;

public float getBalance() throws RemoteException;

public void withdraw(float amt) throws RemoteException;

public void deposit(float amt) throws RemoteException;

public void transfer(float amt, Account src) throws RemoteException;

Implementation of the Remote Account Interface ( filename:

AccountImpl.java)

import java.rmi.server.UnicastRemoteObject; import java.rmi.RemoteException; public class AccountImpl extends UnicastRemoteObject implements Account {

private float balance = 0;

private String name = "";

// Constructor creates a new account with the given name

public AccountImpl(String aName) throws RemoteException {

name = aName;

}

public String getName() throws RemoteException {

return name;

}

public float getBalance() throws RemoteException {

return balance;

}

//Withdraw some funds

public void withdraw(float amt) throws RemoteException {

balance -= amt;

//Ensure balance never drops below zero

balance = Math.max(balance, 0);

}

//Deposit some funds

public void deposit(float amt) throws RemoteException {

balance += amt;

}

//Transfer some funds from another (remote) account into this one

public void transfer(float amt, Account src) throws

RemoteException {

src.withdraw(amt);

this.deposit(amt);

}

}

The utility class, RegAccount (filename: RegAccount.java)

//Utility class, RegAccount, creates an AccountImpl object and then

//binds it to a name in the local registry using the java.rmi.Naming

//interface. After it's done registering the object, the class goes

//into a wait(), which allows remote clients to connect to the remote

//object. import java.rmi.Naming; import java.rmi.RMISecurityManager; public class RegAccount {

public static void main(String argv[]) {

try {

//install a security manager

System.setSecurityManager(new

RMISecurityManager());

//make an Account with the given name

AccountImpl acct = new AccountImpl("JohnAdams");

//register it with the local naming registry

Naming.rebind("JohnAdams", acct);

System.out.println("Registered account");

}

catch (Exception e) {

e.printStackTrace();

}

}

}

The client (filename: AccountClient.java)

//The client first looks up the remote Account object using the

//java.rmi.Naming interface and then calls the deposit method on the

//Account object. import java.rmi.Naming; import java.rmi.RMISecurityManager; public class AccountClient {

public static void main(String argv[]) {

// set the RMI Security Manager, in case we need to load remote

// classes

System.setSecurityManager(new RMISecurityManager());

String url = "rmi://osprey.unf.edu/"; // server

try {

// Lookup account object

Account johnAcct =

(Account)Naming.lookup(url + "JohnAdams");

//Make a deposit

johnAcct.deposit(10000);

//Report results and balance

System.out.println("Deposited $10000 into account owned by " +

}

johnAcct.getName());

System.out.println("Current balance now is: $" +

johnAcct.getBalance());

}

catch (Exception e) {

System.out.println("Error looking up account");

e.printStackTrace();

}

System.exit(0);

}

Policy file needed by the client(filename:rmi policy.txt)

// The default Java security policy does not allow all the network

// operations needed to dynamically load remote classes (e.g. dynamically

// load the stub required by the client). This policy grants the network

// permissions needed.

// It gives the RMI object server machine (in this case osprey.unf.edu)

// permission to open connections to the local machine

// (i.e. to the client machine).

// To run the client:

// java -Djava.security.policy=rmipolicy.txt AccountClient grant {

permission java.net.SocketPermission "osprey.unf.edu", "accept,connect";

};

Policy file needed by the server (filename:rmipolicy1.txt)

// The default Java security policy does not allow all the network

// operations needed to dynamically load remote classes.

//This policy grants the network permissions needed.

// It gives any client machines permission

// to open connections to the RMI Server machine using port numbers

// 1024-65535.

// This would be necessary if the client were to dynamically load classes

// to the server, hence invoking the RMISecurityManager. If the client is

// not going to load classes to the RMI server, then the RMI server need

// not implement the RMISecurityManager. In that case, this security

// policy file is not needed.

// To run the server

// java -Djava.rmi.server.codebase=http://osprey.unf.edu/~sahuja/rmi/

// -Djava.security.policy=rmipolicy1.txt RegAccount grant {

permission java.net.SocketPermission "*:1024-65535", "accept,connect";

};

Commands needed to run the RMI Example

Compiling the source code files

The commands are: javac Account.java javac AccountImpl.java javac RegAccount.java javac AccountClient.java

Generating the stub and skeleton using the rmi compiler

The command to do this is: rmic AccountImpl

If you want the stub and skeleton to reside in the dir /usr/local/classes, you can run the command using the –d option: rmic –d /usr/local/classes AccountImpl

Starting the RMI registry

The command to do this is: rmiregistry 5000 &

Without the port argument, the RMI registry listens on port 1099. Once the RMI registry is running on a host, you can register remote objects with it.

Running the server

The command to run the server is: java -Djava.server.rmi.codebase=http://osprey.unf.edu/~sahuja/rmi/

-Djava.security.policy=rmipolicy1.txt RegAccount

In this example the URL is http://osprey.unf.edu/ and so we have to ensure that an HTTP server is running on osprey.unf.edu and that the necessary class files are in the rmi subdir. Also make sure that the necessary class file (e.g. the AccountImpl stub class) is in the rmi sub-dir. The RMIClassLoader uses the codebase property to determine the URL to the specified host where the needed classes are.

If the server does not need a RMISecurityManager then the command to run the server is: java -Djava.server.rmi.codebase=http://osprey.unf.edu/~sahuja/rmi/ RegAccount

Running the client

The command to run the client is: java -Djava.security.policy=rmipolicy.txt AccountClient

Download