Attempted Shaded Dual-Version Dependency

STATUS

COMPLETED

TIMELINE

Started: 2025-12-08
Completed: 2025-12-11

TECHNOLOGIES

JavaSpring Boot

Postmortem

What I Learned

It was a good reminder that trying to support rollbacks without redeploying is more than just a deployment concern. Shading two versions of the same module into a Spring Boot jar sounded like the perfect solution on paper, but once both versions shared the same package name, I couldn’t get Spring and the JVM to reliably work together at runtime.

Roadblocks

The core issue is that shading two versions of the same code into a single runnable Spring Boot jar only works if they’re isolated at the package or classpath level. Without relocations or treating one version as a true plugin via its own classloader, both versions exist in the same namespace. Spring Boot’s component scanning doesn’t provide a clean way to choose between versions at startup, which ultimately made this approach unworkable.

Background

There is a module that gets built and deployed two ways: as a standalone API service, and also as a dependency inside another Spring Boot service (pulled in through the pom.xml and packaged into the consuming app’s final jar). That setup normally works fine, but it becomes painful during major version upgrades. If a new release causes problems, rolling back requires a new hours long build and deployment so it can be referenced with a stable version. I wanted to build some resiliency into this so we could roll back quickly without triggering another build and deployment. The idea was to ship a “stable” implementation alongside the new one and choose which to run at startup.