OpenJDK:修改JDK代码后如何避免全量重新编译?
First off, I get your frustration—having to wait for 9k+ files to compile just for a single System.out.println() line is brutal. The root issue here is that OpenJDK 8's jdk-only target doesn't handle incremental compilation for Java source changes as smoothly as the hotspot-only target does. The build system defaults to a full rebuild for broader JDK targets unless you guide it to focus only on what changed. Here are actionable fixes to avoid full recompilation:
1. Use Granular Module/Directory Targets Instead of jdk-only
OpenJDK 8 organizes its JDK source into logical functional groups (pre-modular, but still grouped by areas like java.base, java.desktop, etc.). Instead of building the entire JDK, target only the specific group your modified file belongs to:
- If you modified a core class like
java.lang.String, run:make java.base - For even more precision, target individual packages within a group. For example, to build just the
java.langpackage injava.base:make java.base/java.lang
This tells the build system to only process files in that specific package/group, not the entire JDK.
2. Enable Incremental Build Flags
OpenJDK 8's build system supports flags that enforce incremental compilation. Try running make with the INCREMENTAL=true flag:
make jdk-only INCREMENTAL=true
This flag tells the build tool to track modified files and only recompile what's changed, along with direct dependencies. Note that this works best for small, isolated changes—if you modify a widely used core class like Object, you'll still see some dependent files recompile, but it's way better than a full 9k-file rebuild.
3. Compile Individual Files Directly
For tiny changes, you can compile just the modified file manually and place the output in the correct build directory, skipping the build system's full checks entirely:
- Locate your modified file (e.g.,
jdk/src/share/classes/java/lang/String.java) - Compile it using the JDK's internal javac, targeting the build's class output directory:
javac -d build/classes/java.base/share/classes jdk/src/share/classes/java/lang/String.java
Make sure the -d path matches where your build stores compiled classes for the relevant group—this ensures existing build artifacts pick up your updated class without recompiling everything else.
4. Clean Targeted Cache Directories (Not the Entire Build)
Sometimes the build system's cache gets out of sync, triggering a full rebuild. Instead of wiping the entire build directory, delete only the cache for the group/package you modified:
- For a
java.lang.Stringchange, delete just the compiled class:rm -rf build/classes/java.base/share/classes/java/lang/String.class
Or delete the entire package's class files if you want to recompile the whole package:
rm -rf build/classes/java.base/share/classes/java/lang/
Then run make jdk-only—the build system will only recompile missing/modified files.
Important Notes
- OpenJDK 8's incremental support is less robust than in later Java versions (9+ with modules), so some edge cases might still trigger partial recompilations. But these methods will drastically reduce build time compared to a full rebuild.
- If you modify a file referenced by hundreds of other classes (like
java.lang.Object), expect some dependent files to recompile—this is unavoidable, but it's not a full 9k-file rebuild.
内容的提问来源于stack exchange,提问作者wind2412

