A Make Tool for the Java™ Language

What is This Tool?

This tool's functionality is analogous to the "smart checking" feature of Borland JBuilder or the dependency analysis feature of IBM Jikes. However, it is a command line tool that is not tied to any IDE, can be used with any Java compiler, and can run as a task in the popular Ant make system.

Why Another Make Tool?

It has been widely observed that classic make files (and, in fact, any language-independent make mechanisms) are not very good for Java. Well, such mechanisms may not be very smart with other languages as well - remember waiting for tens or hundreds of .c files to be recompiled after you changed just a comment in a single header file. However, in Java the situation is made worse by the fact that dependencies between classes may be many-to-many and take lots of different forms. Class A can call a method of class B, be a subclass of B, reference a static field defined in B, etc. Two classes may depend on each other in complex ways. Depending on a particular change made to a Java class, zero, one, or many other classes may need to be updated and recompiled.

However, the javac Java compiler recompiles class B only if B.java is passed to it explicitly, or if B is used by an explicitly specified class C. If A uses B and B is changed, A.java would not be recompiled unless explicitly specified. On the other hand, each explicitly passed source is always recompiled, whether this is really required or not.

This makes management of large Java projects hard, particularly when done by people who are not the original code developers. Once you make a certain change to a class (for example, change the signature of a public method), you need to recompile (effectively, verify the links) in the whole project. Otherwise there is no guarantee that somewhere in the depths of the application the changed method is not referenced according to its old interface. And due to lazy runtime class resolution of a JVM, bugs like this one can show up very late, increasing development turnaround time.

How It Works

Our make tool keeps track of dependencies between classes and recompiles the source files as necessary by automatically creating and maintaining the so-called project database (equivalent of a "dependency cache" that some other tools use). It contains information about dependencies between classes, and is created the first time you invoke the tool on a given set of .java sources. After that, whenever you change a source file and invoke the make tool, the timestamps of the sources are compared against those preserved in the database, and the changed .java files are recompiled. Then the updated binary classes are checked against their old versions, and, depending on the changes made to them, some dependent classes may be recompiled. If no compilation errors happen, the database is updated, i.e. new class versions get into it, reflecting the new project state.

Unlike some other make tools for Java, our tool performs intelligent dependency checking, which means that it always recompiles the smallest possible subset of project classes, depending on a particular class modification. For example, if the only change you have made is to the signature of a single public method m() in class A, only those classes that prevously called A.m() will be recompiled. All others, which may include e.g. subclasses of A or those referencing other methods or fields of A, will not be touched.

Unlike conventional make utilities, our tool is very easy to use - as easy as javac itself. Its input is the same as that of javac, except that it needs the names of all of the project .java files every time it is invoked. If the project database is not yet present or has been deleted, all of the files are recompiled to make sure that the project, and hence the new project database, are consistent. On subsequent invocations, the tool recompiles only those of the sources that really should be. If you omit some source files, they are considered removed from the project and their records are deleted from it.

Our make tool is a pure Java application. By default, it assumes that you invoke it using the Java launcher of JDK 1.3 or newer, and tries to use the version of the javac Java compiler bundled with the JDK. However, you can use any other JVM to run the tool, and make it use any other Java language compiler.