javac - The Java Compiler Cheatsheet
What it is
javac is the command-line compiler for the Java programming language. You use it to compile .java source files into .class bytecode files that the Java Virtual Machine (JVM) can execute.
Installation
javac is part of the Java Development Kit (JDK). Install the JDK for your operating system:
Linux (Debian/Ubuntu):
sudo apt update
sudo apt install default-jdk
Linux (Fedora/CentOS/RHEL):
sudo dnf install java-11-openjdk-devel # Or java-17-openjdk-devel, etc.
macOS: Download the latest JDK installer from Oracle or use a package manager like Homebrew:
brew install openjdk
Windows:
Download the latest JDK installer from Oracle. After installation, ensure JAVA_HOME environment variable is set and the JDK’s bin directory is in your system’s PATH.
Core Concepts
- Source Files (
.java): Human-readable code written in the Java language. - Class Files (
.class): Compiled bytecode understood by the JVM. Each.classfile typically corresponds to a single Java class. - Classpath: The search path for classes and resources.
javacuses it to find referenced classes during compilation, andjava(the runtime) uses it to find classes to execute. - Modules (Java 9+): A way to organize Java code into logical units.
Commands / Usage
Compiling Single Files
Compile a single Java source file. The output will be MyClass.class in the same directory.
javac MyClass.java
Compiling Multiple Files
Compile several Java source files at once.
javac File1.java File2.java AnotherFile.java
Compiling with Package Structure
If your files are in packages (e.g., com.example.MyClass), javac will create the necessary directory structure for the .class files.
javac com/example/MyClass.java
This will produce com/example/MyClass.class.
Specifying Output Directory (-d)
Compile source files and place the generated .class files into a specified directory. This is crucial for maintaining clean project structures.
javac -d bin src/com/example/MyClass.java src/com/example/AnotherClass.java
This command compiles the files in src/com/example/ and places the resulting .class files in the bin/com/example/ directory.
Specifying Sourcepath (-sourcepath)
Tell javac where to find source files, especially when they are not in the current directory or are organized in a specific way.
javac -sourcepath src -d bin src/com/example/MyClass.java
Here, javac looks for related source files in the src directory if MyClass.java references them.
Specifying Classpath (-classpath or -cp)
Specify the location of user class files and annotation processors. This is essential when your code depends on external libraries (JAR files).
javac -cp "lib/library1.jar:lib/library2.jar" MyProgram.java
On Windows, use semicolons:
javac -cp "lib\library1.jar;lib\library2.jar" MyProgram.java
You can also include directories containing .class files.
Compiling with Encoding (-encoding)
Specify the character encoding used to read the source files.
javac -encoding UTF-8 -d bin src/MyClass.java
Generating Javadoc (-Xdoclint:all)
Enable Javadoc linting to check for common documentation errors.
javac -Xdoclint:all -d bin src/MyClass.java
Enabling Preview Features (--enable-preview)
Compile code that uses features available in preview versions of Java.
javac --enable-preview -d bin src/MyPreviewFeature.java
Note: Running code compiled with --enable-preview often requires java --enable-preview as well.
Setting Source and Target Versions (-source, -target)
Specify the version of the Java language used in the source files and the version of the Java Virtual Machine to which the classes should be compiled.
# Compile using Java 11 source features, targetting Java 8 JVM
javac -source 11 -target 1.8 -d bin src/MyJava11Code.java
Common values for -source and -target: 1.5, 1.6, 1.7, 1.8, 9, 10, 11, 12, etc.
Verbose Output (-verbose)
Print additional information about the compilation process, including which files are being compiled and loaded.
javac -verbose MyClass.java
Generating Debug Information (-g)
Control the level of debug information included in the class files.
javac -g:source,lines,vars -d bin MyClass.java # Include source, line numbers, and local variables
javac -g -d bin MyClass.java # Include all debug information (default)
javac -g:none -d bin MyClass.java # Include no debug information
Creating JAR Files (via jar command, often used after javac)
While javac compiles, the jar command bundles .class files into an archive.
# Compile first
javac -d bin src/com/example/MyClass.java src/com/example/AnotherClass.java
# Then create a JAR
jar cf myapp.jar -C bin .
The -C bin . tells jar to change directory to bin and add all contents (.) from there.
Common Patterns
Compiling a Project with Package Structure
This is the standard way to compile a modern Java project using javac.
# Assume project structure:
# my-project/
# ├── src/
# │ └── com/example/
# │ ├── App.java
# │ └── utils/
# │ └── Helper.java
# ├── lib/
# │ └── some-dependency.jar
# └── bin/ (output directory)
# Compile all .java files in src, placing .class files in bin,
# using external library from lib/
javac -d bin -cp "lib/some-dependency.jar" src/com/example/App.java src/com/example/utils/Helper.java
Compiling with Multiple JARs in Classpath
javac -cp "lib/junit.jar:lib/hamcrest.jar:lib/log4j.jar" -d build src/com/example/MyTest.java
Recompiling Only Changed Files (Manual Approach)
While javac itself doesn’t cache compilation state, you can script it to check timestamps. This is typically handled by build tools like Maven or Gradle. For a simple script:
# Compile all if target directory is empty or source is newer
if [ ! -d "bin" ] || find src -newer bin | grep -q .; then
echo "Compiling..."
javac -d bin src/**/*.java
fi
Compiling with Preview Features and Targeting Older JVM
javac --enable-preview -source 17 -target 1.8 -d bin src/MyNewFeature.java
Gotchas
- Classpath Hell: Incorrectly specifying the classpath is a very common source of
ClassNotFoundExceptionat runtime orcannot find symbolerrors during compilation. Ensure all necessary JARs and directories containing.classfiles are included. - Package Directory Mismatch: If you compile
src/com/example/MyClass.javabut the file itself doesn’t containpackage com.example;,javacmight proceed without error but lead to runtime issues. Conversely, if the file haspackage com.example;but you compile it from a directory where it’s not undercom/example/, you’ll get errors. - Implicit Module Layer (Java 9+): Before modules,
javacwould implicitly place all compiled classes into the unnamed module. With modules, you need to be more explicit about module paths (--module-path,-p) and module declarations (module-info.java). javacvs.java: Rememberjavacis for compiling (.java->.class), whilejavais for running (.class-> application execution).-sourcevs.-target:-sourcedictates which language features you can use in your code.-targetdictates which JVM version the generated bytecode is compatible with. You can use newer source features (-source 11) but target an older JVM (-target 1.8), as long as the features used aren’t specific to a later JVM version.- Default Package Compilation: Compiling files without a
packagedeclaration (in the default package) is generally discouraged for larger projects.javacwill place their.classfiles directly in the output directory (e.g.,bin/MyClass.class).