CF - A fast Java Class Finder22nd Jun 2008
What is it with class finders these days? Everyone seems to have their own version of the tool. From naive programmers creating crude forms to large organizations with fairly sophisticated ones. Through this article, I present my little implementation of the product.
But before you explore further, I have a few claims to make. I have tried my best to bridge the many mutual exclusivities exhibited by similar products in the realm. So, I hope this product (I call it CF, affectionately) will not disappoint you at all. However, as they say in software parlance, bugs always tend to masquerade as features until careful attention catches them. So, please feel free to report any anomalies you may encounter while you use CF.
- What is a class finder?
- Getting started
- What's already available?
- CF feature set
- Known limitations
What is a class finder?
A Java class finder is a tool which lets one search for a particular Java class among hundreds of JAR files. Simple as it sounds, this particular tool is extremely handy in day to day Java/J2EE development. Got a NoClassDefFoundError or ClassNotFoundException? Or simply trying to find out where a particular class could be found in the plethora of JAR libraries you have? Well, that's exactly what a class finder tries to address! CF is my implementation of the product.
Having established that, we can further delve into a brief study of the features provided by some of the popular class finders available.
CF is a command line tool for searching Java classes within Java archives. The binary form, cf.jar ships as an executable JAR file. Thus, the basic form of invoking CF would be to execute the following command (on any operating system, provided, Java is installed and the java command is properly set up).
java -jar cf.jar
The above command would invoke CF but would display a help message. Try the following command or refer to CF feature set for all the options and their interpretations.
java -jar cf.jar --help
What's already available?
Before implementing one myself, I did a survey on similar products already available in the market. Here are my observations (I do not intend to disclose the actual identities of these products due to competitive reasons).
There are at least 5 popular class finders floating around the internet. The following table shows a comparison matrix of them.
|Products vs Features||A||B||C||D||E|
|High Speed Searching||✔|
|WAR, EAR, JAR||✔/2|
|Non .class Searching||✔/2||✔/2|
Thus, none of the products displayed above provide all of the features. My fundamental goal while designing CF was to achieve this level of completeness. Provided popularity for this product increases over time, it would be fulfulling all the above mutual exclusivities.
CF feature set
After having arrived at a decent picture of the variety of class finders already available, lets see how CF helps.
Command line interface
The current version of CF supports only a command line interface. This being a fundamental necessity, can be later retrofitted with a graphical interface depending on the popularity the product gains.
Rich set of options for high degree of customization
The command line interface and the application in general has been designed to be very flexible. Thus, it accepts several options and arguments as listed below.
|Short Form||Long Form||Description|
Shows a detailed help.
Redirects the output to a file.
Additional file extensions in addition to the default .jar. Comma or space separated list accepted.
Makes the search case insensitive.
Causes the search to go silent, without the progress bar animation.
Removes the filtering on .class types so that other file types such as .properties, .xml and virtually anything else can also be searched for.
Performs a shallow search. Doesn’t recurse.
Wildcard searching - A proud feature
Indeed, CF supports the wildcard searching by asterisk (*). The implementation of wildcard searching itself, besides being an exciting endeavour, has some rich consequences. The following shows some sample search strings and their respective interpretations by CF.
|With the –a (All Types) option specified|
If you're curious about the implementation specifics, please refer www.adarshr.com/papers/wildcard, which by itself is another separate topic!
Command line progress animation
I felt this feature, although of trivial importance, should get a place in this article. How often have we done some time consuming command line activity and wished there was some form of progress indicator? If not a realtime work meter, a simple animation that runs whenever the command is busy doing something in the background would help a lot. This serves two purposes. Firstly, it notifies the user that the command is still alive and hasn't run into a vicious deadlock. Secondly, it easens up the impatient programmer.
While implementing this feature for CF I learnt various advanced concepts of multithreaded programming in Java. It's definitely worth a try.
Carefully controlled thread spawning algorithm
CF employs a carefully controlled thread spawning mechanism which ensures that the work is done considerably quicker than other similar products, at the same time ensuring that the processor is neither starved nor memory leaked.
It relies on the highly efficient Atomic Variables introduced as part of Java 1.5. Instead of traditional lock based synchronization mechanisms, CF uses synchronous non-blocking queues that give it an added edge with respect to speed.
To be able to run CF, you need a minimum of JRE 1.5 on your machine. I do not intend to release any build for previous versions of Java. This version of CF has been successfully tested on Windows XP, Windows Vista and SUSE Linux 10.
In Java, when we pass * as a command line argument, it is interpreted as a wild card instead of an ordinary symbol. Thus, if we pass *.txt as a command line argument to a Java program, the String parameter of the main method would contain file names of all the .txt files contained in the current directory instead of just a single entry, "*.txt". Since this is the expected behaviour of Java itself, we run into problems when * shouldn't have any special meaning for our command line arguments.
CF too, suffers from this side effect. The effect can be observed when arguments such as *.*, * or *.extension are passed to the tool. What the main method of CF receives will be a series of file names matching this wild card instead of the unaltered argument. Hence, it fails the argument validation stage and gives out an error.
So far, I haven't found any solution to this. One way to circumvent this would be to use some other symbol instead of the asterisk for wild card matching. Thus it's a tradeoff between the intuitiveness of the feature and the actual probability of occurrence of this scenario.