Making Constants Configurable

There are several constants that a user is likely going to want to change, like the size of the buffers for recording, or the minimum and maximum length of the delays during execution with random delays.

These constants are typically found in classes like SyncPointBuffer and other classes that first get put in the cunitrt.jar file. This file contains all the classes that make up the least dependency fixpoint of the classes required for the Concutest runtime. After it has been created, it gets merged with the rt.jar file during instrumentation and then put on the boot classpath so it’s available right from the beginning during VM initialization.

The problem is that instrumentation is a rather lengthy process (it takes a few minutes), so I want to avoid running a full instrumentation just because a number, like the delay in milliseconds, has changed. That means I have to store these constants externally somehow, outside the rt.jar file (or update the rt.jar file).

The normal way to do this would probably to use a file, maybe a text file. My XML configuration library could easily deal with this. However, since this is happening very often and — more importantly — very early during VM initialization, I want the process to be especially light-weight, especially easy for the VM executing the program.

What’s the easiest way for the VM to get a value? The easiest way is to simply read a value out of a public static final field, or more technically, to load a value out of the constant pool. That’s exactly what’s going on right now, when all these values are hard-coded.

In fact, it cannot be done more easily. Any retrieval from a file, for example, would require the VM to load the name of the file out of the constant pool, and that is already the work necessary to retrieve a constant, so reading the value from a file has to be more work.

But how do I make these constants tweakable? I have decided to create a separate class (an interface, to be precise), edu.rice.cs.cunit.ConcutestConstants, that contains all tweakable constants. It is also included in the cunitrt.jar file and therefore in the rt.jar file during instrumentation. Nothing has really changed right now.

What I can do now, though, is create a copy of that class that lives outside of the rt.jar file and that has different values than the one inside the rt.jar file. If I put this class at the beginning of the boot classpath, then the class outside with the different values will be found first. Creating that modified class file is a little bit more work for the launcher program than writing to a text file or using Java attributes and System.getProperty, but this approach is as light-weight as it can be for the executing program.

The battery on my MacBook (now with 2 GB RAM, thank you, Corky!) is about to run out, so I’ll get back to implementing this on my workstation at home.


About Mathias

Software development engineer. Principal developer of DrJava. Recent Ph.D. graduate from the Department of Computer Science at Rice University.
This entry was posted in Concurrent Unit Testing. Bookmark the permalink.

Leave a Reply