Bvoxro Stack

Building Fleet-Wide Java Architecture Rules: A Practical Guide to Scaling ArchUnit with Nebula ArchRules

A practical guide to scaling Java architecture rules across thousands of repositories using ArchUnit and Nebula ArchRules, with setup steps, common pitfalls, and ecosystem updates.

Bvoxro Stack · 2026-05-21 00:03:23 · Programming

Overview

In large-scale Java organizations, maintaining consistent architecture across hundreds or thousands of repositories is a monumental challenge. Netflix's JVM Ecosystem team tackled this by extending ArchUnit with Nebula ArchRules, turning ad-hoc architecture guidance into enforceable, fleet-wide checks. This tutorial walks through the core concepts and a step-by-step approach to implement similar systems in your own organization, covering build-time feedback, technical debt visibility, and the practicalities of scaling architecture rules.

Building Fleet-Wide Java Architecture Rules: A Practical Guide to Scaling ArchUnit with Nebula ArchRules
Source: www.baeldung.com

Prerequisites

  • Familiarity with Java and build tools (Gradle preferred, as Nebula integrates tightly).
  • Basic understanding of architectural principles (layering, dependencies, patterns).
  • A Java project with a build system that supports custom plugins.
  • (Optional) Polystores or monorepo experience is helpful but not required.

Step-by-Step Guide

1. Setting Up ArchUnit in a Single Repository

Start by adding ArchUnit to your project. ArchUnit is a free, extensible library for checking the architecture of Java code using unit test-like assertions. For a single repository, you can define rules in a test class:

// build.gradle
dependencies {
    testImplementation 'com.tngtech.archunit:archunit-junit5:1.3.0'
}

// ArchTest.java
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*;

public class ArchTest {
    @Test
    void servicesShouldOnlyBeAccessedByControllers() {
        classes().that().resideInAPackage("..service..")
            .should().onlyBeAccessed().byAnyPackage("..controller..", "..service..")
            .check(new ClassFileImporter().importPackages("com.mycompany"));
    }
}

This gives immediate feedback during build. However, maintaining hundreds of such rule files across many repositories becomes unmanageable. Enter Nebula ArchRules.

2. Centralizing Rules with Nebula ArchRules

Netflix's Nebula ArchRules is a Gradle plugin that allows you to define architecture rules in a central place (a “rules repository”) and then apply them across all your projects. The setup involves two parts: the rules repository and the consuming projects.

Rules Repository

Create a new Gradle project that packages your ArchUnit rules as a reusable artifact. For example, define rules as Java classes extending ArchRule or using the standard ArchUnit DSL, then publish the artifact to a internal Maven repository.

// rules-repo/build.gradle
plugins {
    id 'java'
    id 'maven-publish'
}
dependencies {
    implementation 'com.tngtech.archunit:archunit:1.3.0'
}

// src/main/java/com/netflix/archrules/NoCyclicDependencies.java
public class NoCyclicDependencies implements ArchRule {
    @Override
    public void check(JavaClasses classes) {
        // Implementation using ArchUnit
    }
}

Consuming Projects

In each project, apply the Nebula ArchRules plugin and reference your central rules artifact. The plugin automatically aggregates and runs all defined rules during the build.

// consumer/build.gradle
plugins {
    id 'nebula.archrules' version '2.0.0'
}
dependencies {
    archrules 'com.netflix:my-archrules:1.0'
}

3. Integrating Build-Time Feedback

Once applied, every build that runs gradle check will execute the rules. Failures should break the build, giving immediate feedback to developers. This “shift-left” approach catches architectural violations before code is even committed. To make it actionable, ensure error messages clearly describe the rule and how to fix it. For example:

Architecture violation in MainController.java: Method getAllUsers() directly called a repository instead of a service interface. Use a service layer instead.

4. Measuring Technical Debt Visibility

Netflix emphasizes turning architecture violations into measurable technical debt. With Nebula ArchRules, you can categorize rules by severity (e.g., error vs warning) and collect metrics across all repositories. Use a reporting tool (like Gradle’s built-in reports or a custom dashboard) to track the number of violations over time. This data helps prioritize refactoring efforts and demonstrate the value of architectural governance to leadership.

Building Fleet-Wide Java Architecture Rules: A Practical Guide to Scaling ArchUnit with Nebula ArchRules
Source: www.baeldung.com

5. Enforcing Across Thousands of Repos

The true scale comes from applying these rules fleet-wide. Netflix manages thousands of Java repositories; the JVM Ecosystem team ships the rules artifact and plugin version updates centrally. Every project automatically gets the latest rules when it updates its dependencies. To handle exceptions (e.g., legacy projects that cannot immediately comply), use ArchUnit’s ignoreDeclaredExceptions or a custom configuration file that excludes specific packages or classes. Over time, gradually reduce the exception list as technical debt is paid down.

Common Mistakes and Pitfalls

  • Too many strict rules too soon: Start with a small, high-impact set of rules (e.g., layer violations, cycle prevention). Gradually add more as the team adapts.
  • Ignoring false positives: Break the build only for genuine violations. If a rule is too broad, refine it to avoid developer frustration.
  • Not updating rules centrally: If each repository can override or skip rules, the fleet-wide governance breaks. Use centralized versioning.
  • Lack of developer education: Architecture rules are only effective if developers understand why they exist. Document each rule and provide examples.
  • Overlooking performance: ArchUnit analysis can slow builds. Use caching and parallel execution (available via JUnit5) to mitigate.

Summary

Scaling architecture rules across an enterprise is challenging but achievable with ArchUnit and Nebula ArchRules. By centralizing rule definitions, providing build-time feedback, and tracking violations as technical debt, you can maintain consistent architecture across thousands of Java repositories. The approach aligns with Netflix’s production-proven strategy and can be adapted to any organization using Gradle.

Additionally, the Java ecosystem continues to evolve. Notable updates from the original digest include: JDK 25’s FFM API for native interoperability, JDK 27’s preview features (structured concurrency and primitive type patterns), and releases of Quarkus, Spring AI, Hibernate Search, and more. For deeper dives, explore the linked resources: Netflix Tech Blog, Inside Java, and InfoQ. The shift toward enforceable architecture rules is just one part of building robust, future-proof Java systems.

Recommended