A production error reads `ClassCastException: Cannot cast plugin.PriceRule to plugin.PriceRule` — the exact same class name on both sides. A teammate assumes it's a build artifact with a stale class file. Is that a reasonable first guess, and what's actually going on?
It's a reasonable first instinct, but it's the wrong mechanism — there's no typo and no stale file. A class's real identity at run time isn't just its name, it's the pair (name, defining class loader): the same .class file loaded by two different loaders produces two genuinely different Class objects that happen to share a name. The cast fails because an object created by loader A's PriceRule is being handed to code expecting loader B's PriceRule — different classes as far as the JVM is concerned, identical strings as far as the error message goes. This shows up in application servers with a library present in both the server and the deployed app, plugin systems, hot-reload tooling, or a dev-mode restart loader holding one copy of a class while something else cached another.