From: Andreas Leitgeb on
Mike Schilling <mscottschilling(a)hotmail.com> wrote:
>> Now B has a dependency on A. If A changes, for any reason: [...]
>> then B has to recompiled. That's pretty standard stuff I think. There
>> really isn't any need to detect an overloaded method, this
>> simple dependency graph catches it, and many other cases too.
> The overload is a subtle case, because the added method isn;t actually used
> by anyone, so dependencies at the granularity of method usage won't catch
> it. (Unless you conflate all overloads as being "the same method", which is
> probably a good idea.)

Or, somewhat finer-grained: conflate all overloaded methods that take the
same number of arguments - with some special reasoning about varargs...

Another approach was: Maintain a database of each .class's API,
and if, after an incremental build, any recompiled class has a
changed API, or any class was removed, or added, then do a clean
build. Insert "non-private" whereever you find it appropriate.

From: Joshua Maurice on
On May 1, 7:38 am, Lew <no...(a)lewscanon.com> wrote:
> Joshua Maurice wrote:
> > So, I post here because I feel better prepared to discuss this
> > subject. I still disagree that "build from clean" is the correct
> > answer. That would make our product's build still around ~25 minutes
> > for just the Java compilation of around ~20,000 source files (and
> > growing). There must / should be something better. Separation
> > translation units make so much sense. I just wish Java had them.
>
> What, you never heard of JAR files?
>
> There's no excuse for "build clean" having to touch all 20K files.

And what if all of the code is under active development, aka new
features are being added to each layer on a weekly basis?

And what if a large portion of that Java code is generated from a
model file to facilitate serialization between C++ and Java? Thus a
change to a single file would require recompiling a large amount of
generated "interface" files, which theoretically touches a large
portion of the 20,000 Java files.

And that's still no excuse to not having an incremental compile. Even
if componentized, with a full clean build every time, that could be 5
to 10 minutes lost of my work for every compile which is just wasted
time.
From: Joshua Maurice on
On May 1, 9:02 am, markspace <nos...(a)nowhere.com> wrote:
> Joshua Maurice wrote:
> > So, I post here because I feel better prepared to discuss this
> > subject. I still disagree that "build from clean" is the correct
> > answer.
>
> Ant can do most kinds of Java source dependencies for you:
>
> <http://ant.apache.org/manual/OptionalTasks/depend.html>

Please read the paper in my opening post. Then, consider that a build
machine cannot (easily) distinguish between "most" and "all". I want a
fully correct incremental build. A 90% correct incremental build is
useful to nearly no one, as you would do many sanity-check clean
builds.
From: Joshua Maurice on
On May 1, 10:43 am, Lew <no...(a)lewscanon.com> wrote:
> Mike Schilling wrote:
> > "The most obvious example of these limitations is that the task can't tell
> > which classes to recompile when a constant primitive data type exported by
> > other classes is changed. For example, a change in the definition of
> > something like
> > public final class Constants {
> >   public final static boolean DEBUG=false;
> > }
>
> > will not be picked up by other classes. "
>
> > That is, it's an incremental (no pun intended) improvement on the usual Ant
> > algorithm of "recompile what onviouslt needs recompilation; if that doesn't
> > seem to work, do a clean build"
>
> You can't blame Ant for that one.  The class that depends on the compile-time
> constant, such as 'DEBUG' in your example, compiles the constant into its
> class, not the symbol.  Without some external indication of the dependency,
> there's not any way for a compiler or build tool to detect that it exists..
>
> With respect to dependencies where the symbol is stored in the class rather
> than its value, even 'javac' handles the situation pretty well.

I'm not blaming anyone in particular. I just want to know how to get a
fully correct, aka 100% incremental build under the actions: adding,
removing, modifying java files, and adding, removing, or modifying
build steps of "take these jars, compile them to class files, then jar
them", aka the standard developer actions.
From: Joshua Maurice on
On May 1, 11:24 am, Lew <no...(a)lewscanon.com> wrote:
> Lew wrote:
> >> The class that depends on the
> >> compile-time constant, such as 'DEBUG' in your example, compiles the
> >> constant into its class, not the symbol.  Without some external
> >> indication of the dependency, there's not any way for a compiler or
> >> build tool to detect that it exists.
> Mike Schilling wrote:
> > Other than by noting it when the symbol is used during compilation, and
> > storing that bit of information somewhere.  But the details of that get
> > messy.
>
> I said that there is no way, not that there couldn't be a way.
>
> Lew wrote:
> >> With respect to dependencies where the symbol is stored in the class
> >> rather than its value, even 'javac' handles the situation pretty well.
> Mike Schilling wrote:
> > There are other difficult cases, like a method being added in class A that
> > results in a method in B (one of A's descendents) becoming overloaded, such
> > that a client of B should now choose the new overload.  Java really makes
> > this stuff hard.  (C# is no better.)
>
> How would any language handle this?
>
> Short of a class being aware of every possible past, present and future
> extension of it.
>
> You do present a good argument against overuse of inheritance.

Read the paper in my opening post, Ghost Dependencies.