Understanding Reggie


This article covers some of the ins and outs of using Sun's sample implementation of the Jini lookup service, called reggie. Reggie is, quite simply, the single most important and most commonly used Jini service. So understanding how it works is crucial to a painless experience of using Jini. Unfortunately, reggie is also a pretty complicated beast. And reggie also uses a number of techniques that may be unfamiliar to many Java programmers (activation, remote code loading, security).

The material here may be helpful to you if you're trying to understand reggie, and particularly if you're having a problem with the service. The sections here cover:

  • The Reggie Lifecycle
  • Reggie Command Line Arguments
  • Understanding and Customizing the Reggie Log Location
  • Troubleshooting
The Reggie Lifecycle
    The reggie implementation of the Jini lookup service is an activatable process. What this means is that the actual reggie lookup service is started by the RMI Activation Daemon (rmid) only when it is first needed.

    So if this is the case, if reggie is started automatically by rmid, you may be wondering what all the business is with the complicated command line arguments you need to use to run reggie!

    As it turns out, when you run the reggie program, this does not start the lookup service. Instead, what actually happens is that the program registers itself with the activation daemon, telling it to create a reggie instance when and if needed, and then exits. You may have noticed that the reggie command line returns after a short while, rather than running indefinitely. This is because once it has finished registering with the activation daemon it simply terminates.

    The activation daemon, when it detects someone trying to invoke a remote method destined for the lookup service, will launch reggie in its own VM, if needed.

    But activation is used for more than simply "lazy" launching of reggie. When reggie registers itself, it passes a special flag to the activation daemon, telling it that reggie should be registered again automatically in the future whenever the activation daemon is restarted. This is quite handy! By using the restart flag, you can launch a whole array of activatable services by simply starting up the activation daemon when your machine boots.

    This also means that you typically only need to start reggie once on a given machine, ever. Once reggie has been run once, it will have registered itself with rmid, and rmid will have remembered that it should relaunch reggie if needed in the future. From this point on, whenever you start rmid, reggie will be started also. This "new" instance of reggie will be the same from the standpoint of other Jini services and clients--it will recover the same service ID, registrations, and so on, as it had from its previous run.

    This is an important point! If you start a new lookup service every time you sit down to do Jini development, you'll quickly have dozens of them running, since the old ones do not "go away" easily!

    Of course, for the activation daemon to remember this information across restarts, it needs its own log directory in which to save such configuration information. By default, the activation daemon saves its configuration in a directory called "log" under the directory from which you run rmid. So if you plan on using rmid to recover activatable processes, you should make sure you run it from the same directory each time.

    Since reggie is started under control of rmid, you need to understand how to really shut it down, should you need to. One brute force solution is to run rmid -stop, which terminates the activation daemon. Once stopped, you can remove the activation daemon's log directory, causing it to "forget" all of its saved state.

    Refer to Core Jini Appendix A, in the section "Getting the Most from the Activation Daemon," for more details.

Reggie Command Line Arguments
    As you know if you've done any Jini development, reggie is a complicated program to start. Let's look in detail at the reggie command line:
        java -Djava.security.policy=security_policy
             -jar reggie_JAR_file
             lookup_client_codebase
             lookup_policy_file
             log_directory
             lookup_groups
    
    There are six separate arguments here that you can control, so there are six bits of information you have to understand. The first two arguments are parameters to the JVM itself--these control the behavior of the java launcher program, and aren't passed to reggie. The last four are parameters to reggie itself. Fortunately, the settings of a number of these parameters are pretty trivial to get right, once you know the location of your Jini installation.

    Security Policy File

      The first argument sets the location of a security policy file. This policy will control what the reggie application will be allowed to do. Jini ships with two useful policy files, in examples\lookup, called policy and policy.all. In Core Jini I recommend going with the policy.all file, since it eases development headaches.

      This policy is not appropriate for general-purpose deployment, though. Check the section below on how reggie uses its log files for some detailed directions of how to customize and use the policy file that comes with Jini.

      One thing to note is that you should always pass in a fully-qualified path to the security policy file; not a relative one.

    Reggie JAR File
      The -jar argument specifies that the code to be executed by the java launcher lives in an "executable" JAR file. So the next bit of information you will need is the location of the reggie.jar file that comes with Jini. Typically this is in the lib directory of the Jini distribution.

    Lookup Client Codebase
      Setting the codebase is a little trickier than the other arguments. The codebase is a URL that tells clients of reggie where the code they will need to use the service can be downloaded from. When clients download the serialized proxy object for the reggie service (via the Discovery mechanisms), they will need to be able to download the actual classfiles that implement this serialized proxy. This is where the codebase comes in--it will be "attached" to the serialized objects, and will tell clients where the code can be downloaded from.

      Typically this value is set to a URL that references the reggie-dl.jar file on a web server someplace. Many developers will run a web server (typically the small one that comes with Jini), configured so that its "root" directory points to the lib directory in the Jini distribution. If you've set up your environment this way, the codebase you pass should be http://server/reggie-dl.jar. Make sure you use the actual server hostname or IP address, and not "localhost." Also make sure you don't use a file:// URL. (See the article on codebase on this web site for details on why this is important.)

    Log Directory
      The next parameter is the location of a directory for holding logging information for reggie. As reggie runs, it will periodically save its state into this directory, so that it can recover it later if it is restarted.

      The section "Understanding and Customizing the Reggie Log Location," below, has lots of details on this, so I won't cover it fully here. But there is one important thing to realize about the log directory: You need to make sure that the directory you specify doesn't exist; if it does exist, then reggie will complain and not start. If the directory you name does not exist, however, reggie will create it for you, and will run happily.

    Lookup Groups
      The final argument names a set of "groups" that reggie will join. These are simply the names of communities that the lookup service will support. You should make sure you provide at least one name here. By convention, every network should have a lookup service supporting the "public" Jini community. This community is named in the APIs by the empty string, but to cause reggie to join the public community, you pass the string "public" here.

