Here's an example from the standard foundry configuration file:
TRANSPORT osl.transport.udp.UDPTransportLayer transport @scheduler $HOST
The osl.handler classes have been modified to use the customized loader. As long as the loader is enabled, the request handler will resolve ClassNotFoundExceptions by requesting the required classes from the handler session which sent the original message. This is all transparent to underlying actor code.
The shell service (osl.service.shell) now supports an "addpath" command. Here's an example of its usage (from fshell):
% addpath /home/agha/m-astle/tmp
After this command has been issued, the directory "/home/agha/m-astle/tmp" will be added to the list of directories searched when a new Java class is required. There is currently no support for removing a directory from the classpath.
There are a few caveats to keep in mind:
public static final boolean DEBUG = false;The reason we do this is to avoid unnecessary code when DEBUG=false. That is, we are counting on a smart compiler to realize that DEBUG will be false no matter what. Therefore, code blocks of the form:
if (DEBUG) { ... }
should be totally removed from the code. We want to do this so that
code runs fast when we aren't debugging it. However, if we don't use
a smart compiler then this code might get included anyway.
Conditional compilation would prevent this, but we don't have it in Java.
Considering that we're planning on releasing the code to a wider audience in the near future, we'll need to annotate code with assertions so that we can have a reasonable way of tracking down bugs. So I decided to see what I could do, and here's what I came up with.
The makefiles have been reorganized to support PRAGMA specifications in foundry source files. A PRAGMA looks just like a comment and has the following format:
// PRAGMA [key1,...,keyn] java codeThis is a dirty trick from the good ol' days (i.e. mid 80's) of the first high performance Fortran compilers. They used directives specified in comments to control things like data partitioning and placement. We use them here to specify conditional source code. The advantage of this approach is that our code remains portable. We don't have to distribute any special tools unless someone else wants to use the same technique for including their own PRAGMAs.
The "key" values, key1 through keyn, specify the conditions under which java code will be included during compilation. The key listings in PRAGMAs should be comma separated with no spaces. For example, here's a code block from osl.manager.basic.BasicActorManager:
// PRAGMA [debug,debug-BAM] Log.println(FoundryStart.sysLog, "The assert key specifies code to include when we want assertion checking enabled. Similarly, the debug key specifies code to include when debugging is enabled. The debug-BAM key is used for finer-grained debugging when we only want debugging code included in the BasicActorManager ( BAM = Basic Actor Manager). You compile code with pragma options using the following "make" call:Processing migration resume message"); entry = (ActorEntry) managed_actors.get(del.receiver); // PRAGMA [assert] Assert.assert(entry, "migrated actor should have managed_actors entry but doesn't"); // PRAGMA [debug,debug-BAM] Log.println(FoundryStart.sysLog, " Scheduling actor..."); // Schedule the actor for execution so it can start processing messages. // PRAGMA [assert] Assert.assert(!entry.impl.isAlive(), "migrated thread has already been restarted"); Log.logThread("Actor", entry.impl); actorScheduler.scheduleThread(entry.impl);
make pragma KEYS="key1 ... keyn"
This has the same effect as make classes except that each
file which must be recompiled is first transformed by including any
PRAGMA lines with a key matching one of the keys in the
KEYS="..." specification. Keys should be space separated in
the call to make. Here's an example which includes assertion code:
make pragma KEYS="assert"
and here's an example which includes both assertion and debugging
code:
make pragma KEYS="assert debug"
Note that "make pragma" uses the same dependency checking as "make
classes", which means that if you want to recompile with pragma
options enabled, you'll need to either remove the appropriate .class
files or "touch" the appropriate .java files. Also, this is
experimental so you may run into problems. I've taken care not to
destroy the original .java files while transforming the source.
However, it's a good idea to keep a backup around in case you run into
problems. A "make clean" is usually a safe way to recover if you have
compilation problems. Some of the DEBUG code has been rewritten using
PRAGMAs but not all of it. Eventually it will all be converted once
PRAGMAs have been shown to be stable.