Public Means Public
Often in a code review I’ll point out that public signatures are being changed, and we can’t do that in a minor release. Then the author will reply that it’s OK because it’s an internal only API, or an impl API, or both so it’s OK. No one is depending on it. And then this happens:
Error: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.14.0:compile (default-compile) on project mvnd-daemon: Compilation failure Error: /Users/runner/work/maven-mvnd/maven-mvnd/daemon/src/main/java/org/mvndaemon/mvnd/syncontext/DaemonNamedLockFactoryAdapterFactoryImpl.java:[48,9] no suitable constructor found for NamedLockFactoryAdapterFactoryImpl(java.util.Map,java.lang.String,java.util.Map ,java.lang.String,org.eclipse.aether.impl.RepositorySystemLifecycle) Error: constructor org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl.NamedLockFactoryAdapterFactoryImpl(java.util.Map ,java.util.Map ,java.util.Map ,org.eclipse.aether.impl.RepositorySystemLifecycle) is not applicable Error: (actual and formal argument lists differ in length) Error: constructor org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl.NamedLockFactoryAdapterFactoryImpl(java.util.Map ,java.lang.String,java.util.Map ,java.lang.String,java.util.Map ,org.eclipse.aether.impl.RepositorySystemLifecycle) is not applicable Error: (actual and formal argument lists differ in length) Error: -> [Help 1]
Hyrum’s Law applies. From JLBP-3:
Examples of breaking changes to a public API that require a new major version:
- Upgrading to an incompatible dependency that is exposed through a library’s public API. For dependencies that follow semantic versioning, this happens when a dependency is bumped to a higher major version.
- Changing a method signature
- Removing a method (deprecated or not)
- Adding a method to an interface without a default implementation
- Adding an abstract method to a class
There’s no exception because something is called “internal” or “impl”.
Also worth remembering, Maintain API stability as long as needed for consumers.