Understanding and Customizing the Reggie Log Location
    As noted above, reggie will persistently save information about its state to disk, so that if it crashes, it can recover its state later on. The location of this persistent log is a directory, named on the command line a shown above.

    Now, if you kill reggie and try to restart it using the same log directory, it will complain that the log directory already exists. Reggie interprets a pre-existing log file as indicating that another instance of reggie was (or is) running using that logged information. A new instance of reggie will refuse to start unless you give it its own fresh log directory, which it will create for itself.

    So, in general, each instance of reggie that you start should have its own log directory, separate from all other reggie instances.

    If you're getting into the business of running multiple reggie instances, though, you may possibly have to configure the security policy files used by reggie. You'll note from the command line above that reggie uses a policy file that controls what it is allowed to do. There are a couple of policy files that ship with the Jini release from Sun. The example\lookup\policy file is generally used to control the acceses of the lookup service. It's a good idea to take a look at this policy file if you plan to use it:

    grant codebase "file:${java.class.path}" {
        permission java.io.FilePermission "/tmp/reggie_log", "read,write,delete";
        permission java.io.FilePermission "/tmp/reggie_log/-", "read,write,delete";
        // uncomment this one if you need lookup to accept file: codebases
        // permission java.io.FilePermission "<>", "read";
        permission java.lang.RuntimePermission "modifyThreadGroup";
        permission java.lang.RuntimePermission "modifyThread";
        permission java.net.SocketPermission "*:1024-", "connect,accept";
        // for http: codebases
        permission java.net.SocketPermission "*:80", "connect";
        permission java.net.SocketPermission "224.0.1.84", "connect,accept";
        permission java.net.SocketPermission "224.0.1.85", "connect,accept";
        permission java.util.PropertyPermission "java.rmi.server.hostname", "read";
        permission java.util.PropertyPermission "com.sun.jini.reggie.*", "read";
        permission java.util.PropertyPermission "net.jini.discovery.*", "read";
        permission net.jini.discovery.DiscoveryPermission "*";
    };
    
    The most obvious thing you will have to change if you use this policy is the location of the log directory. In particular, if you're running on Windows, you will need to change the lines that read:
        permission java.io.FilePermission "/tmp/reggie_log", "read,write,delete";
        permission java.io.FilePermission "/tmp/reggie_log/-", "read,write,delete";
    
    To something along the lines of:
        permission javaio.FilePermission "D:\\jini1_0\\reggie_log", "read,write,delete"
        permission javaio.FilePermission "D:\\jini1_0\\reggie_log\\-", "read,write,delete"
    
    (Note the use of double backslashes to "escape" the Windows file separator character.)

    Of course, if you use the policy.all policy file, which allows all accesses, then you won't have to customize your policy file (although this is a bad idea in a production environment).

Troubleshooting
    There are a couple of common problems you can run into that aren't covered here in detail, such as your services not finding any lookup services, even though you've run reggie.

    Check out the article on trouble shooting on this web site for details on some common problems and how to avoid them.

Undocumented Reggie Tricks (Use at your own risk!)
    There is an undocumented, unsupported way to run reggie without the activation service. The only reason you might want to do such a thing is if you're trying to debug a problem with reggie; you definitely do not want this in a production environment:
        java -cp reggie.jar com.sun.jini.reggie.TransientLookup 
    
    Use at your own risk!
Go back to Jini Planet

Keith Edwards
kedwards@kedwards.com


Copyright 1999, W. Keith Edwards