Project 1: Remote Method Invocation CSE 291 Spring 2016

Similar documents
15-440: Project 1 Remote File Storage and Access Kit (FileStack) Using Sockets and RMI. Design Report Due Date: 9 Sep 2013 Final Due Date: 25 Sep 2013

Learning Objective. Project Objective

15-498: Distributed Systems Project #1: Design and Implementation of a RMI Facility for Java

Distributed Systems Recitation 3. Tamim Jabban

CS555: Distributed Systems [Fall 2017] Dept. Of Computer Science, Colorado State University

Distributed Objects SPL/ SPL 201 / 0 1

JAVA RMI. Remote Method Invocation


Chapter 4 Defining Classes I

A Report on RMI and RPC Submitted by Sudharshan Reddy B

Kakadu and Java. David Taubman, UNSW June 3, 2003

COMMUNICATION PROTOCOLS: REMOTE PROCEDURE CALL (RPC)

Programming Assignment 3

CS 215 Software Design Homework 3 Due: February 28, 11:30 PM

Distributed Objects and Remote Invocation. Programming Models for Distributed Applications

Message Passing vs. Distributed Objects. 5/15/2009 Distributed Computing, M. L. Liu 1

Q.1. (a) [4 marks] List and briefly explain four reasons why resource sharing is beneficial.

SUMMARY INTRODUCTION REMOTE METHOD INVOCATION

Homework # 7 Distributed Computing due Saturday, December 13th, 2:00 PM

How are classes loaded into the Java Virtual Machine (JVM)? from the local file system (CLASSPATH). by an instance of ClassLoader

BEAAquaLogic. Service Bus. Interoperability With EJB Transport

Chapter 15: Distributed Communication. Sockets Remote Procedure Calls (RPCs) Remote Method Invocation (RMI) CORBA Object Registration

Introduction to Java.net Package. CGS 3416 Java for Non Majors

JBoss Remoting. Version alpha. November 15, 2004

Compilers Project 3: Semantic Analyzer

API Knowledge Coding Guide Version 7.2

RMI (Remote Method Invocation) Over the year, there have been 3 different approaches to application development:

Arjun V. Bala Page 13

Last Class: RPCs. Today:

Introduction & RMI Basics. CS3524 Distributed Systems Lecture 01

CMPSCI 187 / Spring 2015 Implementing Sets Using Linked Lists

Programming with RMI Reminder

Communication. Distributed Systems Santa Clara University 2016

Structured communication (Remote invocation)

Remote Method Invocation

Distributed Systems. 02r. Java RMI Programming Tutorial. Paul Krzyzanowski TA: Long Zhao Rutgers University Fall 2017

Distributed Systems Theory 4. Remote Procedure Call. October 17, 2008

School of Informatics, University of Edinburgh

P2: Collaborations. CSE 335, Spring 2009

Grid4All Security User's Manual, Release 0.6

Objectives for this class meeting. 1. Conduct review of core concepts concerning contracts and pre/post conditions

Distributed object component middleware I - Java RMI

Distributed object component middleware I - Java RMI

Exceptions. CSE 142, Summer 2002 Computer Programming 1.

Exceptions. Readings and References. Exceptions. Exceptional Conditions. Reading. CSE 142, Summer 2002 Computer Programming 1.

5 Distributed Objects: The Java Approach

Lecture 5: Object Interaction: RMI and RPC

Lecture 5: RMI etc. Servant. Java Remote Method Invocation Invocation Semantics Distributed Events CDK: Chapter 5 TVS: Section 8.3

CIS 121 Data Structures and Algorithms with Java Spring 2018

The security mechanisms of Java

Exceptions in Java

