How to configure Java builds in the Moderne CLI
Java is the default ecosystem supported by the Moderne CLI, so Maven and Gradle builds work out of the box without any additional configuration. However, you may want to customize which JDK is used, register build tool installations from non-standard locations, pin specific versions, or pass extra build arguments.
In this guide, we'll walk you through how to configure the Moderne CLI for Java builds — including JDK selection, Gradle, and Maven tuning.
Prerequisites
This guide assumes that:
- You have installed and configured the Moderne CLI (version
4.1.9or higher) - You are familiar with running Moderne CLI commands (if not, work through our CLI workshop)
- You have at least one JDK installed on your machine
Step 1: Confirm Java is enabled in your moderne.yml file
Java is enabled by default via the maven and gradle build steps. Your moderne.yml file, located at ~/.moderne/cli/moderne.yml, should already include them.
If you have customized your build steps previously, confirm that maven and gradle are present. Otherwise, no changes are needed:
# Other keys and values...
build:
steps:
- type: maven
- type: gradle
- type: resource
inclusion: |-
**/*
Step 2: (Optionally) Configure your JDK
The CLI automatically discovers JDK installations from these locations (with the first one representing the one given the highest priority):
$PATH$JAVA_HOME- Predictable OS installation paths
- SDKMAN directories (
~/.sdkman/candidates/java/) - Homebrew directories
- Gradle toolchains
- User-configured paths (via
mod config java installation edit)
Discovering installations
You can see all detected JDKs and their priority by running:
mod config java installation list
Here is what the output of that command might look like:
> Listing available JDKs
> Set globally for all repositories
17.0.7-tem $PATH java
17.0.7-tem $JAVA_HOME /Users/someuser/.sdkman/candidates/java/17.0.7-tem/bin/java
21.0.1-oracle OS directory /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home/bin/java
17.0.7-tem SDKMAN /Users/someuser/.sdkman/candidates/java/17.0.7-tem/bin/java
17.0.8-graalce SDKMAN /Users/someuser/.sdkman/candidates/java/17.0.8-graalce/bin/java
* What to do next
> Run mod config java installation edit to change this configuration
> Add --local <path-to-local-repos> to see repository-specific values
> Run mod config java installation delete to delete global configuration
Adding installation locations
If you have JDKs installed in locations the CLI does not automatically discover, you can register them:
mod config java installation edit /path/to/jdk
Each path should point to a JDK home directory. Projects will only use a registered location if the appropriate Java version exists there. For example, if a project targets Java 17 but the registered path only contains Java 11, the CLI will look elsewhere for a matching JDK.
To remove manually configured installation paths:
mod config java installation delete
This only removes user-configured paths. Automatically discovered installations remain available.
Selecting a version
To force the CLI to use a specific Java version when building:
mod config java version edit 17
You can use a major version (17), a vendor-qualified name (17-tem), or an exact version (17.0.6-tem) depending on how tight you need the match to be.
To apply a version only to a specific group of repositories, use the --local flag:
mod config java version edit 17 --local ./working-set
To revert to auto-detection:
mod config java version delete
To see the currently configured version:
mod config java version show
Specifying a Java version in the CSV
When cloning using mod git sync csv, you can add a java column to the CSV to specify the version per repository.
In the example below, rewrite-maven-plugin is configured to use Java 8, while rewrite-spring will use auto-detection:
"cloneUrl","branch","origin","path","java"
"https://github.com/openrewrite/rewrite-maven-plugin","main","github.com","openrewrite/rewrite-maven-plugin",8
"https://github.com/openrewrite/rewrite-spring","main","github.com","openrewrite/rewrite-spring"
The CLI uses mod config java version edit <VERSION> --local <REPO> for each row that has a value for that column, so you can verify the configuration by running:
mod config java version show --local <REPO>
Passing JVM options
You can configure JVM options (for example, heap size) that will be applied when the CLI runs Java-based build tools and recipes:
mod config java options edit -Xmx8G
To see the currently configured options:
mod config java options show
To revert to defaults:
mod config java options delete
Step 3: (Optionally) Configure Gradle
By default, the CLI uses the Gradle wrapper (gradlew) included in each repository. If a repository doesn't include a wrapper, the CLI falls back to Gradle installations it discovers on your machine.
Discovering installations
The CLI automatically discovers Gradle installations from these locations (with the first one representing the one given the highest priority):
- User-configured paths (via
mod config build gradle installation edit) $PATH$GRADLE_HOME- SDKMAN (
~/.sdkman/candidates/gradle/) - Homebrew (
/opt/homebrew/opt/gradle*or/usr/local/opt/gradle*)
You can see all detected installations and their priority by running:
mod config build gradle installation list
Adding installation locations
If you have Gradle installations in locations the CLI does not automatically discover, you can register them:
mod config build gradle installation edit /path/to/gradle-home
Each path should point to a Gradle home directory (i.e., a directory containing bin/gradle). You can register multiple installations at once:
mod config build gradle installation edit /opt/gradle-4.5 /opt/gradle-8.1.1
To remove manually configured installation paths:
mod config build gradle installation delete
Selecting a version
When a repository does not include a Gradle wrapper, you can tell the CLI which Gradle version to use. The version must exactly match one of the installations known to the CLI.
To set a Gradle version globally:
mod config build gradle version edit 8.1.1
To apply a version only to a specific group of repositories:
mod config build gradle version edit 4.5 --local ./working-set
To revert to auto-detection:
mod config build gradle version delete
To see the currently configured version:
mod config build gradle version show
Specifying a Gradle version in the CSV
When cloning using mod git sync csv, you can add a gradleVersion column to the CSV to specify the Gradle version per repository:
"cloneUrl","branch","origin","path","gradleVersion"
"https://github.com/example/legacy-app","main","github.com","example/legacy-app","4.5"
"https://github.com/example/modern-app","main","github.com","example/modern-app"
If a repository has a Gradle wrapper, the wrapper always takes precedence regardless of the configured Gradle version. The gradleVersion setting only applies to repositories without a wrapper.
Passing Gradle arguments
You can pass additional arguments to Gradle when building LSTs. For details on how gradleArgs works with global, local, and CSV-based configuration, please check out our layered configuration guide.
Step 4: (Optionally) Configure Maven
The CLI uses the Maven installation found on your $PATH. There is no version selection or installation discovery for Maven.
Passing Maven arguments
You can pass additional arguments to Maven when building LSTs. For details on how mavenArgs works with global, local, and CSV-based configuration, please check out our layered configuration guide.
Step 5: (Optionally) Clone a custom list of repositories
If you don't have the repositories you want to work with cloned locally already, you can clone a group of them by defining a repos.csv file that lists them out such as in the following example:
cloneUrl,branch,origin,path
git@github.com:spring-projects/spring-petclinic.git,main,github.com,spring-projects/spring-petclinic
git@github.com:openrewrite/rewrite.git,main,github.com,openrewrite/rewrite
git@github.com:apache/commons-lang.git,master,github.com,apache/commons-lang
Check out our documentation on creating a repos.csv file for more detailed information about what's expected in this file.
After creating the CSV, clone the repositories by running the following command:
mod git sync csv . repos.csv --with-sources
Step 6: Build your Java repositories
The next thing you'll need to do is build LSTs for each of your repositories. To build the LSTs, run:
mod build /path/to/your/repos
Presuming everything has been set up correctly, you should see output similar to:
▶ spring-projects/spring-petclinic@main
Build output will be written to build.log
> Step 1 - build with Maven
Selected JDK 17.0.7-tem
Running mvn install
✓ Built spring-petclinic-20260424120000000-ast.jar
Cleaned 1 older builds
Step 7: Install recipes
In order to run recipes, you'll need to make sure the recipes are installed on your local machine.
You can install a specific Java recipe JAR by running a command like:
mod config recipes jar install org.openrewrite.recipe:rewrite-migrate-java:LATEST
You can find the specific installation command for any recipe on its page in the recipe catalog.
Step 8: Run recipes
With the LSTs built and recipes installed, you can now run recipes against your Java repositories. You can either specify the full recipe path for running such as in:
mod run . --recipe=org.openrewrite.java.migrate.UpgradeToJava21
Or, you can search for a specific recipe and set it as the active recipe:
mod config recipes search UpgradeToJava21
Then you can run the active recipe by:
mod run . --active-recipe
Step 9: View data tables
Many recipes will also produce useful data tables that you can access via the mod study command such as in:
mod study . --last-recipe-run --data-table SourcesFileResults