Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Luckily the JDK provides flexibility when it comes to providing a solution to this problem. Using reflection, doclets, and jar file support available from within the running JVM, we propose two distinct solutions, each with pros and cons.
An important element common to both of these approaches is their reliance on the source control system. Most modern source control systems provide access to version information via a set of macros (sometimes called keywords) that are expanded by the source control system.
For instance, Perforce from Perforce Corp. provides access to version information through the RCS-like macro $Id$. So when the source file checks in, Perforce scans the file for that macro and expands the string to something like $Id: //depot/src/com/vdibart/util/VersionLister.java#1 $. Yes, those dollar signs are annoying, but you can easily parse them out; plus, they are necessary for the source control
system to recognize the macro, especially after its first expansion.
It's important to know your system's macro capabilities, as each system expands the macros differently. SCCS, which is usually installed on Unix systems by default, only displays the version information when the file is not writeable (i.e. only when it's checked in). On the other hand, PVCS shows the version information regardless of the source file's state, and only updates the string when the file is checked in. Some systems also supply access to change notes and file ownership, which you could easily integrate with this article's solutions. Other systems might only expand the macro when the file is first checked in and after that will ignore it. Again, check your source control system's documentation for details.
With this versioning tool in your box, you can design some objects that utilize the macro expansion to return version information for compiled class files. We identify two approaches to implant this information in the jar file: The first has each class return its own version. The second lists the version information in the jar's manifest file. We'll cover each of these in turn.
Reflection takes center stage in the first approach. The concept is this: place a method, called getVersion(), in each unique class. The method should be public and static, but not final. The reasons for these requirements should be
obvious; you want to be able to call the method from another object without instantiating an instance of the object supplying
its version. The method shouldn't be final because it is likely a subclass with a different version than its parent class,
and therefore must have its own getVersion(). The getVersion() method should return a String object that contains a descriptive version message. How does it generate this version message? With the macro supplied by
the version control system. Here's a sample getVersion() method; notice how little code is needed: