Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #14843 > unrolled thread

How are multiple Java files compiled together?

Started byJason Kim <iamjsonkim@gmail.com>
First post2012-05-27 15:48 -0700
Last post2012-05-28 22:56 -0700
Articles 12 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  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

#14843 — How are multiple Java files compiled together?

FromJason Kim <iamjsonkim@gmail.com>
Date2012-05-27 15:48 -0700
SubjectHow 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]


#14844

FromKnute Johnson <nospam@knutejohnson.com>
Date2012-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]


#14845

FromJason Kim <iamjsonkim@gmail.com>
Date2012-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]


#14849

FromLew <noone@lewscanon.com>
Date2012-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]


#14850

FromKnute Johnson <nospam@knutejohnson.com>
Date2012-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]


#14867

FromGene Wirchenko <genew@ocis.net>
Date2012-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]


#14875

FromLew <noone@lewscanon.com>
Date2012-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]


#14889

FromGene Wirchenko <genew@ocis.net>
Date2012-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]


#14846

FromRoedy Green <see_website@mindprod.com.invalid>
Date2012-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]


#14848

FromRoedy Green <see_website@mindprod.com.invalid>
Date2012-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]


#14860

FromRoedy Green <see_website@mindprod.com.invalid>
Date2012-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]


#14876

FromLew <noone@lewscanon.com>
Date2012-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