Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java Gradle multi-project build: source ownership and a verified application task

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A Gradle multi-project build gives separately named projects their own source sets and connects them through explicit project dependencies.

Download Java source kit

Java 21+. This is a complete program using JDK classes.

Separate the billing rule from its caller

The downloadable build has a billing library and an app project. The library owns the checked quantity-times-price operation. The app depends on that library and supplies the command-line entry point. Keeping the rule in one source set avoids compiling slightly different copied formulas in several applications.

Both projects target the Java 21 toolchain in the supplied Gradle 8.10.2 build. The application plugin names the main class. A toolchain chooses a Java installation for compilation or execution; setting source syntax alone is not the same decision.

The root settings file includes both projects. The app’s implementation dependency names the billing project. The included command runs the application task and prints the same result as the standalone Java rule below. No external dependency is required by this two-project fixture.

Keep reproducibility outside IDE state

Use a declared build and pinned tool version so another machine can reconstruct source roots and the dependency graph. A Gradle wrapper is convenient when included; this kit declares Gradle 8.10.2 and documents the installed-tool command rather than claiming a wrapper binary is present.

A dependency lock or verification policy is useful when external libraries are added. This fixture has only a local project dependency, so it makes no claim about a production dependency audit, cached repository availability or a published artifact.

Working program

Java
package in.aitrove.billing;
public class BillingRule {
    public static long total(int quantity,long unitCents){
        if(quantity<0||unitCents<0)throw new IllegalArgumentException("Negative billing input");
        return Math.multiplyExact((long)quantity,unitCents);
    }
    public static void main(String[] args){System.out.println(total(3,50));}
}

Output

Output
150

Costs and boundaries

The billing calculation is O(1). Build configuration, compilation and startup have separate costs dependent on source changes and the build environment. The two-project fixture verifies dependency wiring and launch; it does not measure incremental-build performance.

Common Mistakes

  • An IDE project layout is not a portable build declaration.
  • Source compatibility and toolchain selection are different settings.
  • Do not promise that an omitted wrapper is bundled.

Read next

Maven project setup, Boundary tests.

Build files and command

The settings.gradle file includes billing and app. Run the application with the declared Gradle version from the extracted gradle-multi directory.

groovy
rootProject.name = 'aitrove-billing'
include 'billing', 'app'
groovy
plugins { id 'application' }
java { toolchain { languageVersion = JavaLanguageVersion.of(21) } }
dependencies { implementation project(':billing') }
application { mainClass = 'in.aitrove.app.Main' }
bash
gradle :app:run --console=plain
java
gradle-build
Storage details