RMI Interruptus! Or how to interrupt RMI method calls
Once upon a time, I was working on the assignment for the SCJD certification.
The project was a classic client-server application, with an RMI server, and a
Swing-based GUI, which you could use to book hotel rooms or some such. One of the
project requirements was to provide record locking, such that only one instance
of the client could edit the hotel room entry at once. Fairly standard stuff.
So, when the user clicks Edit Room in the client GUI, the client makes an RMI
call to acquireLock
, and when that method returns, the client can then call
update
, and so on. But if another client already has the lock, then the
acquireLock
method will block until the lock becomes available. In that case,
the app shows a pleasant dialog like this:
Obviously you, as the user, would like to be able to click Cancel
.
And obviously you, as the developer, would like the RMI thread that’s stuck in
the remote acquireLock
method to return promptly. But you, as the developer,
would be sorely disappointed, because the RMI thread will continue to block.
Indefinitely! And from this outrage, thus was born the Interruptible RMI library.
Overview
The Interruptible RMI library provides a mechanism to interrupt Java RMI calls. Typically when a thread invokes an RMI method, the thread blocks until the RMI method returns. If the method call is taking too long (e.g. if the RMI server is busy, or hangs, or if the user wants to cancel the RMI operation), there is no easy way to interrupt the blocking RMI call and return control to the RMI thread. The Interruptible RMI library provides this functionality.
The library consists of two key components: an RMISocketFactory
and a
ThreadFactory
. RMI calls made on a thread from the provided
ThreadFactory
to an RMI interface using sockets from the
RMISocketFactory
can be interrupted by calling Thread#interrupt()
on
the client thread. So, it’s really easy to use. But note also on the
server side that you may wish to add a call to a handy utility method to
ensure that the current thread isn’t a “zombie” or orphaned thread that
has already been “interrupted” by the client. There is a demo app
provided with the library that shows exactly how to do this. See the
GitHub repo for more
details and to download the library and demo app.
Originally posted on java.net, now sadly shuttered