Java rules here. You can take any Java 1.0 (1995) codebase and compile it as-is on a recent JDK. Moreover, you can also use any ancient compiled Java library and link it to modern Java app. Java source and bytecode backward compatibility is fantastic.
* Terms and conditions apply
Java is very good here, but (and not totally it's fault) it did expose internal APIs to the userbase which have caused a decent amount of heartburn. If your old codebase has a route to `sun.misc.unsafe` then you'll have more of a headache making an upgrade.
Anyone that's been around for a while and dealt with the 8->9 transition has been bit here. 11->17 wasn't without a few hiccups. 17->21 and 21->25 have been uneventful.
Can confirm; my team spent the past 9 months upgrading an application JDK 8 -> 17, and there were breaking changes even after we got it compiling + running
Java has had some breaking changes (e.g., [0, 1]), though in practice I have to say my experience tends to agree and I've been fortunate enough to never run into issues.
[0]: https://stackoverflow.com/q/1654923
[1]: https://news.ycombinator.com/item?id=28542853