About SCIM

SCIM was written in 2 hours, 13 minutes (including the util classes and test code), and totals 786 lines of code. The test case worked the first time I ran it.

I'm distributing SCIM simply as a proof-of-concept. It's a very basic implementation of an RMI-like system, is not optimised, and can be improved in a number of ways.

I wrote SCIM partially for the fun of it, and partially as a challenge to myself to see how fast I could get the basic working implementation done.

I don't plan any further development of SCIM, but if you like it and wish to use it yourself, you're welcome to it.


Introduction

SCIM is a simple replacement for RMI. It does not attempt to reproduce the flexibility of RMI, but instead proposes a simple client/server model for remote method invocations which provides the functionality needed for the majority of simple client/server applications.

Key benefits of SCIM over RMI include:


Download

You can download scim.zip.

The 'make' script assumes you're using the jikes compiler, so modify if necessary. You don't need to compile it, since the classes are already there. Run the 'runtestserver' script to run the test server (it'll open a server on port 12345), and then the 'runtestclient' will run the client (it'll connect to localhost:12345). You won't be given a prompt; just type 'help' and it'll tell you what the available commands are. It's a simple directory browser.


Communication Protocol

All communication between one client and one server will take place over a single socket, unless extra communication channels are explicitly opened by the application.

Communications are begun with a single byte describing the type of message. The type codes are listed below:

  1. Server reference (the original object or remote reference passed to the client on socket start-up).
  2. Method call; followed by the request ID (int), remote reference ID (int), the method name (serialized String), argument types (serialized Class[]) and arguments (serialized Object[]).
  3. Method call result; followed by the request ID (int), and a serialized object representing the result.
  4. Remote reference lost; followed by the remote reference ID (int).
  5. Method exception result, followed by the request ID (int), and a serialized Throwable.

This communications protocol is clearly optimisable. One obvious optimisation would be to produce method indices for the classes which are remoted (at runtime), and use these to identify which method to call, rather than passing the name and argument type list.

One could also special-case on certain types of return types - since both the server and client know what the return types must be, primitive types can be encoded by writing the primitive value directly to the ObjectOutputStream. This trick could also be used to reduce overhead in argument passing, although care must be taken to serialize the non-primitive arguments together in one 'writeObject' call (not doing so could lead to unnecessary duplication).

There are many other potential improvements too, but right at the moment my only intention has been to bring this project to the proof-of-concept stage. I don't plan on developing this further unless someone pays me to do so :-).