0

I just found this out and I'm hoping someone has a clue as to what's going on. Commands to follow (run this in a temp directory, clearing everything beforehand):

No problems:

cat << EOF > Myface.java
public interface Myface {}
EOF

cat << EOF > Myclass.java
public class Myclass implements Myface {}
EOF

javac Myface.java
javac Myclass.java

Myclass won't compile:

cat << EOF > Myface.java
package Mypackage;
public interface Myface {}
EOF

cat << EOF > Myclass.java
package Mypackage;
public class Myclass implements Myface {}
EOF

javac Myface.java
javac Myclass.java

Myclass WON'T compile:

cat << EOF > Myface.java
package Mypackage;
public interface Myface {}
EOF

cat << EOF > Myclass.java
package Mypackage;
public class Myclass implements Myface {}
EOF

javac Myclass.java

What's going on here?

EDIT: All the commands, run:

javatest@l-bel-smai-ubuntu:~$ ls
javatest@l-bel-smai-ubuntu:~$ pwd
/home/javatest
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myface.java
> public interface Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$ 
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myclass.java
> public class Myclass implements Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$ 
javatest@l-bel-smai-ubuntu:~$ javac Myface.java
javatest@l-bel-smai-ubuntu:~$ javac Myclass.java
javatest@l-bel-smai-ubuntu:~$ ls
Myclass.class  Myclass.java  Myface.class  Myface.java
javatest@l-bel-smai-ubuntu:~$ rm *
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myface.java
> package Mypackage;
> public interface Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$ 
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myclass.java
> package Mypackage;
> public class Myclass implements Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$ 
javatest@l-bel-smai-ubuntu:~$ javac Myface.java
javatest@l-bel-smai-ubuntu:~$ javac Myclass.java
Myclass.java:2: cannot find symbol
symbol: class Myface
public class Myclass implements Myface {}
                                ^
1 error
javatest@l-bel-smai-ubuntu:~$ rm *
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myface.java
> package Mypackage;
> public interface Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$ 
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myclass.java
> package Mypackage;
> public class Myclass implements Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$ 
javatest@l-bel-smai-ubuntu:~$ javac Myclass.java
Myclass.java:2: cannot find symbol
symbol: class Myface
public class Myclass implements Myface {}
                                ^
1 error
javatest@l-bel-smai-ubuntu:~$ 
Stefan Mai
  • 23,367
  • 6
  • 55
  • 61
  • Can you show the commands you ran, the folders you ran them from, and the error messages that were output by the compiler? – Michael Aaron Safyan Oct 10 '11 at 22:46
  • 4
    Java/Class files must be put in the class path in a subfolder structure according to their packages. Maybe thats the problem here. – Gandalf Oct 10 '11 at 22:51
  • 3
    Geez, what a long day. You're right Gandalf. Write it in an answer and claim your prize ;). – Stefan Mai Oct 10 '11 at 22:56
  • There is no requirement in Java that the source files be in any particular directory structure (some tools may depend on it, but none in the JDK do that I am aware of). It is sane to put them in a directory structure of course :-) – TofuBeer Oct 10 '11 at 23:49
  • @TofuBeer That's just not so. The structure of a JAR file is completely specified, and 'loose' .class files lying around a file system are expected to conform to the same directory structure. Otherwise classpath searches won't work, which is why the failing cases here are failing. – user207421 Oct 11 '11 at 02:52
  • Source files do not go in a JAR. I didn't say anything about class files. – TofuBeer Oct 11 '11 at 03:47
  • @TofuBeer fair enough, but the compiler is a tool in the JDK, and it is documented thus: http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html: "If packages are used, the local path name within the directory or archive must reflect the package name." And this question proves that it is only looking in certain places for source files. – user207421 Oct 11 '11 at 06:21
  • From that same tech note: "You should arrange source files in a directory tree that reflects their package tree". If you rely on the compiler to find the source files then, yes, you need to have the package and directory match. If you pass all of the files that need to be compiled on the command line (say *.java) then it doesn't matter what the packages are. – TofuBeer Oct 11 '11 at 07:14

3 Answers3

1

Yeah here we go: Java/Class file directory structure must match the package structure the Java classes are declared in for compilation and class loading to work correctly.

Gandalf
  • 2,350
  • 20
  • 28
0

While compiling Myclass.java add the classpath option

javac -classpath . Myclass.java
0

Case 2: When you compile Myclass.java the javac will look for Mypackage/Myface.class. Thats not there. You should compile with javac -d . which makes javac to create the appropriate directory structure for classes it generates. That is also implicitely in the searchpath for the next javac call.

Case 3: When you compile Myclass.java it will look for Mypackage/Myface.class, then for a suitable source file given on the commandline then for a suitable sourcefile in Mypackage/Myface.java. Neither exist. Either compile with javac -d Myface.java Myclass.java or shove the *.java into the appropriate directory structure indicated by the package names.

A.H.
  • 63,967
  • 15
  • 92
  • 126