/commands/java/javac-compile-multiple-files
javac -d out: compile multiple Java files with packages and run them
- tool
- Java
- versions
- Java 8+, @argfiles: Java 8+, java --source launcher: Java 11+
- os
- linux, macos, windows
To compile a Java program made of several files and packages, pass all source files to javac with -d out: javac writes each class into out/ in folders that match its package (out/com/example/App.class). Run it with java -cp out com.example.App, using the fully qualified class name and the output folder as the class path.
Compile and run a two-package program
mkdir -p src/com/example/app src/com/example/util
cat > src/com/example/util/Greeter.java <<'EOF'
package com.example.util;
public class Greeter {
public static String greet(String name) { return "Hello, " + name; }
}
EOF
cat > src/com/example/app/App.java <<'EOF'
package com.example.app;
import com.example.util.Greeter;
public class App {
public static void main(String[] args) {
System.out.println(Greeter.greet(args.length > 0 ? args[0] : "javac"));
}
}
EOF
find src -name '*.java' > sources.txt
javac -d out @sources.txt
find out -name '*.class' | sort
java -cp out com.example.app.App
java -cp out com.example.app.App packagesOutput
out/com/example/app/App.class out/com/example/util/Greeter.class Hello, javac Hello, packages
@sources.txt is an argument file: javac reads the file list from it, which avoids "argument list too long" on big projects and works the same on every shell.
Options
| Command | Effect |
|---|---|
| javac -d out $(find src -name "*.java") | Compile every source file under src (Unix shells) |
| javac -d out @sources.txt | Read the list of files from an argument file |
| javac -d out --source-path src src/com/example/app/App.java | Compile App and every class it references, found under src |
| javac -d out -cp lib/dep.jar @sources.txt | Compile against a library JAR |
| javac --release 17 -d out @sources.txt | Produce class files that run on Java 17 and check API usage against Java 17 |
| javac -Xlint:all -d out @sources.txt | Show all recommended warnings |
Pitfalls
- Running with a path instead of a class name.
java out/com/example/app/Apporjava Appfails with Could not find or load main class. Pass the class path with-cp outand the name with dots:com.example.app.App. - Forgetting a file. If
javaconly receivesApp.javaand cannot findGreeteron the class path or source path, it reports cannot find symbol orpackage com.example.util does not exist. - Stale classes. javac does not delete old
.classfiles; a class you removed from the sources still exists inout/. Deleteout/before a clean build. - Windows globs.
src/**/*.javais not expanded bycmd.exe; use an argument file ordir /s /b src\*.java > sources.txt. - Single-file shortcut. For a program in one file,
java App.javacompiles in memory and runs it without javac: see running a source file.
Confirm it worked
out/ contains one .class file per class in package folders, and java -cp out PACKAGE.CLASS runs main. For anything larger than a few files, a build tool (Maven or Gradle) does the same with dependency management.
FAQ
Does javac compile files that my code imports automatically?
It compiles source files it finds on the source path when a class is referenced and no newer .class file exists. Passing every file explicitly, or --source-path src, makes the result predictable.
Why must the folder structure match the package name?
The JVM finds class com.example.App at com/example/App.class below a class path entry. javac -d creates that layout for you; the source tree should follow it too, so tools and javac's source path lookup work.
What is the difference between -d and -cp?
-d is where javac writes the compiled classes. -cp (or --class-path) is where javac and java look for classes your code uses, such as other compiled code or JAR files.