Handle common migration problems such as unclear boundaries, leaky Java interop, hidden side effects, team unfamiliarity, performance anxiety, and Java architecture habits that no longer fit.
Most migrations fail for predictable reasons: unclear boundaries, too much interop in the core, mutability sneaking back in, or a team trying to force Java architecture patterns onto Clojure.
This section collects practical fixes and review questions so you can keep the migration honest: use Java libraries where appropriate, but let the core become idiomatic Clojure so you get the real maintainability and testability benefits.
| Migration problem | Practical response |
|---|---|
| Interop spreads everywhere | Add adapter namespaces and convert Java types at the boundary. |
| Clojure imitates Java classes | Revisit the data model and move behavior into pure functions. |
| Side effects are hard to test | Push I/O, time, randomness, and mutable state to named edges. |
| Team confidence drops | Keep changes small, preserve tests, document seams, and review expanded Clojure code directly. |