Remote Method Invocation (RMI)
5.5 RMI Security
*/
Bank2 temp =
(Bank2)Naming.lookup("rmi://" + HOST + "/Account" + acctNum[i]);
//Now invoke the methods of the interface to //display details of associated account…
System.out.println("\nAccount number: "
+ temp.getAcctNum());
System.out.println("Name: "
+ temp.getName());
System.out.println("Balance: "
+ temp.getBalance());
} }
catch(ConnectException conEx) {
System.out.println(
"Unable to connect to server!");
System.exit(1);
}
catch(Exception ex) {
ex.printStackTrace();
System.exit(1);
} } }
Output for this client will be exactly as shown in Fig. 5.5 for Method 1 .
govern applets. Without such an object, a Java application will not even attempt to load classes that are not from its local fi le system.
Though the security policy can be modifi ed by use of the Java utility policytool , this can be done only for individual hosts, so it is probably more straightforward to write and install one’s own security manager. There is a default RMISecurityManager , but this relies on the system’s default security policy, which is far too restrictive to permit the downloading of class fi les from a remote site. In order to get round this problem, we must create our own security manager that extends RMISecurityManager . This security manager must provide a defi nition for method checkPermission , which takes a single argument of class Permission from package java.security . For sim- plicity’s sake and because the complications involved with specifying security poli- cies go beyond the scope of this text, we shall illustrate the procedure with the simplest possible security manager—one that allows everything! The code for this security manager is shown below.
import java.rmi.*;
import java.security.*;
public class ZeroSecurityManager
extends RMISecurityManager {
public void checkPermission(Permission permission) {
System.out.println("checkPermission for : "
+ permission.toString());
} }
As with all our associated RMI application fi les, this fi le must be compiled with javac . The client program must install an object of this class by invoking method setSecurityManager , which is a static method of class System that takes a single argu- ment of class SecurityManager (or a subclass of SecurityManager , of course). For illustration purposes, the code for our HelloClient program is reproduced below, now incorporating a call to setSecurityManager . This call is shown in emboldened text.
import java.rmi.*;
public class HelloClient {
private static fi nal String HOST = "localhost";
public static void main(String[] args) {
//Here's the new code…
if (System.getSecurityManager() == null) {
System.setSecurityManager(
new ZeroSecurityManager());
} try {
Hello greeting =
(Hello)Naming.lookup(
"rmi://" + HOST + "/Hello");
System.out.println("Message received: "
+ greeting.getGreeting());
}
catch(ConnectException conEx) {
System.out.println(
"Unable to connect to server!");
System.exit(1);
}
catch(Exception ex) {
ex.printStackTrace();
System.exit(1);
} } }
When executing the server, we need to specify where the required .class fi les are located, so that clients may download them. To do this, we need to set the java.rmi.
server.codebase property to the URL of this location, at the same time that the server is started. This is achieved by using the -D command line option to specify the setting of the codebase property. For example, if the URL of the fi le location is http://java.
shu.ac.uk/rmi/ , then the following line would set our HelloServer program running and would set the codebase property to the required location at the same time:
java -Djava.rmi.server.codebase=http://java.shu.ac.uk/
rmi/ HelloServer
It is very easy to make a slip during the above process that will cause the application to fail, but coverage of these problems goes beyond the scope of this text.
Exercises
5.1 Using class Result (shown below) and making the minor modifi cation that will ensure that objects of this class are serialisable, make method getResults available via an RMI interface. This method should return an ArrayList containing initialised Result objects that are set up by a server program (also to be written by you) and made available via an implementation object placed in the RMI registry by the server. The server should store two Result objects in the ArrayList contained within the implementation object. Access this implementation object via a client program and use the methods of the Result class to display the surname and examination mark for each of the two Result objects. (I.e., employ ‘Method 1’ from Sect. 5.4 .)
You should fi nd the solution to the above problem relatively straightforward by simply modifying the code for the Bank example application from this chapter.
class Result implements java.io.Serializable {
private String surname;
private int mark;
public Result(String name, int score) {
surname = name;
mark = score;
}
public String getName() {
return surname;
}
public void setName(String name) {
surname = name;
}
public int getMark() {
return mark;
}
public void setMark(int score) {
if ((score>=0) && (score<=100)) mark = score;
} }
5.2 Repeat the above exercise, this time without using a separate Result class, but holding the result methods directly in the implementation class. (I.e., use
‘Method 2’ from Sect. 5.4 .) Store the implementation objects remotely under the names result1 and result2 . Access these objects via a client program and use the methods of the implementation class to display the surnames and exam- ination marks for each of the two objects.
151 J. Graba, An Introduction to Network Programming with Java: Java 7 Compatible,
DOI 10.1007/978-1-4471-5254-5_6, © Springer-Verlag London 2013
Learning Objectives
After reading this chapter, you should:
• understand the basic principles of CORBA;
• appreciate the importance of CORBA in providing a method for implementing distributed objects in a platform-independent and language-independent manner;
• know how to create IDL specifi cations;
• know how to create server processes for use with the Java IDL ORB;
• know how to create client processes for use with the Java IDL ORB;
• know how to create and use CORBA factory objects.
Though RMI is a powerful mechanism for distributing and processing objects in a platform-independent manner, it has one signifi cant drawback—it works only with objects that have been created using Java. Convenient though it might be if Java were the only language used for creating software objects, this simply is not the case in the real world. A more generic approach to the development of distributed systems is offered by CORBA (Common Object Request Broker Architecture), which allows objects written in a variety of programming languages to be accessed by client programs which themselves may be written in a variety of programming languages.