Leaky internals

The problem

You open an implementation package and nearly every class is public. Only a handful look like the real contract, but the rest are available to become one. Is this a deliberate API surface, or did the package quietly lose the boundary that was supposed to protect its internals?

Why it matters

A JVM-public class can be reached from outside its package. Once callers depend on it, changing or moving it can carry impact beyond the package you thought you were refactoring. Broad visibility is perfectly reasonable for APIs, DTO contracts, facades, and plugin extension points. In an implementation package, it is worth checking whether the exposed surface still matches the job.

Where to start

Begin with Composition.

Step by step

  1. Start Leaky internals.

    In the Workflow Wizard, choose Leaky internals and click Start exploring. AtlasArc opens Composition with the Relative Visibility heatmap and no dependency cutoff, so packages are not removed before you can inspect their public surface.

  2. Pick a high-RV candidate.

    A stronger colour means a larger share of the package's JVM classes are public. That is a reason to look, not proof of bad design. Select the package and read its Relative Visibility detail before deciding what kind of boundary it is meant to be.

  3. Drill into its classes.

    Follow the Treemap down to a leaf package. The class view marks JVM-public classes with a coloured edge and a JVM public label where the tile has room. Hover any class for the exact visibility fact.

  4. Check callers and source.

    Select a marked class to inspect its Fan-in and Fan-out. Open the source when you need to understand whether it is a contract, a DTO, an extension point, or an implementation detail that happens to be reachable.

  5. Verify the dependency evidence.

    Switch to Topology for the package's incoming and outgoing dependencies and the concrete references behind relevant edges. Open Package Internals only when you also need the local class relationships inside that package.

  6. Make the surface deliberate.

    Keep a public API, DTO contract, facade, or plugin extension point that is doing a real job. For accidental exposure, narrow JVM visibility where the language permits or move the implementation behind a smaller public seam.

Interpreting results

Relative Visibility is public JVM classes divided by all JVM classes in the package. There is no universal target: an API package and an implementation package are supposed to have different shapes. The useful outcome is an intentional surface backed by real consumers. In Java, narrowing that surface may mean package-private classes. In Kotlin, remember that RV reads compiled JVM visibility, so source-level internal is a separate design choice and may still appear JVM-public to this metric.

Export & share

Export the Composition view as PNG with the Relative Visibility heatmap active to show where the JVM-public surface concentrates. When one package needs evidence, capture the focused Topology view with the relevant dependency references visible.