Search code examples
javaintellij-ideajavac

Java error: cannot find symbol, but everything is in the same package


I'm having issues running a java class through the command line. It runs perfectly fine through the IntelliJ IDE, but when I attempt to compile my Simulator class, it throws an error

Simulator.java:4: error: cannot find symbol
    private final StackCreator<String> myStack;
                  ^
  symbol:   class StackCreator
  location: class Simulator
Simulator.java:7: error: cannot find symbol
        myStack = new StackCreator<>();
                      ^
  symbol:   class StackCreator
  location: class Simulator
2 errors
error: compilation failed

StackCreator and Simulator both have "package JavaClasses;" at the start of the files. I've tried compiling StackCreator first and it works, but doesn't change anything for Simulator, still producing the same error.


Solution

  • javac isn't going to scan your entire disk, you need to tell it everything. There is a reason nobody* ever actually invokes javac, ever. They run mvn, gradle, or have set up a CI tool to do so, or let their IDE do so.

    If you must use javac for some bizarre reason (do yourself a favour and learn first steps maven, it's really not very difficult and avoids this mess), you need to tell it where to look. There are multiple ways to do so:

    Let's assume you have these files:

    /Users/zekrofire/projects/MyApp/src/StackCreator/MyApp.java
    /Users/zekrofire/projects/MyApp/src/StackCreator/util/MyFastList.java
    /Users/zekrofire/projects/MyApp/src/otherpkg/Something.java
    

    and you want the class files to be in /Users/zekrofire/projects/MyApp/bin.

    Easiest way: Compile all the things, in one go

    Forget about a src dir and mix your java and class files (if you find this ugly, see comment about using maven). Then, just...

    javac *.java

    This will fix your problem. Tell javac about EVERY source file. Unfortunately, you can't java to just recursively trawl an entire dir for every java file, you'd have to do:

    cd /Users/zekrofire/projects/MyApp
    cd src
    mv -r * ..
    cd ..
    rmdir src
    javac StackCreator/*.java otherPkg/*.java StackCreator/util/*.java
    

    Use -classpath

    cd /Users/zekrofire/projects/MyApp
    javac -cp bin -d bin src/StackCreator/*.java
    

    now you can compile files one at a time.

    Use -sourcepath

    This isn't as cool as it sounds, don't think this lets you skip using an actual build system.

    cd /Users/zekrofire/projects/MyApp
    javac -sourcepath src -d bin src/StackCreator/*.java
    

    The absolute, hands down best way

    apt install maven
    ; create a pom.xml file describing your deps
    ; move your source files to src/main/java as per
    ; maven standard
    mvn compile
    

    *) I rounded down.