Distributed Systems Lecture 2 1. External Data Representation and Marshalling (Sec. 4.3) Request reply protocol (failure modes) (Sec. 4.

RPC and RMI. 2501ICT Nathan

ASSIGNMENT 5 Data Structures, Files, Exceptions, and To-Do Lists

Outline. Interprocess Communication. Interprocess Communication. Communication Models: Message Passing and shared Memory.

CC755: Distributed and Parallel Systems

Exceptions. References. Exceptions. Exceptional Conditions. CSE 413, Autumn 2005 Programming Languages

Program 12 - Spring 2018

CS 315 Software Design Homework 3 Preconditions, Postconditions, Invariants Due: Sept. 29, 11:30 PM

P2P Programming Assignment

Object-Oriented Distributed Technology

Questions and Answers. A. RMI allows us to invoke a method of java object that executes on another machine.

Lecture 06: Distributed Object

Programming Standards: You must conform to good programming/documentation standards. Some specifics:

Advanced Java Programming

CS 3 Introduction to Software Engineering. 3: Exceptions

10 Java Collections; Equality, JUnit

Communication. Overview

CS555: Distributed Systems [Fall 2017] Dept. Of Computer Science, Colorado State University

Dynamic code downloading using Java TM (Using the java.rmi.server.codebase Property)

Exceptions and Libraries

Last Class: RPCs. Today:

MODELS OF DISTRIBUTED SYSTEMS

Distributed Systems Architecture

IBD Intergiciels et Bases de Données

ROEVER ENGINEERING COLLEGE Elambalur,Perambalur DEPARTMENT OF CSE

MODELS OF DISTRIBUTED SYSTEMS

3. When you process a largest recent earthquake query, you should print out:

Usmux: Unix-domain socket multiplexing

CS3114 (Fall 2013) PROGRAMMING ASSIGNMENT #2 Due Tuesday, October 11:00 PM for 100 points Due Monday, October 11:00 PM for 10 point bonus

Distributed Programming with RMI. Overview CORBA DCOM. Prepared By: Shiba R. Tamrakar

5.4. Events and notifications

Distributed Middleware. Distributed Objects

Apartments and COM Threading Models. Jim Fawcett CSE775 - Distributed Objects Spring 2008

EE 422C HW 6 Multithreaded Programming

Distributed Systems Project 4 Assigned: Friday March 20 Due: Friday April 3, 11:59pm

Lab Assignment 3 for ECE374

Outline. EEC-681/781 Distributed Computing Systems. The OSI Network Architecture. Inter-Process Communications (IPC) Lecture 4

Oracle Service Bus. Interoperability with EJB Transport 10g Release 3 (10.3) October 2008

Course Description. Learn To: : Intro to JAVA SE7 and Programming using JAVA SE7. Course Outline ::

Distributed Systems Recitation 2. Tamim Jabban

1 OBJECT-ORIENTED PROGRAMMING 1

Open Chord version User s Manual

BEAWebLogic Server and WebLogic Express. Programming WebLogic JNDI

Object Interaction. Object Interaction. Introduction. Object Interaction vs. RPCs (2)

Lab 10: Sockets 12:00 PM, Apr 4, 2018

MTAT Enterprise System Integration. Lecture 2: Middleware & Web Services

Advanced Topics in Operating Systems

416 Distributed Systems. RPC Day 2 Jan 11, 2017

Interpreting Languages for the Java Platform

Transcription:

Project 1: Remote Method Invocation CSE 291 Spring 2016 Assigned: Tuesday, 5 April Due: Thursday, 28 April Overview In this project, you will implement a remote method invocation (RMI) library. RMI forwards method calls over a network connection, permitting objects located on one Java virtual machine to call methods on another. Users of the RMI library write code in the usual Java style: remote methods appear, syntactially, as regular Java methods. The only difference is in how the objects on which the methods are invoked are obtained. The usage is roughly as follows: Regular methods Remote method invocation // Create a (contrived) object which can read // files on the local filesystem. Storage storage = new Storage(); // Invoke a method on the local object. // Create a "stub" object which "knows" how to // communicate with the server. This object is // generated for you automatically by the RMI // library ("Stub" is a class in the RMI // library) - you only need to define the // interface "Server". InetSocketAddress address = new InetSocketAddress("127.0.0.1", 80); Server server = Stub.create(Server.class, address); // Invoke a method on the remote object. This // method is executed remotely. The data and // return value are automatically marshalled // and unmarshalled for you by the RMI library. // Return values and exceptions are passed // back to the local VM and can be handled in // the usual Java fashion. byte[] data = storage.retrieve("/dir/file"); byte[] data = server.retrieve("/dir/file"); A similar simplification takes place on the server side the details are given later in the handout. As you can probably see, RMI greatly reduces the difficulty of writing networked Java code. After you complete the RMI library, you will use it to write a distributed filesystem in the next project. Java already has a standard RMI library, but we will not be using it in this course. You may be interested in browsing its documentation to get more ideas about RMI. A link is given in the references section.

Logistics You should work with a partner on this project. The starter code can be downloaded from http://idon tknowwhere. When you are finished, submit your code in a single zip archive to /afs/somewhere. Be sure to include your modified Skeleton.java and Stub.java, and files containing any helper classes you have created. Stub, Skeleton, and all helper classes must be in the package rmi. We will extract these classes and use them to test your implementation. Your RMI library should work on Java 7 virtual machines. Detailed Description RMI works, firstly, by exposing an object on one Java virtual machine as remotely-accessible, and secondly, by providing other virtual machines with a way to access this object. The remotely-accessible object can be thought of as a server in the abstract sense, since it provides some services through its remotely-accessible methods. Each Java virtual machine that accesses this object is then a client. Therefore, the RMI library has two major components: one that simplifies the task of making servers remotely-accessible, and another that simplifies the writing of the corresponding clients. Note that it is important not to think of the remotely-accessible object as a server in the low-level (socket programming-level) sense. As you will soon see, a low-level TCP server is implemented in, and hidden by, the RMI library. On the Server: Skeleton The server is a regular Java object of a regular Java class, with some public methods. Some of these public methods are meant to be accessible remotely. To permit remote access, a skeleton object is created for the server. The skeleton object is implemented in the RMI library. It is a multithreaded TCP server which handles all the low-level networking tasks: it listens for incoming connections, accepts them, parses method call requests, and calls the correct methods on the server object. When a method returns, the return value (or exception) is sent over the network to the client, and the skeleton closes the connection. Note that the server object itself need not perform any network I/O this is all done entirely by the skeleton, within the RMI library. The server object does not even have to be aware of the existence of any skeletons that might invoke methods on it. What determines which public methods of the server object are accessible remotely? The server object implements a certain kind of interface called a remote interface, which will be detailed later. The remote interface lists the remotely-accessible methods of the server object. The skeleton object is created for this interface, and only forwards calls to the methods which are listed in it. On the Client: Stub Clients use stub objects to access the server. Stub objects are created by the RMI library. Each one appears to implement a given remote interface. However, instead of implementing the interface in a direct manner, each stub object forwards all method calls to a server by contacting a remote skeleton. When the client invokes a method on a stub object, the stub opens a connection to the skeleton, and 2

sends the method name and arguments. As described in the section on skeletons, this causes the remote skeleton to call the same method on the server object. When the method finishes, the skeleton transmits the result, and the stub returns this result to the caller in the client virtual machine. As with the skeleton, the user of the stub need not explicitly perform any network I/O again, this is done entirely by the stub object, and implemented within the RMI library. Diagram The goal of the RMI library is, simply, that when the client calls a method on the stub, the skeleton calls exactly the same method on the server. If no network error occurs, it should appear as if the client made the call directly on the server, as if the server is a local object. Remote Interfaces A remote interface is simply a regular interface with the additional requirement that every method be marked as throwing a special exception, RMIException. This is because, when using RMI, a method may fail due to a network error, a protocol incompatibility, or for other reasons that are related only to RMI and have nothing to do with the functionality of the server object. These failures are, of course, signalled by throwing RMIException. Example: File Server Based on RMI 1. Defining a remote interface public interface Server public long size(string path) throws FileNotFoundException, RMIException; public byte[] retrieve(string path) throws FileNotFoundException, RMIException; 2. Defining a server class public class ServerImplementation implements Server // Fields and methods. 3

public long size(string path) throws FileNotFoundException, RMIException // Some implementation of the size method, which probably // accesses the server machine s local storage and does no // network I/O. public byte[] retrieve(string path) throws FileNotFoundException, RMIException // Some implementation of the retrieve method. 3. Creating the server object and making it remotely-accessible // Create the server object. ServerImplementation server = new ServerImplementation(); // At this point, the server object is a regular local object, and is not accessible // remotely. // Create the skeleton object. Note that the type Skeleton is parametrized by the // remote interface for which the skeleton is being created. Unfortunately, due to // a limitation of the Java language, the class object for the same interface must // also be passed as the first parameter to the constructor, as shown below. Skeleton<Server> skeleton = new Skeleton(Server.class, server); // Start the TCP server in the skeleton, making the server object remotely-accessible. skeleton.start(); 4. Accessing a server object remotely // Create an RMI stub which will forward method calls to the remote object. InetSocketAddress Server address = new InetSocketAddress(hostname, port); server = Stub.create(Server.class, address); // Perform some method calls using the stub. In practice, RMIException and any // other exceptions thrown by the methods in the Server interface must either be // handled or declared by the method containing this code. long file_size = server.size("/file"); byte[] data = server.retrieve("/file"); 4

Specification You are to create, within the package rmi, two classes: Skeleton and Stub. Detailed specifications can be found in the Javadoc distributed with the starter code, which can be generated by executing make docs in your project directory. Brief overviews are given here. Skeleton implements a multithreaded TCP server. The class is parametrized by the remote interface for which it accepts calls. Each of the Skeleton constructors requires the caller to provide a reference to a server object which implements that interface. The skeleton object must forward all valid call requests it receives to the server object thus specified. The skeleton object must also stop gracefully in response to calls to stop, must be restartable, and must call the stopped, listen error, and service error methods in response to the appropriate events. Stub is a class factory which generates stub objects for remote interfaces. The class Stub itself cannot be instantiated. To repeat, it is important to note that stub objects are not instances of the Stub class, for reasons that should become clear after reading the implementation section. Stubs must necessarily implement all the methods in their remote interface, and they must do this by forwarding each method call to the remote skeleton. Stubs should open a single connection per method call. Arguments should be forwarded as given, and results should be returned to the caller as they were returned to the skeleton from the server. If the remote method raises an exception, the stub must raise the same exception, with the same fields and the same stack trace. The stub may additionally raise RMIException if an RMI error occurs while making the method call. Stubs must also additionally implement the methods equals, hashcode, and tostring. Two stubs are considered equal if they implement the same remote interface and connect to the same skeleton. The equals and hashcode methods must respect this requirement. The tostring method should report the name of the remote interface implemented by the stub, and the remote address (including hostname and port) of the skeleton to which the stub connects. Stubs must also be serializable. All the constructors of Skeleton and all versions of Stub.create must reject interfaces which are not remote interfaces. Implementation The RMI library is very generic. Skeleton must be able to call any method in any remote interface. Stub must solve an even greater challenge: it must be capable of generating stub objects that implement any remote interface at run-time. You will need to use Java Reflection in order to achieve this level of flexibility. To start, consult the documentation for the Class and Method classes. Also see InvocationTargetException. The generation of stubs that implement arbitrary remote interfaces at run-time is done by creating proxy objects (class Proxy). Every proxy object has a reference to an invocation handler (class InvocationHandler), whose invoke method is called whenever a method is called on the proxy object. The RMI library s stub objects will therefore be proxy objects, and the marshalling of arguments will be done in their invocation handlers. Please refer to the documentation of these classes. Perhaps the easiest way to transmit arguments and results is by using Java s native serialization facility. For this, please refer to the documentation for the classes ObjectInputStream and ObjectOutputStream. 5

You may create whatever helper classes you need to implement Skeleton and Stub, but please put them in the rmi package and make them package-private. Testing: Local The starter code is distributed together with some test cases in the conformance/ subdirectory. These test the public interface of your RMI library for conformance with its specification, and part of your grade will depend on passing these tests. You may create additional test cases in the conformance/ subdirectory to test the public interface of your library. These tests are in the package conformance.rmi, so they can only access the public interface. You may also create test cases in the unit/ subdirectory. The tests in the unit/ subdirectory are meant to share the package rmi with your library code, so you can test package-private classes and methods. Run make test to run all tests. For detailed documentation on how to use the test library and write your own tests, run make docs-all and read the documentation for the package test in the Javadoc generated in the javadoc-all/ subdirectory. The Test and Series classes are of particular interest. You should also look at the some of the tests distributed with the starter code as examples. Testing: Docker This requirement is intentionally loosely specified. Write a PingPongClient and a PingPongServer. The client should invoke a String ping(int idnumber) method upon the server, which should, in turn, return a String containing Pong followed by the idnumber (all part of the returned string). Then, write a PingServerFactory which contains a PingServer makepingserver() method that should create a new PingServer and return it (as a remote object reference). Using the same techniques as used for your project 0, you should create two docker containers, one for the client and one for the server and factory. The client should then use the RMI registry to get a reference to the factory, then use the factory to get a reference to a server, then it should test the ping server 4 times and confirm that it works correctly each time by printing 4 Tests Completed, 0 Tests Failed. Of course, if it does fail 1, 2, or 3 times, the output should indicate this appropriately. Notes and Tips If you are creating both an ObjectInputStream and an ObjectOutputStream on two sides of a connection, you must ensure that the output stream is created first, and you must flush it before creating the input stream. This is because the ObjectInputStream constructor might not return until it receives a header from the peer s ObjectOutputStream object, and that object tends not to send it until it is either used to transmit something, or is flushed. If both peers create their input streams first, or fail to flush their output streams, then they will deadlock waiting for stream headers that will never come. Be sure to gracefully handle invalid arguments (for example, null), and eagerly release any system resources your code acquires. 6

Note that the skeleton is multithreaded, so server objects must be thread-safe. Overlapping requests may, in principle, arrive from clients at any time. Note also that there are several interesting cases: a server object may implement multiple remote interfaces, and different skeletons may be forwarding requests on those interfaces. Multiple skeletons may be forwarding requests on the same interface. There may also be no skeletons forwarding requests to a particular server. On the client side, the type of a stub is simply a remote interface. Nothing prevents a regular, local object from implementing this interface and masquerading as a stub. In fact, this allows a degree of flexibility a user can choose between a remote or a local object at run-time. There are two Stub.create methods, corresponding to two ways to create stubs. Why is this? The usefulness of one of the ways is obvious the caller specifies the remote interface and the address of the remote host, and obtains a stub. The other way allows a stub to be created by taking the address automatically from a skeleton, which must therefore be running in the same virtual machine on which the stub is being created. This second method is useful when this stub will then be transmitted to a client. This allows callbacks to be implemented easily. RMI stubs can be passed as arguments and return values in RMI calls. In this way, servers and clients can make each other aware of other servers by simply passing stubs through which the other servers can be accessed. Syntactically, passing stubs in this way appears the same as passing regular local references. This is also the reason for defining equality of stubs as done in the specification section. References Java Remote Method Invocation API http://docs.oracle.com/javase/tutorial/rmi/index.html http://docs.oracle.com/javase/6/docs/api/java/rmi/package-summary.html Java Reflection API http://docs.oracle.com/javase/tutorial/reflect/ http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/package-summary.html Proxy objects and invocation handlers http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/proxy.html http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/invocationhandler.html Object input and output streams http://docs.oracle.com/javase/7/docs/api/java/io/objectinputstream.html http://docs.oracle.com/javase/7/docs/api/java/io/objectoutputstream.html 7