Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #35110 > unrolled thread
| Started by | parmenides <xparmenides@yahoo.com> |
|---|---|
| First post | 2016-07-24 00:55 +0800 |
| Last post | 2016-07-23 19:06 -0400 |
| Articles | 12 — 5 participants |
Back to article view | Back to comp.lang.java.programmer
Is it necessary the source file should be at the same location with the class file? parmenides <xparmenides@yahoo.com> - 2016-07-24 00:55 +0800
Re: Is it necessary the source file should be at the same location with the class file? Steven Simpson <ss@my.domain.invalid> - 2016-07-23 20:10 +0100
Re: Is it necessary the source file should be at the same location with the class file? Arne Vajhøj <arne@vajhoej.dk> - 2016-07-23 19:05 -0400
Re: Is it necessary the source file should be at the same location with the class file? Steven Simpson <ss@my.domain.invalid> - 2016-07-24 08:42 +0100
Re: Is it necessary the source file should be at the same location with the class file? Arne Vajhøj <arne@vajhoej.dk> - 2016-07-24 07:47 -0400
Re: Is it necessary the source file should be at the same location with the class file? Steven Simpson <ss@my.domain.invalid> - 2016-07-24 22:08 +0100
Re: Is it necessary the source file should be at the same location with the class file? Martin Gregorie <martin@address-in-sig.invalid> - 2016-07-24 21:28 +0000
Re: Is it necessary the source file should be at the same location with the class file? Arne Vajhøj <arne@vajhoej.dk> - 2016-07-24 18:06 -0400
Re: Is it necessary the source file should be at the same location with the class file? Steven Simpson <ss@my.domain.invalid> - 2016-07-25 21:21 +0100
Re: Is it necessary the source file should be at the same location with the class file? Arne Vajhøj <arne@vajhoej.dk> - 2016-07-25 21:03 -0400
Re: Is it necessary the source file should be at the same location with the class file? Roedy Green <inquiry@mindprod.com> - 2016-07-26 15:24 -0700
Re: Is it necessary the source file should be at the same location with the class file? Arne Vajhøj <arne@vajhoej.dk> - 2016-07-23 19:06 -0400
| From | parmenides <xparmenides@yahoo.com> |
|---|---|
| Date | 2016-07-24 00:55 +0800 |
| Subject | Is it necessary the source file should be at the same location with the class file? |
| Message-ID | <nn07hl$8ti$1@gioia.aioe.org> |
Hi,
I try to understand the relationship of the souce file and the class
file. I have the following file cascade:
work/Test.java
work/Circle.java
work/compute/shape/
The Test.java is written:
import compte.shape.*;
public class Test {
public static void main(String[] args) {
Circle c = new Circle(3);
System.out.println(c.circleArea());
}
}
The Circle.java is written:
package compute.shape;
public class Circle{
double radius;
public Circle(double radius){
this.radius = radius;
}
public double circleArea() {
return Math.PI*radius*radius;
}
}
I compiled the Circle.java and copied the Circle.class to the
compute/shape directory:
javac Circle.java
cp Circle.class compute/shape
Then, I compiled the Test.java:
javac Test.java
I got a message like this:
Test.java:5: error: cannot access Circle
Circle c = new Circle();
I modified the first line of Test.java as follows:
import compte.shape.*;
===>
import compte.shape.Circle;
I compiled the Test.java again:
javac Test.java
and it is all right.
Then, I moved the Circle.java to compute/shape directory
mv Circle.java compute/shape
and changed the Test.java back:
import compte.shape.Circle;
===>
import compte.shape.*;
At last, the compiling of the Test.java is correct.
It seems that the source file should be at the same location as the
class file.Is this right? Why the compiling is wrong? Thanks.
[toc] | [next] | [standalone]
| From | Steven Simpson <ss@my.domain.invalid> |
|---|---|
| Date | 2016-07-23 20:10 +0100 |
| Message-ID | <v2sc6d-u2p.ln1@s.simpson148.btinternet.com> |
| In reply to | #35110 |
On 23/07/16 17:55, parmenides wrote:
> package compute.shape;
> public class Circle{ [snip]
>
> I compiled the Circle.java and copied the Circle.class to the
> compute/shape directory:
>
> javac Circle.java
> cp Circle.class compute/shape
>
> Then, I compiled the Test.java:
>
> javac Test.java
>
> I got a message like this:
>
> Test.java:5: error: cannot access Circle
> Circle c = new Circle();
Did it not also say the following?:
bad class file: ./Circle.class
class file contains wrong class: compute.shape.Circle
Please remove or make sure it appears in the correct subdirectory of the classpath.
1 error
> I modified the first line of Test.java as follows:
>
> import compte.shape.*;
> ===>
> import compte.shape.Circle;
(The typo in the package name won't help.) With the whole-package
import, javac first tries to interpret the name Circle as a class in the
default package (which the referencing class belongs to). Lo and
behold, there is a file called Circle.class in the current directory
(the default classpath), so it tries to read the definition from there.
However, it declares itself to be the definition of
compute.shape.Circle, not Circle, and you get the error above.
If you remove Circle.class, javac finds Circle.java, and tries to
compile it, and reports a similar error.
Keep the source file in the same position in the directory hierarchy as
the class file to avoid confusion. They don't have to be in the same
directory tree (using -sourcepath, -classpath and -d), just the same
relative position within their respective trees.
--
ss at comp dot lancs dot ac dot uk
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-07-23 19:05 -0400 |
| Message-ID | <nn0t8n$17np$1@gioia.aioe.org> |
| In reply to | #35110 |
On 7/23/2016 12:55 PM, parmenides wrote: > I try to understand the relationship of the souce file and the class > file. > It seems that the source file should be at the same location as the > class file.Is this right? Why the compiling is wrong? For small projects you can use .java and .class files in same dir tree matching package structure. projectroot/mypackage/MyClass.java projectroot/mypackage/MyClass.class Remember to have projectroot in classpath. For bigger projects then I will recomment having a src tree and a bin tree for .java and .class respectively. projectroot/src/mypackage/MyClass.java projectroot/bin/mypackage/MyClass.class Remember to have projectroot/bin in classpath. Arne
[toc] | [prev] | [next] | [standalone]
| From | Steven Simpson <ss@my.domain.invalid> |
|---|---|
| Date | 2016-07-24 08:42 +0100 |
| Message-ID | <q38e6d-nn9.ln1@s.simpson148.btinternet.com> |
| In reply to | #35113 |
On 24/07/16 00:05, Arne Vajhøj wrote: > projectroot/mypackage/MyClass.class > > Remember to have projectroot in classpath. > projectroot/bin/mypackage/MyClass.class > > Remember to have projectroot/bin in classpath. Do you mean just for executing, or for compiling (too)? -- ss at comp dot lancs dot ac dot uk
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-07-24 07:47 -0400 |
| Message-ID | <nn29sl$old$1@gioia.aioe.org> |
| In reply to | #35124 |
On 7/24/2016 3:42 AM, Steven Simpson wrote: > On 24/07/16 00:05, Arne Vajhøj wrote: >> projectroot/mypackage/MyClass.class >> >> Remember to have projectroot in classpath. > >> projectroot/bin/mypackage/MyClass.class >> >> Remember to have projectroot/bin in classpath. > > Do you mean just for executing, or for compiling (too)? For: * excecuting * compiling if multiple compiles Arne
[toc] | [prev] | [next] | [standalone]
| From | Steven Simpson <ss@my.domain.invalid> |
|---|---|
| Date | 2016-07-24 22:08 +0100 |
| Message-ID | <8bnf6d-sua.ln1@s.simpson148.btinternet.com> |
| In reply to | #35125 |
On 24/07/16 12:47, Arne Vajhøj wrote: > On 7/24/2016 3:42 AM, Steven Simpson wrote: >> On 24/07/16 00:05, Arne Vajhøj wrote: >>> projectroot/mypackage/MyClass.class >>> >>> Remember to have projectroot in classpath. >> >>> projectroot/bin/mypackage/MyClass.class >>> >>> Remember to have projectroot/bin in classpath. >> >> Do you mean just for executing, or for compiling (too)? > > For: > * excecuting > * compiling if multiple compiles With the output directory in the classpath, doesn't it mean that javac will attempt a kind of incremental build? And doesn't it then miss some not particularly extraordinary cases (inlined constants; return types), leading to broken builds? ISTR it being discussed here not so long ago, but haven't found the thread. -- ss at comp dot lancs dot ac dot uk
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2016-07-24 21:28 +0000 |
| Message-ID | <nn3btn$36d$1@dont-email.me> |
| In reply to | #35130 |
On Sun, 24 Jul 2016 22:08:24 +0100, Steven Simpson wrote: > On 24/07/16 12:47, Arne Vajhøj wrote: >> On 7/24/2016 3:42 AM, Steven Simpson wrote: >>> On 24/07/16 00:05, Arne Vajhøj wrote: >>>> projectroot/mypackage/MyClass.class >>>> >>>> Remember to have projectroot in classpath. >>> >>>> projectroot/bin/mypackage/MyClass.class >>>> >>>> Remember to have projectroot/bin in classpath. >>> >>> Do you mean just for executing, or for compiling (too)? >> >> For: >> * excecuting * compiling if multiple compiles > > With the output directory in the classpath, doesn't it mean that javac > will attempt a kind of incremental build? And doesn't it then miss some > not particularly extraordinary cases (inlined constants; return types), > leading to broken builds? ISTR it being discussed here not so long ago, > but haven't found the thread. The following assumes you're using ant to control compiles, etc. I've seen that problem in the past, but not recently. However, it never hurts to add a 'clean' <target>, that removes all *.class and *.jar files that a build generates, to your build.xml and running "ant clean; ant" periodically. If you follow the 'large project' advice and separate *.class files from the source files, then using 'ant' or an equivalent program to manage compilation will make using the separation rather easier. -- martin@ | Martin Gregorie gregorie. | Essex, UK org |
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-07-24 18:06 -0400 |
| Message-ID | <nn3e5r$dk1$1@gioia.aioe.org> |
| In reply to | #35130 |
On 7/24/2016 5:08 PM, Steven Simpson wrote: > On 24/07/16 12:47, Arne Vajhøj wrote: >> On 7/24/2016 3:42 AM, Steven Simpson wrote: >>> On 24/07/16 00:05, Arne Vajhøj wrote: >>>> projectroot/mypackage/MyClass.class >>>> >>>> Remember to have projectroot in classpath. >>> >>>> projectroot/bin/mypackage/MyClass.class >>>> >>>> Remember to have projectroot/bin in classpath. >>> >>> Do you mean just for executing, or for compiling (too)? >> >> For: >> * excecuting >> * compiling if multiple compiles > > With the output directory in the classpath, doesn't it mean that javac > will attempt a kind of incremental build? And doesn't it then miss some > not particularly extraordinary cases (inlined constants; return types), > leading to broken builds? ISTR it being discussed here not so long ago, > but haven't found the thread. Multiple compiles in single build can cause this. I am just saying that if you do multiple compiles and separate bin dir tree then you will need to have bin in classpath. The problem you mention is real and need to be handled. There are ways to do that via various build scripts from OS shell to ant to newer build frameworks. Arne
[toc] | [prev] | [next] | [standalone]
| From | Steven Simpson <ss@my.domain.invalid> |
|---|---|
| Date | 2016-07-25 21:21 +0100 |
| Message-ID | <209i6d-u46.ln1@s.simpson148.btinternet.com> |
| In reply to | #35132 |
On 24/07/16 23:06, Arne Vajhøj wrote:
> On 7/24/2016 5:08 PM, Steven Simpson wrote:
>> With the output directory in the classpath, doesn't it mean that javac
>> will attempt a kind of incremental build? And doesn't it then miss some
>> not particularly extraordinary cases (inlined constants; return types),
>> leading to broken builds?
> The problem you mention is real and need to be handled. There are
> ways to do that via various build scripts from OS shell to ant to
> newer build frameworks.
I was not convinced that Ant would be enough, as the <javac> task
behaves largely as [javac -classpath out -d out], comparing timestamps
of corresponding .java and .class files, so it's exposed to the same
problems. Combining <depend> with <javac> should do better, but it
looked like it would still miss inlined constants, so I tried it out:
mkdir src
cat > build.xml <<EOF
<project>
<target name="clean">
<delete dir="build" />
</target>
<target name="compile">
<mkdir dir="build/classes" />
<!-- depend srcDir="src" destdir="build/classes"
cache="build/depcache" / -->
<javac srcdir="src" destdir="build/classes" />
</target>
<target name="jar">
<mkdir dir="build/jar" />
<jar destfile="build/jar/test.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="A" />
</manifest>
</jar>
</target>
<target name="run">
<java jar="build/jar/test.jar" fork="true" />
</target>
</project>
EOF
cat > src/A.java <<EOF
public class A {
public static void main(String[] args) throws Exception {
B.test();
}
}
EOF
cat > src/B.java <<EOF
public class B {
public static void test() {
C.test();
int d = D.CONSTANT;
System.out.println("CONSTANT = " + d);
}
}
EOF
cat > src/C.java <<EOF
public class C {
public static String test() {
D.test();
return null;
}
}
EOF
cat > src/D.java <<EOF
public class D {
public static void test() {
}
public static final int CONSTANT = 15;
}
EOF
ant compile && ant jar && ant run
It should run fine, and print the correct constant. Change the constant
in class D, compile again, and the old value is printed. Make C.test()
return Object instead of String, and try again, and you get:
java.lang.NoSuchMethodError: C.test()Ljava/lang/String;
If you enable the <depend> task, the return-type problem is fixed. The
inline problem isn't fixed if you're using Java 7, but I was surprised
to find that it is for Java 8. javap reveals why:
Last modified 25-Jul-2016; size 540 bytes
MD5 checksum 375791f56bf0e955d6630fdc464c8ea6
public class B
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #13.#18 // java/lang/Object."<init>":()V
#2 = Methodref #19.#20 // C.test:()Ljava/lang/String;
#3 = Class #21 // D
#4 = Fieldref #22.#23 // java/lang/System.out:Ljava/io/PrintStream;
#5 = Class #24 // java/lang/StringBuilder
#6 = Methodref #5.#18 // java/lang/StringBuilder."<init>":()V
#7 = String #25 // CONSTANT =
#8 = Methodref #5.#26 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#9 = Methodref #5.#27 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
#10 = Methodref #5.#28 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#11 = Methodref #29.#30 // java/io/PrintStream.println:(Ljava/lang/String;)V
#12 = Class #31 // B
#13 = Class #32 // java/lang/Object
#14 = Utf8 <init>
#15 = Utf8 ()V
#16 = Utf8 Code
#17 = Utf8 test
#18 = NameAndType #14:#15 // "<init>":()V
#19 = Class #33 // C
#20 = NameAndType #17:#34 // test:()Ljava/lang/String;
#21 = Utf8 D
#22 = Class #35 // java/lang/System
#23 = NameAndType #36:#37 // out:Ljava/io/PrintStream;
#24 = Utf8 java/lang/StringBuilder
#25 = Utf8 CONSTANT =
#26 = NameAndType #38:#39 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#27 = NameAndType #38:#40 // append:(I)Ljava/lang/StringBuilder;
#28 = NameAndType #41:#34 // toString:()Ljava/lang/String;
#29 = Class #42 // java/io/PrintStream
#30 = NameAndType #43:#44 // println:(Ljava/lang/String;)V
#31 = Utf8 B
#32 = Utf8 java/lang/Object
#33 = Utf8 C
#34 = Utf8 ()Ljava/lang/String;
#35 = Utf8 java/lang/System
#36 = Utf8 out
#37 = Utf8 Ljava/io/PrintStream;
#38 = Utf8 append
#39 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#40 = Utf8 (I)Ljava/lang/StringBuilder;
#41 = Utf8 toString
#42 = Utf8 java/io/PrintStream
#43 = Utf8 println
#44 = Utf8 (Ljava/lang/String;)V
{
public B();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void test();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=1, args_size=0
0: invokestatic #2 // Method C.test:()Ljava/lang/String;
3: pop
4: bipush 10
6: istore_0
7: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
10: new #5 // class java/lang/StringBuilder
13: dup
14: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
17: ldc #7 // String CONSTANT =
19: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: iload_0
23: invokevirtual #9 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
26: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
32: return
}
Entry #3 in the constant pool refers to class D, even though no other
part of the class file uses it. That's evidently enough to get <depend>
to force recompilation of B. Bytecode from javac 7 doesn't include that
reference.
So Ant will handle the two mentioned cases if used with <depend> and
javac from JDK8.
--
ss at comp dot lancs dot ac dot uk
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-07-25 21:03 -0400 |
| Message-ID | <nn6csg$f03$1@gioia.aioe.org> |
| In reply to | #35136 |
On 7/25/2016 4:21 PM, Steven Simpson wrote: > On 24/07/16 23:06, Arne Vajhøj wrote: >> On 7/24/2016 5:08 PM, Steven Simpson wrote: >>> With the output directory in the classpath, doesn't it mean that javac >>> will attempt a kind of incremental build? And doesn't it then miss some >>> not particularly extraordinary cases (inlined constants; return types), >>> leading to broken builds? >> The problem you mention is real and need to be handled. There are >> ways to do that via various build scripts from OS shell to ant to >> newer build frameworks. > > I was not convinced that Ant would be enough, as the <javac> task > behaves largely as [javac -classpath out -d out], comparing timestamps > of corresponding .java and .class files, so it's exposed to the same > problems. Combining <depend> with <javac> should do better, but it > looked like it would still miss inlined constants, so I tried it out: > So Ant will handle the two mentioned cases if used with <depend> and > javac from JDK8. That was not my point. My point was the much simpler fact that with a script it is easy to start by deleting all class files. :-) Arne
[toc] | [prev] | [next] | [standalone]
| From | Roedy Green <inquiry@mindprod.com> |
|---|---|
| Date | 2016-07-26 15:24 -0700 |
| Message-ID | <3mofpb9f4nl6vcgfagpe1j88b2qb4oacmn@4ax.com> |
| In reply to | #35113 |
On Sat, 23 Jul 2016 19:05:59 -0400, Arne Vajhøj <arne@vajhoej.dk> wrote: > >Remember to have projectroot/bin in classpath. there are also the Javac options -classpath <path> Specify where to find user class files and annotation processors -sourcepath <path> Specify where to find input source files
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-07-23 19:06 -0400 |
| Message-ID | <nn0tac$17np$2@gioia.aioe.org> |
| In reply to | #35110 |
On 7/23/2016 2:42 PM, Stefan Ram wrote: > parmenides <xparmenides@yahoo.com> writes: >> I try to understand the relationship of the souce file and the class >> file. > > The java commands (»javac« and »java«) must be called from > the root of the directory hierarchy. I think that is the easiest. But I would not call it a must. Arne
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web