Explain Codes LogoExplain Codes Logo

Javac option to compile all java files under a given directory recursively

java
build-tools
command-line
javac
Alex KataevbyAlex Kataev·Dec 2, 2024
TLDR

Compile all java files recursively using javac compiler, utilizing a wildcard:

javac -d bin $(find . -name "*.java")

This command finds and compiles all .java files within the current directory and its sub-folders, to a directory named bin. Make sure to run this command from the root directory of your Java source files.

Correct tools for different scenarios

IDEs such as Eclipse and IntelliJ IDEA provide a handy incremental compilation feature. It automatically compiles your changes as you save your work. This feature is vital for maintaining productivity whilst working on lengthy Java projects.

However, in head-to-head battles with the command line, fans of the terminal may choose a more direct approach when working on less complex projects. Using fast answer above, you can compile files quickly and efficiently.

When steering through more involved codebases, Apache Maven and Apache Ant come to the rescue. Maven is especially good at overall project lifecycle management, escorting from compiling to packaging and testing stages.

If your quest starts to cross paths with different language realms, Sbt for Scala, Ivy for Ant-based projects, and Gradle for Groovy backed projects can be your guide.

Automation of the compilation process makes build times more predictable and enables continuous integration, which is an important aspect in today's development workflows.

Harness the power of the command line

Going recursive with the wildcard

To compile all .java files in a directory and its subdirectories with javac, put the find command with a wildcard (*) to work:

find . -name "*.java" -print | xargs javac -d bin

Setting classpath for external dependencies

When you are wandering around codebases filled with external dependencies, include them in the classpath using -cp or -classpath option:

javac -d bin -cp "lib/*" $(find . -name "*.java")

This command lets javac spy and employ JARs located in the lib directory while doing the dirty compile work.

Handling xargs splitting arguments

Using xargs can sometimes lead to unexpected results with large file sets — xargs may decide to split the arguments across multiple javac calls. In such scenarios, consider levelling up to GNU Parallel to replace xargs, and forget about split personalities.

Commanding the command line

Working with package structures

When dealing with Java files living in different packages, we can use wildcards (**) to guide javac through all the directories.

The might of exec with find

If you're feeling adventurous, combine find with exec to perform a direct action on the located files, bypassing the need for xargs. Thus, perform one action at a time. Not all heroes wear capes, some carry braces:

find . -name "*.java" -exec javac -d bin {} \;

Compiling considering dependencies

When import dependencies need to be taken into account, use -sourcepath to ensure javac abides by the import hierarchy:

javac -d bin -sourcepath src $(find src -name "*.java")

This command enlightens javac about the source path when resolving import declarations.

Embracing build automation

As your codebase grows larger and larger, choosing a build tool capable of handling this monstrous complexity becomes critical. Build automation tools decrease the malevolent human error factor, providing more consistent and repeatable builds. This is key for teams and continuous integration pipelines. Moreover, build tools simplify the onboarding process for new team members, because who doesn't like things that save time?