Jini in One Hour

Our homes are becoming full of more and more complex pieces of electronic equipment: TVs, microwaves, stereo systems, and so forth - and many of these items have clocks. It's pretty common to find one or more of these clocks flashing; particularly the one on the VCR. Whenever there is a power failure, all the clocks on these pieces of equipment start up again with an incorrect time and signal this by flashing until they are manually corrected. In addition, many offices synchronize the clocks in a building to a central time server, but this is a luxury most homes do not have. But wouldn't it be nice if every clock in the house could find a correct, central clock and set itself? In this section, we'll walk through the steps of setting up a Jini system that will do this for some "software" clocks. No real clocks currently support Jini, but it would be nice if they did!

The first step is to get the Jini classes, which you can download from http://www.jini.org by following the "Getting Started" link to the Jini Downloads page. This page has several options; you only need the Jini Technology Starter Kit for now, but you may like to download other projects as well.

The Starter Kit installation process for platforms such as Windows and Linux will check your network settings and Java installation, and start up a key component of Jini called a registrar. Once you see a window called Service Browser with the message "1 registrar, not selected," you'll know this key component is running and you can start up some services and clients. You should see something similar to Figure 1-1.

Figure Overview of Jini.1. Figure 1-1. Service Browser window showing the registrar running

Figure 1-1. Service Browser window showing the registrar running

At later times, you can get to this page by just running the command LaunchAll from the installverify directory.

At this stage, you will use three files in the Jini directories:

As you already know, this book is all about how programmers can build Jini services and clients. The flashing clocks problem has all the source code explained in Chapter 18. For now, you can download .jar files containing all the compiled classes from http://jan.newmarch.name/java/jini/tutorial/programs.zip. Unzip the files into any directory you want. Three .jar files are of interest, under the dist directory:

When clients find services, they download a proxy for the service. Support code for this proxy is usually in a .jar file on an HTTP server. So the file clock.clock-dl.jar has to be on an HTTP server somewhere. You can copy this file to an HTTP server you have access to, or you can just use the file on the HTTP server that I run at jan.newmarch.name. (If you have a firewall between my server and your computers, then it may be easier to put the file on a local server than to get Java to talk through the firewall. You can get away with not using these classes in this example; the clocks will work fine, but the service browser won't see the services properly.)

That's all you need to get this demonstration working. You can start up a flashing clock by running Java from, say, a command box under Windows or a terminal window under Unix. You will need to set your classpath so that it contains the Jini files jsk-platform.jar and jsk-lib.jar, and also the clock file clock.clock.ticker.jar. For example, under Unix you could run

JINI_HOME=...
CLOCK_DIR=...
CLASSPATH=$JINI_HOME/lib/jsk-lib.jar:$JINI_HOME/lib/jsk-platform.jar:$CLOCK_DIR/clock.clock.ticker.jar
export CLASSPATH

and under Windows, you could run

set JINI_HOME = ...
set CLASSPATH = %JINI_HOME%/lib/jsk-lib.jar;%JINI_HOME%/lib/jsk-platform.jar;%CLOCK_DIR%/clock.clock.ticker.jar

After setting the classpath, run a dumb ticking clock:

java \
     -Djava.rmi.server.codebase=http://jan.newmarch.name/classes/clock.clock-dl.jar \
     -Djava.security.policy=JINI_HOME/installverify/support/jsk-all.policy \
     clock.clock.TickerClock \
     "Ticking Clock"

where JINI_HOME is replaced by the directory name where you installed Jini. The first parameter (codebase) lets the service tell clients where the downloadable files are; the second parameter (security) sets the policy for what remote code is allowed to do to this service. The third parameter is the main class file, and the last parameter is just a string to be displayed as window title.

You should see a clock like the one shown in Figure 1-2, flashing every second.

Figure Overview of Jini.2. Figure 1-2. Jini service browser

Figure 1-2. Jini service browser

You can run this command as often as you want, on the same or different machines. Each one should start up a new flashing clock. These clocks will all discover one another, but since none of them shows a valid time, there is nothing they can do to each other.

Now start up a "smart" clock that is showing the right time. The classpath needs to be set to the Jini files jsk-platform.jar and jsk-lib.jar again, but this time it should include clock.clock.computer.jar instead of clock.clock.ticker.jar. The you run the good clock as follows:

java \
     -Djava.rmi.server.codebase=http://jan.newmarch.name/classes/clock.clock-dl.jar \
     -Djava.security.policy=JINI_HOME/installverify/support/jsk-all.policy \
     clock.clock.ComputerClock \
     "Computer Clock"

As this one starts up, it will discover the other clocks and they will discover it. The wrong clocks will ask the right clocks for the correct time; the right clocks will tell the wrong clocks to reset their time. This is a peer-to-peer system, and I don't know whether right tells wrong the correct time or wrong gets the correct time from right - it doesn't matter. All that matters is that the correct time will soon show on all clocks. Later, the clocks will "drift," but after reading Chapter 18 you will easily be able to add code to resynchronize on a regular basis.

If you now start up another possible flashing clock, it will quickly discover the other correct clocks and may not even flash at all.

So, what is going on with these clocks that is valuable to a distributed application's programmer?

Finally in this section, let's look at pseudocode for the clocks:

main:
    allow remote code to be downloaded and run within this VM
    start a thread to asynchronously discover proxies for clock services,
        calling us as listener

service discovered:
    if we are invalid and the remote clock is valid
        set our time from the remote clock
        set state to valid
    else if we are valid and the remote clock is invalid
        set the time on the remote clock

That's it! The rest of the clocks' code (less than 700 lines total) is the service specification, user interface classes, and code to keeping the clocks ticking.