4

I've the following two source files

File World.java

package planets;

public class World {
    public static void main(String[] args) {
        Mars.land();
    }
}

File Moon.java

package planets;

public class Moon {
    public static void land() {
        System.out.println("Hello Moon");
    }
}

class Mars {
    public static void land() {
        System.out.println("Hello Mars");
    }
}

As we can see, the Moon.java contains two classes: the public Moon class and the nonpublic Mars class.

The files are located inside planets directory, below is showed the directory tree

+current-dir:
+----+planets:
      +----+World.java
      +----+Moon.java

Now, if I try to compile from Windows command prompt (I'm inside current-dir folder) typing

javac planets\World.java

I receive this error message:

planets\World.java:5: error: cannot find symbol
       Mars.land();
       ^
  symbol:   variable Mars
  location: class World
1 error

It's very strange, because I know that the compiler searches for nonpublic classes inside all the source files of the current package. Also Cay Horstmann's Core Java Vol 1, 10th ed. at pp. 192-193 says that:

[...]you can import nonpublic classes from the current package. These classes may be defined in source files with different names. If you import a class from the current package, the compiler searches all source files of the current package to see which one defines the class.

In addition I tried to write these files using Eclipse Oxygen and it compile without problems. But I know that Eclipse use a different compiler.

Why does javac compiler fail?

EDIT: I have not set CLASSPATH variable. So by default compiler looks inside current directory.

Vin
  • 701
  • 1
  • 9
  • 30
  • 2
    Try making a seperate file for Mars. I don't think Java supports having 2 top level classes in one file. – MrKickkiller Jul 30 '17 at 20:32
  • Thank you for describing the problem so clearly and precisely. You need to add the current directory to the classpath, which you can do by specifying `-cp .` when you compile and run the program. – Jesper Jul 30 '17 at 20:35
  • @Pshemo Just tried, same error because `.` is default classpath dir – Vin Jul 30 '17 at 20:36
  • 3
    Try compiling all the source files at once with `javac planets\*.java` – Jesper Jul 30 '17 at 20:37
  • Compile first `javac -cp . planets\Moon.java` then `javac -cp . planets\World.java`. Or better use @Jesper advice if you want to avoid this ordering. – Pshemo Jul 30 '17 at 20:37
  • @Jesper I tried, it still doesn't work – Vin Jul 30 '17 at 20:38
  • 1
    Did you add `-cp .` to Jesper's solution, like `javac -cp . planets\*.java`? – Pshemo Jul 30 '17 at 20:38
  • `javac -cp . planets\*` works. Now I would know why. – Vin Jul 30 '17 at 20:40
  • I know that, if not set, compiler looks always for files in the current dir, so `-cp .` seems to me redundant. EDIT: Infact it also works using `javac planets\*.java` as @Jesper suggested – Vin Jul 30 '17 at 20:46
  • 1
    @MrKickkiller Actually it is fully supported, though it’s not good practice. – VGR Jul 30 '17 at 20:55
  • However, what Horstrmann says does not actually matches what compiler does. Because things to work need that I have to compile `Moon.java` manually so that `Mars` class is already "visible" by compiler – Vin Jul 30 '17 at 21:18

1 Answers1

0

you need to type the following commands in order (inside your 'current-dir')

  1. javac planets\Moon.java
  2. javac -cp . planets\World.java
  3. java -cp . planets.World
marsouf
  • 1,107
  • 8
  • 15