Project 4: Distributed E-book library with RMI

Due: Monday, November 24, Tuesday, November 25, 11:59 PM


Quick Links

Project Overview

For this project you will be implementing a distributed E-book library that will use Java RMI to allow members to check out library resources. The goal of this project is for you to better understand distributed object computing using Java RMI.

The Project Setup

The project consists of two packages. Package library contains the following classes:

Package member contains the following classes:

The server process, running on one machine, will be running LibraryServerImpl. Its main method should start an RMI registry, and register a LibraryServerImpl object with it. The client process, running in a different JVM on a potentially different machine, will be hosting one or more MemberImpl objects. The main method of the MemberImpl class should connect to the server's registry and look up the LibraryServer object the server stored there. Then it can create one or more MemberImpl objects that can interact with the server via the remote reference to a LibraryServer object it receives. It should be possible to run multiple client programs to connect to the server at the same time. It is up to you to write the code for these main methods in this way, which will be useful for testing; how we actually will test your project is described at the bottom.

Do not change either the LibraryServer or Member interfaces, or any of the methods or constructors in Book and MemberData; you may add methods, fields, etc. to the latter two classes if you wish. You may also add any other classes you need. Note that the project also includes a security.policy file to allow RMI. Do not modify this file.

General Requirements

Most of the code you write is not too specific to RMI; that part is handled in the main methods of the two Impl classes. Implement these two classes according to the following requirements.

The Library maintains a list of books and registered members. Books are created based on the arguments passed to the LibraryServerImpl constructor, which are numBooks (the number of books in the library), copiesPerBook (copies of each book), and booksPerMember (the maximum number of books a member can check out). LibraryServerImpl creates numBooks objects of class Book, each with a distinct title. You can determine titles however you like; one way is to have a prefix constant string such as "Book" and a static counter. This would give book titles of the form "Book1", "Book2", "Book3", ... "BookN" where N is the value of numBooks.

Members interact with the library via its method calls (from the LibraryServer interface):

In all cases, the LibraryServerImpl should confirm that the name and ID present in any MemberData object it receives are consistent; i.e., the ID is the one returned when a user with the given name first registered.

The MemberImpl class defines methods that direct a member to interact with a library server. The method getBooksRead return a list of books that the member has read (i.e., those books the member has ever checked out and subsequently returned), while getBooksCurrCheckedOut returns the list of books the member current has checked out. Your code will have to maintain these lists, which should be stored in the MemberData object. Other MemberImpl methods simply make calls to the appropriate LibraryServer methods, or set/return what that server is.

For this project, two members cannot have the same name. All member data should be consistent with the server's state and vice versa. This means that the library should also have its own record keeping of the books checked out by each member. The library should not rely on the MemberData objects passed in to make decisions. It should rely on its own internal records to make decisions. The reason is that a member may "lie" or send erroneous MemberData. In fact, we will be testing these cases.

You must ensure that the implementation of your server can handle multiple clients and keep their state consistent with that of the server. Ex. if there are multiple members trying to checkout the same book and the library has a fixed number of copies, n, of that book, then no more than n requests can be honored at any one time. And, of course, because things can be happening at the same time, you should worry about using proper synchronization.

Running RMI and Testing

For the sake of simplicity, you will run all of the elements in different JVMs on a single machine. However, in practice, the elements would potentially be running on different hosts.

You should write your own test cases to test the functionality of the client and server. You can test the RMI functionality through the main methods of the LibraryServerImpl and MemberImpl. This includes the registry creation, the registry binding, and all further communication between the library and member remote objects. Look at the PublicTests file for hints on how to get started.

Our testing on the submit server will ignore your main methods and RMI setup. We will have our own testing classes that will create the registry and library and member objects and will call the appropriate methods for each using RMI. For this reason, all of your code for registry creation should be in the main method and no where else, so that it does not interfere with our setup.

What to Turn In

Every file you submit should have your name and UID. To enforce academic integrity, Code WILL BE CHECKED for similarity to other submissions. Each student should make his or her own individual submission.

Submit your code on the Department's Submit Server. Contact the TA if you have any troubles submitting.

No design document is needed for this assignment.

Web Accessibility