>1) Is it only the static final constants that have this discontinuity in
>javac's dependency checking? Usually such constants are used as manifest
>constants, in the old K&R C language sense, and rarely are changed.
Yes, even though javac has other problems [see the post by Misha
Dmitriev], none of them are insurmountable, except for this one [AFAIK].
The static final issue may not be a big deal to some, but I use ANT for
building enterprise software [$$$] and make damn sure the production
builds are produced out of a "clean" state so that nothing is incremental.
>2) I couldn't find any documentation to support that this is possibly a
>language issue, that it is consistent with the language definition.
Anybody
>disagree?
Perhaps my statement could have been more precise: this issue is caused by
the combination of Java language, .class format, and Java bytecode specs.
Ostensibly, at the language level this allows us to have a limited support
for conditional compilation [i.e. the block in "if (DEBUG) {....}" does
not result in any bytecode emitted if DEBUG is static final but not so if
it is merely static or has a runtime init expression]. At the .class and
bytecode leveIs this conversion of constants to literals makes tableswitch
and lookupswitch opcodes work [used for Java "case" statements]. I can't
provide any "official" spec references right now but you can check out
"Compile-Time Resolution of Constants" in chapter 8 of "Inside the JVM" by
Bill Venners.
To be fair, every JVM is required to support .class format but it does not
have to be the only format a JVM supports. But of course the .class format
is the de facto standard nowadays. It is conceivable to use a completely
custom compiler and bytecode packaging that has extra metadata needed for
correct incremental building. But this is probably too much work because
the JVM spec allows custom attributes in .class files (there is a required
set, a set that should be supported with reserved meanings, and then you
can add your own attributes to your heart's content) -- in fact, this is
precisely the option being entertained by Sun according to Misha's post
earlier in this thread.
>3) Would it be a good guess that Sun has given up on real dependency
checking
>in the javac compiler? I notice that -Xdepend is dropped from the 1.3.1
>compiler.
My answer would have been yes before I learned about javamake and the
changes being considered for JDK 1.5. By JDK 1.101 we should have a pretty
good language to work with :-) ...
Have fun and my apologies to the rest of the group for straying too far
from pure ANT matters,
Vlad.
Please respond to "Ant Users List" <[EMAIL PROTECTED]>
To: Ant Users List <[EMAIL PROTECTED]>
cc:
Subject: Re: newbie question: javac not checking build dependencies?
Thanks, Vlad, for taking the time to describe the problem in detail. I
tried it
out and you are correct. I even tried oldjavac -Xdepend, which was
fruitless.
I still have some questions before I can say I'm satisfied completely.
1) Is it only the static final constants that have this discontinuity in
javac's dependency checking? Usually such constants are used as manifest
constants, in the old K&R C language sense, and rarely are changed.
2) I couldn't find any documentation to support that this is possibly a
language issue, that it is consistent with the language definition.
Anybody
disagree?
3) Would it be a good guess that Sun has given up on real dependency
checking
in the javac compiler? I notice that -Xdepend is dropped from the 1.3.1
compiler.
[EMAIL PROTECTED] wrote:
> If class A uses a static final int constant "FIVE" from class B (let's
say
> it evaluates to "5"), that constant is not embedded in A as a symbolic
> link to "B.FIVE". Instead, the _literal value_ 5 is emitted into the
> bytecode in A.class file. That's it, the dependency of A on B is _lost_
at
> that point. If javac locates A.class during any variation of the scheme
> that you refer to, it has no need to look further for B.java or B.class,
> because A.class already contains everything it may need and no extra
type
> information about field FIVE is required [in fact, javac can't even know
> there is such a field by looking at A.class only]. If B is later
> recompiled separately, A.class and B.class will be out of synch.
>
> If <depend> does not handle static finals like the javamake tool, it can
> produce invalid builds in incremental mode. In all fairness, I have not
> gone through the sources to ascertain one way or another, but that's why
I
> gave my warning earlier in the thread. javamake's solution is a bit of
an
> overkill, but at least it's documented and is guaranteed to be correct.
>
> The dependency of A on B through static final constants can only be
> resurrected by parsing the sources. This is a fundamental problem with
> Java itself and no "depends"-like tool will solve this problem correctly
> without using either the javamake approach or by parsing the sources.
> C/C++ has no issue here because #include's could be recovered from the
> sources very easily. But once you start parsing Java sources, you find
> that it's half of the job of compiling everything already, so you might
> instead just do that.
>
> Vlad.
>
> P.S. Interestingly enough, by now Sun could have added a new attribute
to
> .class format that could be used to simulate symbolic links for all
static
> finals that got optimized into literals. Then we could have had a
perfect
> depends tool...
>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>