Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #14843 > unrolled thread
| Started by | Jason Kim <iamjsonkim@gmail.com> |
|---|---|
| First post | 2012-05-27 15:48 -0700 |
| Last post | 2012-05-28 22:56 -0700 |
| Articles | 12 — 5 participants |
Back to article view | Back to comp.lang.java.programmer
How are multiple Java files compiled together? Jason Kim <iamjsonkim@gmail.com> - 2012-05-27 15:48 -0700
Re: How are multiple Java files compiled together? Knute Johnson <nospam@knutejohnson.com> - 2012-05-27 16:34 -0700
Re: How are multiple Java files compiled together? Jason Kim <iamjsonkim@gmail.com> - 2012-05-27 16:47 -0700
Re: How are multiple Java files compiled together? Lew <noone@lewscanon.com> - 2012-05-27 20:18 -0700
Re: How are multiple Java files compiled together? Knute Johnson <nospam@knutejohnson.com> - 2012-05-27 21:08 -0700
Re: How are multiple Java files compiled together? Gene Wirchenko <genew@ocis.net> - 2012-05-28 09:32 -0700
Re: How are multiple Java files compiled together? Lew <noone@lewscanon.com> - 2012-05-28 22:35 -0700
Re: How are multiple Java files compiled together? Gene Wirchenko <genew@ocis.net> - 2012-05-29 09:20 -0700
Re: How are multiple Java files compiled together? Roedy Green <see_website@mindprod.com.invalid> - 2012-05-27 17:35 -0700
Re: How are multiple Java files compiled together? Roedy Green <see_website@mindprod.com.invalid> - 2012-05-27 19:34 -0700
Re: How are multiple Java files compiled together? Roedy Green <see_website@mindprod.com.invalid> - 2012-05-28 04:00 -0700
Re: How are multiple Java files compiled together? Lew <noone@lewscanon.com> - 2012-05-28 22:56 -0700
| From | Jason Kim <iamjsonkim@gmail.com> |
|---|---|
| Date | 2012-05-27 15:48 -0700 |
| Subject | How are multiple Java files compiled together? |
| Message-ID | <90a3f6ec-dfd4-472b-866d-98eaa92364d5@googlegroups.com> |
I am new to Java.
Here are two files.
VolcanoApplication.java
class VolcanoApplication {
public static void main(String[] arguments) {
VolcanoRobot dante = new VolcanoRobot();
dante.status = "exploring";
dante.speed = 2;
dante.temperature = 510;
dante.showAttributes();
System.out.println("Increasing speed to 3.");
dante.speed = 3;
dante.showAttributes();
System.out.println("Changing temperature to 670");
dante.temperature = 670;
dante.showAttributes();
System.out.println("Checking the temperature.");
dante.checkTemperatur();
dante.showAttributes();
}
}
VolcanoRobot.java
class VolcanoRobot {
String status;
int speed;
float temperature;
void checkTemperatur() {
if (temperature > 50) {
status = "returning home";
speed = 5;
}
}
void showAttributes() {
System.out.println("Status: " + status);
System.out.println("Speed: " + speed);
System.out.println("Temperature: " + temperature);
}
}
I compiled the program by doing
$ javac VolcanoApplication.java
But how does Java know that VolcanoRobot.java should also be in the compilation?
[toc] | [next] | [standalone]
| From | Knute Johnson <nospam@knutejohnson.com> |
|---|---|
| Date | 2012-05-27 16:34 -0700 |
| Message-ID | <jpudmj$m0h$1@dont-email.me> |
| In reply to | #14843 |
On 5/27/2012 3:48 PM, Jason Kim wrote:
> I am new to Java.
>
> Here are two files.
>
> VolcanoApplication.java
> class VolcanoApplication {
> public static void main(String[] arguments) {
> VolcanoRobot dante = new VolcanoRobot();
> dante.status = "exploring";
> dante.speed = 2;
> dante.temperature = 510;
>
> dante.showAttributes();
> System.out.println("Increasing speed to 3.");
> dante.speed = 3;
> dante.showAttributes();
> System.out.println("Changing temperature to 670");
> dante.temperature = 670;
> dante.showAttributes();
> System.out.println("Checking the temperature.");
> dante.checkTemperatur();
> dante.showAttributes();
> }
> }
>
> VolcanoRobot.java
> class VolcanoRobot {
> String status;
> int speed;
> float temperature;
>
> void checkTemperatur() {
> if (temperature> 50) {
> status = "returning home";
> speed = 5;
> }
> }
>
> void showAttributes() {
> System.out.println("Status: " + status);
> System.out.println("Speed: " + speed);
> System.out.println("Temperature: " + temperature);
> }
> }
>
> I compiled the program by doing
> $ javac VolcanoApplication.java
>
> But how does Java know that VolcanoRobot.java should also be in the compilation?
If it didn't know, think about what a pain that would be every time you
had to compile a program with a lot of files. You reference
VolcanoRobot in VolcanoApplication, the compiler looks for that that
class in the classpath and compiles it if necessary.
That feature can be the source of a very tricky problem and that is if
there is a VolcanoRobot.class file in the classpath the compiler won't
compile VolcanoRobot.java even if it has changed since the
VolcanoRobot.class file was created.
--
Knute Johnson
[toc] | [prev] | [next] | [standalone]
| From | Jason Kim <iamjsonkim@gmail.com> |
|---|---|
| Date | 2012-05-27 16:47 -0700 |
| Message-ID | <19fc754b-0501-46dc-ac81-3589c708e004@googlegroups.com> |
| In reply to | #14844 |
On Sunday, 27 May 2012 19:34:42 UTC-4, Knute Johnson wrote:
> On 5/27/2012 3:48 PM, Jason Kim wrote:
> > I am new to Java.
> >
> > Here are two files.
> >
> > VolcanoApplication.java
> > class VolcanoApplication {
> > public static void main(String[] arguments) {
> > VolcanoRobot dante = new VolcanoRobot();
> > dante.status = "exploring";
> > dante.speed = 2;
> > dante.temperature = 510;
> >
> > dante.showAttributes();
> > System.out.println("Increasing speed to 3.");
> > dante.speed = 3;
> > dante.showAttributes();
> > System.out.println("Changing temperature to 670");
> > dante.temperature = 670;
> > dante.showAttributes();
> > System.out.println("Checking the temperature.");
> > dante.checkTemperatur();
> > dante.showAttributes();
> > }
> > }
> >
> > VolcanoRobot.java
> > class VolcanoRobot {
> > String status;
> > int speed;
> > float temperature;
> >
> > void checkTemperatur() {
> > if (temperature> 50) {
> > status = "returning home";
> > speed = 5;
> > }
> > }
> >
> > void showAttributes() {
> > System.out.println("Status: " + status);
> > System.out.println("Speed: " + speed);
> > System.out.println("Temperature: " + temperature);
> > }
> > }
> >
> > I compiled the program by doing
> > $ javac VolcanoApplication.java
> >
> > But how does Java know that VolcanoRobot.java should also be in the compilation?
>
> If it didn't know, think about what a pain that would be every time you
> had to compile a program with a lot of files. You reference
> VolcanoRobot in VolcanoApplication, the compiler looks for that that
> class in the classpath and compiles it if necessary.
>
> That feature can be the source of a very tricky problem and that is if
> there is a VolcanoRobot.class file in the classpath the compiler won't
> compile VolcanoRobot.java even if it has changed since the
> VolcanoRobot.class file was created.
>
> --
>
> Knute Johnson
I didn't know Java compiler could be that smart.
As for the potential problem you mentioned, I don't think I'll have to worry about it any time soon. I won't be programming anything crazy complicated for some time.
Thanks Knute.
[toc] | [prev] | [next] | [standalone]
| From | Lew <noone@lewscanon.com> |
|---|---|
| Date | 2012-05-27 20:18 -0700 |
| Message-ID | <jpuqqg$md9$1@news.albasani.net> |
| In reply to | #14845 |
Jason Kim wrote:
> Knute Johnson wrote:
>> Jason Kim wrote:
>>> I am new to Java.
>>>
>>> Here are two files.
>>>
>>> VolcanoApplication.java
>>> class VolcanoApplication {
Get used to declaring top-level classes 'public':
public class VolcanoApplication
Once in a while you don't, but really almost never.
(The top-level class is the one whose name matches the file name.)
>>> public static void main(String[] arguments) {
>>> VolcanoRobot dante = new VolcanoRobot();
As you have learned, the "javac" compiler is smart enough to recognize the
reference to 'VolcanoRobot' and hunt down the source or class.
You absolutely do have to give the compiler some help. This help comes in two
forms: "sourcepath" and "classpath". (The JVM runner, "java", also knows about
"classpath".)
In your case, without any other specification, both paths by default are ".",
that means the current directory.
So when the compiler hunts the classpath, it looks in the current directory.
The first time it does not find "VolcanoRobot.class" in the classpath, so it
hunts for "VolcanoRobot.java" in the sourcepath. In your case, it found it
there, compiled it, then used the resulting "VolcanoRobot.class" in the classpath.
Next time you compile, if you have made no source changes that are newer than
the class files, it will skip the step.
If you compile just 'VolcanoApplication', and there are no newer changes to
'VolcanoRobot' the compiler will find the class file and be happy. If the
source is newer, the compiler will recompile "VolcanoRobot.java", then find
the class file and be happy.
...
>>> }
>>>
>>> VolcanoRobot.java
>>> class VolcanoRobot {
>>> ...
>>> }
>>>
>>> I compiled the program by doing
>>> $ javac VolcanoApplication.java
>>>
>>> But how does Java know that VolcanoRobot.java should also be in the compilation?
>>
>> If it didn't know, think about what a pain that would be every time you
>> had to compile a program with a lot of files. You reference
>> VolcanoRobot in VolcanoApplication, the compiler looks for that that
>> class in the classpath and compiles it if necessary.
>>
>> That feature can be the source of a very tricky problem and that is if
>> there is a VolcanoRobot.class file in the classpath the compiler won't
>> compile VolcanoRobot.java even if it has changed since the
>> VolcanoRobot.class file was created.
That is not always correct, only if the compiler can't find the source or if
the change is limited to compile-time constants.
"Note: Classes found through the classpath may be subject to automatic
recompilation if their sources are also found. See Searching For Types."
<http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javac.html>
> I didn't know Java compiler could be that smart.
> As for the potential problem you mentioned, I don't think I'll have to worry
> about it any time soon. I won't be programming anything crazy complicated for some time.
Never give yourself such an excuse to defer learning.
How do you know, as a self-admitted beginner, what you do and do not need to
learn?
As it happens, understanding how the compiler and JVM invoker work are among
the very first and most important things you should learn. It isn't about
whether what you do will be "crazy complicated", or even slightly complicated,
or even dog simple. It's about whether you can do anything at all.
<http://docs.oracle.com/javase/6/docs/technotes/tools/>
P.S., Don't quote sigs.
--
Lew
This is a sig (short for "signature"). It does not convey part of the main
conversation. No need to quote it.
[toc] | [prev] | [next] | [standalone]
| From | Knute Johnson <nospam@knutejohnson.com> |
|---|---|
| Date | 2012-05-27 21:08 -0700 |
| Message-ID | <jputnt$sea$1@dont-email.me> |
| In reply to | #14849 |
On 5/27/2012 8:18 PM, Lew wrote: > That is not always correct, only if the compiler can't find the source > or if the change is limited to compile-time constants. > "Note: Classes found through the classpath may be subject to automatic > recompilation if their sources are also found. See Searching For Types." > <http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javac.html> Lew: Did I mis-remember that or has it changed since version 4 or there abouts? I seem to remember a long thread here on this subject and I've always erased all my .class files before every compilation to avoid it. Have I generated my own myth? -- Knute Johnson
[toc] | [prev] | [next] | [standalone]
| From | Gene Wirchenko <genew@ocis.net> |
|---|---|
| Date | 2012-05-28 09:32 -0700 |
| Message-ID | <vr97s717126jijtd0jl0hjq8h8c6urkufk@4ax.com> |
| In reply to | #14850 |
On Sun, 27 May 2012 21:08:29 -0700, Knute Johnson
<nospam@knutejohnson.com> wrote:
[snip]
>Did I mis-remember that or has it changed since version 4 or there
>abouts? I seem to remember a long thread here on this subject and I've
>always erased all my .class files before every compilation to avoid it.
> Have I generated my own myth?
Maybe, but I can believe you had a difficulty that needed clean
compiles.
I had a problem with jCreator where I was using code from a
textbook on an assignment. (Many of the exercises used textbook
source code.) I had to compile the textbook source code, but then
subsequent compilations would fail claiming that the textbook source
code was not valid Java code! The solution^Whorrible kludge was to
the delete the textbook source code used after the first compilation.
When things like this happen, I am not surprised that people get
shy. I prefer clean, full compiles myself.
Sincerely,
Gene Wirchenko
[toc] | [prev] | [next] | [standalone]
| From | Lew <noone@lewscanon.com> |
|---|---|
| Date | 2012-05-28 22:35 -0700 |
| Message-ID | <jq1n6r$6fa$1@news.albasani.net> |
| In reply to | #14867 |
Gene Wirchenko wrote: > Knute Johnson wrote: > [snip] > >> Did I mis-remember that or has it changed since version 4 or there >> abouts? I seem to remember a long thread here on this subject and I've >> always erased all my .class files before every compilation to avoid it. >> Have I generated my own myth? I live in the now. I don't know what you remember, nor how well, nor what changed. > Maybe, but I can believe you had a difficulty that needed clean > compiles. +1 > I had a problem with jCreator where I was using code from a > textbook on an assignment. (Many of the exercises used textbook > source code.) I had to compile the textbook source code, but then > subsequent compilations would fail claiming that the textbook source > code was not valid Java code! The solution^Whorrible kludge was to > the delete the textbook source code used after the first compilation. Or put it in it own JAR. Or figure out why it went wrong and solve it from understanding. > When things like this happen, I am not surprised that people get > shy. I prefer clean, full compiles myself. The Java compiler does the best it can to resolve dependencies. It can't cover a lot of scenarios, and it can really lose it over sometimes having source in the sourcepath and sometimes not. It treats constants (as the JLS defines them) differently from other immutable or mutable expressions. Clean compiles are fine for your non-library (not in JARs) code and sometimes necessary. We're not supposed to behave by superstition, but clean compile is a prevalent and fairly harmless one. Better protection is to organize your code into JARs, where you never compile upstream JARs except when you work on their projects explicitly. I espouse full knowledge of the rules, but I struggle to stay up on the corner cases myself. I keep returning to study them, and discussions like this one help to elucidate them. For dependencies beyond what javac can handle, we have Ant. That why we have Ant. I am jaundiced by project after project after project where I've stepped in the build mess left by predecessors who created build systems by cult ritual. One of the worst was a "refactoring" of the build consigned to a contract company that claimed great expertise and tangled the ball of yarn even further. (That one used Maven, which complicated the repair process.) Build and deployment procedures require even more professionalism, diligence and attention to detail than program code. -- Lew -- Lew Honi soit qui mal y pense. http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
[toc] | [prev] | [next] | [standalone]
| From | Gene Wirchenko <genew@ocis.net> |
|---|---|
| Date | 2012-05-29 09:20 -0700 |
| Message-ID | <gjt9s79rk07h30s2cu7id3huhktcj28qjh@4ax.com> |
| In reply to | #14875 |
On Mon, 28 May 2012 22:35:41 -0700, Lew <noone@lewscanon.com> wrote:
>Gene Wirchenko wrote:
>> Knute Johnson wrote:
>> [snip]
>>
>>> Did I mis-remember that or has it changed since version 4 or there
>>> abouts? I seem to remember a long thread here on this subject and I've
>>> always erased all my .class files before every compilation to avoid it.
>>> Have I generated my own myth?
>
>I live in the now. I don't know what you remember, nor how well, nor what changed.
>
>> Maybe, but I can believe you had a difficulty that needed clean
>> compiles.
>
>+1
>
>> I had a problem with jCreator where I was using code from a
>> textbook on an assignment. (Many of the exercises used textbook
>> source code.) I had to compile the textbook source code, but then
>> subsequent compilations would fail claiming that the textbook source
>> code was not valid Java code! The solution^Whorrible kludge was to
>> the delete the textbook source code used after the first compilation.
>
>Or put it in it own JAR.
>
>Or figure out why it went wrong and solve it from understanding.
Easy to say. Not necessarily easy to do.
The error message was quite misleading. The solution was by
accident. There was nothing that I could see that would help me in
tracking down the cause of the problem.
While I do like solving problems, sometimes, there is no clean
solution.
>> When things like this happen, I am not surprised that people get
>> shy. I prefer clean, full compiles myself.
This still fits.
>The Java compiler does the best it can to resolve dependencies. It can't cover
>a lot of scenarios, and it can really lose it over sometimes having source in
>the sourcepath and sometimes not. It treats constants (as the JLS defines
>them) differently from other immutable or mutable expressions.
Well, it sure seems to have done that here.
>Clean compiles are fine for your non-library (not in JARs) code and sometimes
>necessary. We're not supposed to behave by superstition, but clean compile is
>a prevalent and fairly harmless one.
It does remove the problem of loss of synchronisation.
[snip]
Sincerely,
Gene Wirchenko
[toc] | [prev] | [next] | [standalone]
| From | Roedy Green <see_website@mindprod.com.invalid> |
|---|---|
| Date | 2012-05-27 17:35 -0700 |
| Message-ID | <ush5s7losci9deken8k09qpbia9nqku6s5@4ax.com> |
| In reply to | #14843 |
On Sun, 27 May 2012 15:48:01 -0700 (PDT), Jason Kim <iamjsonkim@gmail.com> wrote, quoted or indirectly quoted someone who said : >But how does Java know that VolcanoRobot.java should also be in the compilation? 1. say javac *.java 2. compiler sees you calling some method and it can't find the class file for it. So it looks on the sourcepath for the *.java file to compile. 3. It can compare the dates on the class file and corresponding *.java file. If the *.java file is newer it knows to recompile. see http://mindprod.com/jgloss/javac.html 4. Use ANT. See http://mindprod.com/jgloss/ant.html -- Roedy Green Canadian Mind Products http://mindprod.com I would be quite surprised if the NSA (National Security Agency) did not have a computer program to scan bits of shredded documents and electronically put them back together like a giant jigsaw puzzle. This suggests you cannot just shred, you must also burn. .
[toc] | [prev] | [next] | [standalone]
| From | Roedy Green <see_website@mindprod.com.invalid> |
|---|---|
| Date | 2012-05-27 19:34 -0700 |
| Message-ID | <rso5s71koad7qf0m8i37t975h9b9vc6aie@4ax.com> |
| In reply to | #14846 |
On Sun, 27 May 2012 17:35:05 -0700, Roedy Green <see_website@mindprod.com.invalid> wrote, quoted or indirectly quoted someone who said : >3. It can compare the dates on the class file and corresponding *.java >file. If the *.java file is newer it knows to recompile. >see http://mindprod.com/jgloss/javac.html This gives me trouble all the time. Javac can recompile code with target 1.7 that was intended to be compiled with 1.6 if it gets recompiled as a side effect of compilng something with 1.7. I wrote a utility http://mindprod.com/products1.html#JARCHECK to make sure everything is the version it is supposed to be. If it is out of whack, I manually clean compile it. If it is really screwed up, I do a clean rebuild of everything. -- Roedy Green Canadian Mind Products http://mindprod.com I would be quite surprised if the NSA (National Security Agency) did not have a computer program to scan bits of shredded documents and electronically put them back together like a giant jigsaw puzzle. This suggests you cannot just shred, you must also burn. .
[toc] | [prev] | [next] | [standalone]
| From | Roedy Green <see_website@mindprod.com.invalid> |
|---|---|
| Date | 2012-05-28 04:00 -0700 |
| Message-ID | <7im6s7leho1fhnqd28lcbmpg7c18hbj2hi@4ax.com> |
| In reply to | #14846 |
On Sun, 27 May 2012 17:35:05 -0700, Roedy Green <see_website@mindprod.com.invalid> wrote, quoted or indirectly quoted someone who said : >3. It can compare the dates on the class file and corresponding *.java >file. If the *.java file is newer it knows to recompile. >see http://mindprod.com/jgloss/javac.html There is a gotcha. If have a static final constant X in class A. Class B references X. You modify the value of X. The compeller will be smart enough to recompile A, but not B. It should recompile B, because of constant inlining. When you update non-private constant values, do a clean compile of everything to get the inlined constant values propagated. -- Roedy Green Canadian Mind Products http://mindprod.com Controlling complexity is the essence of computer programming. ~ Brian W. Kernighan 1942-01-01 .
[toc] | [prev] | [next] | [standalone]
| From | Lew <noone@lewscanon.com> |
|---|---|
| Date | 2012-05-28 22:56 -0700 |
| Message-ID | <jq1od6$8bu$1@news.albasani.net> |
| In reply to | #14860 |
Roedy Green wrote: >> 3. It can compare the dates on the class file and corresponding *.java >> file. If the *.java file is newer it knows to recompile. >> see http://mindprod.com/jgloss/javac.html > > There is a gotcha. > If have a static final constant X in class A. I think it applies to instance and local constants also. > Class B references X. > > You modify the value of X. > > The compeller will be smart enough to recompile A, but not B. It > should recompile B, because of constant inlining. "Should"? What do you mean by that? The constant, by virtue of it being a constant, is in the B class as a constant. It is not a reference because it's a constant. Class B has no way of knowing that the constant once had a label in another class. Because it's a constant. That's the way it is. I do not express an opinion on how it should be. The JLS does explain why that is, though. > When you update non-private constant values, do a clean compile of > everything to get the inlined constant values propagated. We create non-private constants, but we really aren't supposed to. "Other than for true mathematical constants, we recommend that source code make very sparing use of class variables that are declared static and final. If the read-only nature of final is required, a better choice is to declare a private static variable and a suitable accessor method to get its value." <http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.9> BTW, public, don't confuse constants with "static final" variables. Only some of the latter are the former, and some of the former are not the latter. The JLS doesn't restrict the definition of "constant variable" to static variables, or even member variables. <http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4> "A variable of primitive type or type _String_, that is _final_ and initialized with a compile-time constant expression (§15.28), is called a /constant variable/." One of the implications: "One other thing to note is that static final fields that have constant values (whether of primitive or String type) must never appear to have the default initial value for their type (§4.12.5). This means that all such fields appear to be initialized first during class initialization (§8.3.2.1, §9.3.1, §12.4.2)." [op. cit.] -- Lew Honi soit qui mal y pense. http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web