Re: Incremental Java Compile
On May 14, 4:15 am, Steven Simpson <s...@domain.invalid> wrote:
On 12/05/10 22:35, Joshua Maurice wrote:
Bad news. It appears that class files do not contain the necessary
dependency information for my goal of not rebuilding all java files
downstream. Ex:
//AA.java
public class AA { public final int x = 1; }
//BB.java
public class BB { public int x = new AA().x; }
//javap -verbose -classpath . BB
Compiled from "BB.java"
public class BB extends java.lang.Object
SourceFile: "BB.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #7.#19; // java/lang/Object."<init>"=
:()V
const #2 = class #20; // AA
Surely, you /do/ have enough information in this case, as BB.class
refers to AA in order to call 'new AA()' in order to get AA#x. You
don't specifically need to know that BB uses AA#x, do you? ...just tha=
t
BB uses AA.
Only if AA#x was static would you be able to write AA.x, which would be
inlined with no reference to AA.
A simple example of my goal is the following, for the appropriate
definition of "using":
A uses B
B uses C.
I modify C. I need to rebuild C. If C's classfile has the same binary
contents, then no further work needs to be done. Otherwise, I need to
rebuild B. If B's classfile has the same binary contents, then no
further work needs to be done. Otherwise, I need to rebuild A.
Put more simply, I want a system where I do not have to rebuild all
java files downstream. I think that it is unnecessary to do such a
thing, and a lot of time could be saved if you could identify a point
where a change no longer "ripples" down the dependency chain.
Let's take a slight alteration of the example from the previous
post:
//AA.java
public class AA { public final int x = 1; }
//BB.java
public class BB extends AA {}
//CC.java
public class CC { public final int x = new BB().x; }
When javac compiles CC.java, it loads BB.class, looks for a member
named x, finds no such member, then loads AA.class, and finds member
x. javac's verbose output contains this information.
The class file CC.class does not refer to "AA" or "x". It calls BB's
constructor, and it hardcodes "1" through the JVM instruction
iconst_1.
With just the information available in the class files, I don't think
it would be possible to detect when the change cascading down the
dependency graph can have no further effects. To know when the cascade
is done, I need the full compile dependencies, specifically "CC uses
AA". (I also need ghost dependencies, as mentioned else-thread.)
Note that there is no analogy between the first and second examples of
this post. The first example is "A uses B, and B uses C". For the
second example, I would say "BB uses AA, CC uses BB, and CC uses AA."
Maybe one day I'll get even fancier, and instead of "same class file
binary contents", I'll use something like "same super class, same
interface, same methods".