ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jason Boehle <>
Subject RE: Incremental Compilation and ant
Date Fri, 21 Jul 2000 17:39:23 GMT
I don't know if this is feasible, but has anyone explored using jikes to
generate the dependency information for a source tree?  I thought I saw a
command line parameter to jikes to produce this...

Jason Boehle

-----Original Message-----
From: Vitaly Stulsky []
Sent: Friday, July 21, 2000 9:31 AM
Subject: Re: Incremental Compilation and ant

> Setup: somewhere there should be storage of dependencies. In my script,
> .java and .class files lived in the same directory (no -d option), and I
> added .dep files for each source as well in the same directory. Each
> .dep file was a text file with a list of dependencies, one per line,
> given as class names (outer classes only, no inner classes listed); it
> represents the dependencies in the source tree of the given class, not
> to include classes present in JARs and so on in the (non-source)
> classpath, nor including the class itself. Timestamp of the .dep file is
> significant. For efficiency, it would be possible to store a single deps
> database in some format, listing timestamp, dependent class name, and
> all source dependencies of that class. Or .dep files could be placed in
> a special separated directory.

It is neccessary to decide here do we want intermediate files generated
by ant?
If yes - dependancy tracking will work faster, but we need
to specify where to store this files cause this files could add some garbage
to distributive if will strore them in dest directory or add this garbage to
the source diectory.
If no - dependancy tracking will work slower, but we will not care about
As for me, I like first, cause what the faster solution is beter for me.

> Algorithm:
> 1. Prepare list of classes to compile. Scan the source tree (given
> includes/excludes, etc.) for source files. A source file is out of date
> if any of the following are true:
> 1a. It has no .class file.
> 1b. Its .class file is older than the source file.
> 1c. It has no .dep file.
> 1d. Its .dep file is older than the source file.
> 1e. One or more of the source files listed in its .dep file is missing.
> 1f. One or more of the source files listed in its .dep file is newer
> than the considered source file.
> 2. Run the selected Java compiler on the source files thus gleaned. It
> should not matter how that compiler does dependency analysis, or even if
> it does any; all required files ought to have been explicitly listed
> anyway.
> 3. Again using the same list of source files, find the freshly-compiled
> .class files and parse them. A full bytecode library should not be
> necessary, only ability to parse the constant pool. All classes
> referenced at compile time should be listed as class constants in this
> pool. (My original script simply grepped the binary .class file for
> likely references using a conservative approximation, but doing it right
> should not be that hard.) Remember to search all inner-class files.
> (JDK-1.0-style package-private outer classes might be a problem here--it
> may be necessary to check the "source" attribute in the class file to
> handle these.)

There are some tricky compiler behaviours here. Sometimes you cannot
receive all dependancy info from constant pool. Do not forget about
optimizer! I analyzed javac generated bytecode (1.2.2) and compared it
to jikes. Jikes fro example remove from constant pool unused classes,
but javac stores it there. That's why you cannot rely on jikes generated
.class file and you can on javac generated. Exist a lot of complex examples
using interfaces, inheritance, inner classes and static variables where very
difficult for you to track dependancies (indirect dependencies).

Here is simple one:
public class A extends B {
        public int a = 1;
        public A() {
        public static void main(String args[]) {
                new A();

public class B extends C {
        public int b = 2;
        void print() {

public class C implements I {
        public int c = 3;

public interface I {
        static int i = 100;

"A" and "B" constant pools don't contain anything about I.

In optimized code dependencies can be resolved only by java class
parsing (class file doesn't contain full info).


In general I agree with you and your algorithm looks pretty good. One
thing we need too decide: do we need .dep files or no?


View raw message