Modern Build Tools & Dependency Management
Maven and Gradle for Java AI projects: managing Spring AI and LangChain4j versions with BOMs, multi-module layout for projects with separate ingestion and serving, and dependency hygiene.
On this page
Dependency management is where AI projects quietly go wrong. This ecosystem moves fast enough that a loosely-pinned version breaks a build you did not touch, and mismatched module versions produce runtime errors that look like bugs in your code. Getting the build right saves hours of confusion.
Key Takeaways
- Use a BOM to pin every
spring-ai-*(orlangchain4j-*) artifact to a compatible set. - Pin exact versions. A floating range in a fast-moving library breaks builds unpredictably.
- Reach for multi-module only when parts have different lifecycles — e.g. heavy ingestion vs lean serving.
- Gradle version catalogs centralise versions across modules; Maven's
dependencyManagementdoes the same job.
The BOM is the important part
A Bill of Materials declares compatible versions for a whole family of artifacts. You import it once and stop specifying versions on individual dependencies.
<properties>
<!-- Pin exactly. Not a range, not "latest". -->
<spring-ai.version>1.0.0</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- No <version> here — the BOM supplies it. -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
</dependency>
</dependencies>dependencies {
implementation(platform("org.springframework.ai:spring-ai-bom:1.0.0"))
implementation("org.springframework.ai:spring-ai-starter-model-openai")
implementation("org.springframework.ai:spring-ai-starter-vector-store-pgvector")
}Gradle version catalogs
For multi-module Gradle projects, a version catalog centralises versions in one file so every module agrees.
[versions]
spring-ai = "1.0.0"
langchain4j = "1.0.0"
[libraries]
spring-ai-bom = { module = "org.springframework.ai:spring-ai-bom", version.ref = "spring-ai" }
spring-ai-openai = { module = "org.springframework.ai:spring-ai-starter-model-openai" }
langchain4j-core = { module = "dev.langchain4j:langchain4j", version.ref = "langchain4j" }dependencies {
implementation(platform(libs.spring.ai.bom))
implementation(libs.spring.ai.openai)
}Change a version in one place and every module updates. The equivalent in Maven is a parent POM's
dependencyManagement.
Multi-module: when and how
Split a project into modules when parts have genuinely different dependency sets or lifecycles. A common AI split:
Why this split earns its keep: the ingestion module pulls in Apache Tika, PDF parsers and other heavy dependencies that the serving module has no reason to ship. Keeping them apart means your web service's image stays small and its attack surface narrow, and you can run ingestion as a separate batch job.
<modules>
<module>common</module>
<module>ingestion</module>
<module>serving</module>
</modules>Dependency hygiene for AI projects
- Audit regularly.
mvn dependency:treeorgradle dependencies— AI libraries pull in large transitive trees (HTTP clients, JSON libraries, ONNX runtimes). Know what you are shipping. - Scan for vulnerabilities. The OWASP Dependency-Check plugin or
gradle dependencyCheckAnalyzein CI. AI libraries are young and their transitive dependencies churn. - Exclude what you do not use. Some starters bundle multiple providers; exclude the ones you do not need to shrink the image.
- Watch for duplicate HTTP clients. Spring AI and LangChain4j may each bring their own; aligning them avoids surprises.
A reproducible build is the goal
The single most valuable property of your build configuration is reproducibility: the same source produces the same artifact today and in six months. Exact versions, a BOM, and a committed lockfile (Gradle) or a fully-pinned POM get you there. In a field where the libraries change weekly, that stability is what lets you tell a real regression from a dependency drift.
Next
You have completed Phase 0. Your Java foundation is ready.
- Introduction to the Spring AI Framework — Phase 1 begins
- The roadmap — see the whole path
Frequently Asked Questions
Maven or Gradle for a Spring AI project?
Why use a BOM for AI dependencies?
Should I split my AI project into modules?
Related tutorials
- Containerization with Docker & KubernetesContainerize and deploy a Spring Boot AI application: a production Dockerfile with layered JARs, Kubernetes deployment with secrets for API keys, health probes and resource limits.
- Microservices Architecture Deep DiveMicroservices patterns that matter for AI systems: API gateway, circuit breakers around model calls, the saga pattern for agent workflows, and where an AI service fits in the topology.
- Reactive Programming with Project ReactorProject Reactor for AI developers: Mono, Flux, back-pressure and WebFlux — and the one place they are genuinely the right tool, streaming LLM tokens to a browser.
- Functional Programming in Java for AI PipelinesFunctional Java refreshed for AI work: streams for document pipelines, Optional for safe metadata access, and CompletableFuture for concurrent model calls — with practical examples.