Comment by Aeolun
2 years ago
> java where 10 year old code still runs fine with their modern tooling
I don’t know about you. But even when I try to run 3 year old Java code with a new SDK it’s always broken somehow.
2 years ago
> java where 10 year old code still runs fine with their modern tooling
I don’t know about you. But even when I try to run 3 year old Java code with a new SDK it’s always broken somehow.
I write Java for 15 years and I've yet to encounter a single JVM bug or incompatibility. It's always application to blame.
The only exception is Java 9 which removed some Java EE dependencies from JDK, but that's easily solved.
Just an example: I'm running application on Java 21 which uses Oracle 9i driver that was compiled for Java 1.4 and it works fine.
There are plenty of other removals, deprecated stuff like Thread.stop(), security providers, JDBC interfaces changes, finalizers no longer do anything (better not depend on them ever running) and might be removed in some future version.
Java does not have perfect backwards compatibility, but it's pretty good.
Thread.stop was deprecated very long time ago. It was deprecated at least in Java 6 (2006 year) and I'm too lazy to check for earlier versions.
Security providers have very limited usefulness for ordinary applications. And AFAIK it's not even removed for Java 21 yet, so formally old apps should work for now.
I'm not aware of incompatible JDBC interface changes and I used to use very old Oracle driver without that much problem. Yes, there are some new methods in JDBC interfaces which are not implemented with old drivers, but you can just not call those methods. It's not breaking change.
Finalizers were never reliable. But you're not correct about them not running right now, I just checked and with Java 21 they're called.
So while there are breaking changes, they're always some application issues. If you call Thread.stop, you should not do that, that's bad application. If you're using security providers, you should not do that, they're not safe enough, you should use containers or VM or other means of code isolation. I'm not completely sure about JDBC issues, but I had experience running very old JDBC driver and it works just fine. If you rely on finalizer, you should not do that, that's wrong approach to resource management and it was always wrong.
Like I said, it's application to blame.
I maintain Eclipse RDF4J and I noticed this too between Java 9 and 11, after that there haven’t been any breaking things except for having to bump a maven plugin dependency. We make sure to stay compatible with both Java 11 and whatever is the newest version by running our CI on both Java versions.
Any examples? Actual Java code works all the way back to 1996 IME, the only thing that breaks is reflection nonsense, usually Spring.
You can run Minecraft 1.7.10 and mods on Java21 with surprisingly few changes needed.
https://github.com/GTNewHorizons/lwjgl3ify
All the stuff that got removed since Java 9, as the new policy is to actully remove deprecations after a couple of warning releases, instead of supporting them forever.
Additionally, being more strict regarding internal APIs security, not allowing access to JVM internals by naughty 3rd party libraries.
I had major issues running Bitcoin Armory after a few years, which was rather problematic.
Years? After one year, something amongst the hundreds of deps will have a horrible security vulnerability and updating means breaking changes.
I've had JRE minor version revisions break things. The compatibility is there, but it's below legendary.