Skip to content

/commands/java/javac-compile-multiple-files

javac -d out: compile multiple Java files with packages and run them

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · openjdk version "17.0.20.1" 2026-08-18updated
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

bash
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 packages

Output

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

CommandEffect
javac -d out $(find src -name "*.java")Compile every source file under src (Unix shells)
javac -d out @sources.txtRead the list of files from an argument file
javac -d out --source-path src src/com/example/app/App.javaCompile App and every class it references, found under src
javac -d out -cp lib/dep.jar @sources.txtCompile against a library JAR
javac --release 17 -d out @sources.txtProduce class files that run on Java 17 and check API usage against Java 17
javac -Xlint:all -d out @sources.txtShow all recommended warnings

Pitfalls

  • Running with a path instead of a class name. java out/com/example/app/App or java App fails with Could not find or load main class. Pass the class path with -cp out and the name with dots: com.example.app.App.
  • Forgetting a file. If javac only receives App.java and cannot find Greeter on the class path or source path, it reports cannot find symbol or package com.example.util does not exist.
  • Stale classes. javac does not delete old .class files; a class you removed from the sources still exists in out/. Delete out/ before a clean build.
  • Windows globs. src/**/*.java is not expanded by cmd.exe; use an argument file or dir /s /b src\*.java > sources.txt.
  • Single-file shortcut. For a program in one file, java App.java compiles 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.

Sources