Open source · LGPL-3.0
maddi
maddi works out what is actually immutable in your Java codebase — and tells you why it isn’t.
Computed, not declared
maddi is a whole-program static analyzer for Java — and for Kotlin, through a shared syntax tree. You don’t write annotations: maddi computes them. It reads your sources and your classpath, follows how objects flow between fields, parameters and return values, and derives @Immutable, @Container, @Modified and @Independent for every type, method and field.
Levels, not verdicts
@Mutable → @FinalFields → @Immutable(hc=true) → @Immutable. Real code is rarely deeply immutable, and a yes/no answer throws away everything useful. A level tells you how far you got — and what stopped you.
Honest about hidden content
hc=true records the caveat that a link runs to the elements of a type parameter maddi cannot see into. It is not hc-free @Immutable, and the tool does not pretend otherwise.
Eventual immutability
@Mark, @Only and @Immutable(after=…) describe the builder and freeze patterns: types that are mutable while being constructed, and immutable ever after.
Use the annotations without adopting the analyzer
The only artifact your own code compiles against is the annotations library. From 0.9.0 it is Apache-2.0, has no transitive dependencies at all, and targets Java 17 — so you can depend on it without taking on the analyzer’s LGPL.
implementation("io.codelaser:maddi-support:0.9.0") // Gradle
They are useful as documentation and as contracts on your interfaces even before you run the analyzer, because maddi verifies them against what it computes. The library also carries the eventually-final support classes — SetOnce, Freezable, EventuallyFinal, Lazy and FirstThen.
Status: not yet production ready
This section is kept honest deliberately. If you run maddi on your own code today, expect rough edges — issues and questions are very welcome.
| Part | State |
|---|---|
| Concepts, and the book | Stable |
| Parser / resolver (javac front end) | Robust; exercised on many open-source projects and one closed-source 3M-line codebase |
| Modification & immutability analysis | Runs to a certified fixpoint on a proving-ground corpus — Timefold, LangChain4j, Fernflower, Guava, ActiveMQ, Jenkins, Camel. Not yet ready for general use |
| Kotlin front end | Works; ships only via the mixed CLI |
| Gradle / Maven plugins | Functional, but have had little attention recently |
| Releases | Annotations on Maven Central (0.9.0). The analyzer itself is built from source |
From e2immu to maddi
maddi re-implements e2immu, which ran from 2020 until it was archived at v0.6.2. Same ideas, rewritten analyzer, now covering Java and Kotlin. The root Java package is still org.e2immu.*, after its predecessor.
maddi is developed by Bart Naudts at CodeLaser, and is and will remain open source. CodeLaser’s commercial Refactor product is built on this engine — the engine stays here, under this licence.
Get started
The concepts are developed in full in The Road to Immutability. The user manual covers running maddi on your own project.