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


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

Is it necessary the source file should be at the same location with the class file?

Started byparmenides <xparmenides@yahoo.com>
First post2016-07-24 00:55 +0800
Last post2016-07-23 19:06 -0400
Articles 12 — 5 participants

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


Contents

  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

#35110 — Is it necessary the source file should be at the same location with the class file?

Fromparmenides <xparmenides@yahoo.com>
Date2016-07-24 00:55 +0800
SubjectIs 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]


#35112

FromSteven Simpson <ss@my.domain.invalid>
Date2016-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]


#35113

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-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]


#35124

FromSteven Simpson <ss@my.domain.invalid>
Date2016-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]


#35125

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-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]


#35130

FromSteven Simpson <ss@my.domain.invalid>
Date2016-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]


#35131

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2016-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]


#35132

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-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]


#35136

FromSteven Simpson <ss@my.domain.invalid>
Date2016-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]


#35138

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-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]


#35141

FromRoedy Green <inquiry@mindprod.com>
Date2016-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]


#35114

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-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