3 ms·
Your vision of the Java version numbers seems different from the way all developers I know see the Java version numbers. It doesn't matter that minor releases
by cesarb 6y ago
Your vision of the Java version numbers seems different from the way all developers I know see the Java version numbers.
It doesn't matter that minor releases within Java 7 or Java 8 introduced new features. What matters is compatibility. If your code ran on a given Java 7 release, it would work unchanged on all later Java 7 releases; the same for Java 8. The same pattern still applies for later Java versions; if your code ran on a given Java 9 release, it should work unchanged on all later Java 9 releases, but not necessarily on Java 10 or Java 11 (this is not a theoretical concern, I've seen it happen in practice).
> but I think the main issue is that many companies are severely overestimating the cost of the one last major upgrade past 8
I worked on upgrading one large codebase from Java 8 to also compile and run on Java 9 and Java 11 (making it run on Java 9 is a good first step to making things run on Java 11, but it's not enough; there are important breaking changes on Java 11), so I have a good idea of the costs. It's not just the compiler being slightly more strict with generics and a new class in java.lang conflicting with a wildcard import, which are very easy to fix, or the whole system failing to initialize when ran on the Java 9 or Java 11 JVM, which is annoying but hard to miss; it's also less used parts of the system failing to work when it's on a Java 9 or Java 11 JVM, many months later.
You not only have to upgrade your code (and hope your QA and unit tests caught all relevant cases) for the new Java version, but you also have to upgrade all your dependencies, recursively (and hope they didn't introduce any compatibility breaks themselves), and sometimes even introduce new dependencies (especially for Java 11). As late as this year, I was still seeing open source libraries releasing compatibility updates for Java 9 and/or Java 11.
- pron 6y ago8 -> 9+ is an entirely different story, because not only was 9 the last (ever) major release, but it was a particularly big one. > If your code ran on a given Java 7 release, it would work unchanged on all later Java 7 releases; the same for Java 8. The same pattern still applies for later Java versions; if your code ran on a given Java 9 release, it should work unchanged on all later Java 9 releases, but not necessarily on Java 10 or Java 11 (this is not a theoretical concern, I've seen it happen in practice). But the situation now is even better. If your code works on 9, it will work with no or very few changes on 10 and if it works on 14 it will work with no or very few changes on 15, but while there might be slightly more work between 14 and 15 than between 8u20 and 8u40, in exchange you never have another major upgrade again. So the work is just spread differently, and in a way that makes it less costly overall, true, once you've got used to it. But there's one more difference to those who do remember how things were: It is true that in the Java 6-7 era there weren't as many breaking changes, but that was mostly because Sun was dying and Java barely changing. With Oracle's growing investment, change is picking up, and the new release model makes it easier to cope with, not harder, as those who'll skip too many feature releases are sure to find out. > You not only have to upgrade your code (and hope your QA and unit tests caught all relevant cases) for the new Java version, but you also have to upgrade all your dependencies, I'd say that such a policy is based on folklore and/or luck rather than actual long-term experience. You have to do that for every patch release, too (although "upgrading your code" is not something that's very common in Java; most JDK 1.4 code still runs unchanged, and the required changes are mostly on the command line, not in the code). It is not the small spec changes that are most likely to break your code in complex ways, but internal changes that occur even in patches. The change that required the most code changes since 9 has been this one [1], in 11.0.2/8u202 -- i.e. a patch release, not a feature release. The one area where there is more need to update dependencies on feature releases than patch releases is in bytecode parsing/manipulating libraries, some of which for some historical reason (a bad ASM accident about 8 years ago) still insist on shadowing ASM into their JARs. As a consumer of such libraries, you should advise them to stop. [1]: https://pangin.pro/posts/computation-in-static-initializer https://pangin.pro/posts/computation-in-static-initializer
- mumblemumble 6y agoAdd to this that multi-release JARs created a way for Java 9 to break your code even when you're staying on Java 8†, and it's pretty easy to see why long-time Java shops are jumpy. Things had been moving along relatively slowly and placidly for quite a long time, and then, all of a sudden, Java gets a bee in its bonnet and decides that it, too, needs to move fast and break things. † Admittedly only if you're getting feisty with run-time reflection fanciness. Which you probably shouldn't, in principle, be doing in the first place. But, in practice, it's pretty standard practice in Java.
- pron 6y agoChange is not made for the thrill, but because changing hardware, hosting, software requirements and changes in the wider software ecosystem demand it. Most of what Java broke and is about to break is the ability of libraries to too-strongly depend on implementation details -- what you admit you know is bad but do anyway; if every implementation detail is exposed and relied on, then the necessary changes cannot be made in a backward compatible way. In other words, Java is breaking the ability of libraries to break its backward compatibility. I'm sure this will require some adjustment, but is overall a better plan for backward compatibility in the long term than reducing investment in the platform and not coping with necessary change.
- mumblemumble 6y agoAll of this is true. But avoiding change is not just knee-jerk stodginess, either. In a large, long-lived Java codebase, the cost to test for breaks can be immense. So you've got to convince yourself that the cost to stay on the old JDK is greater than the cost of moving to a new one. I think we can see from the Python 2->3 precedent that it's easy for new projects to adopt the new platform. That, in turn, incentivizes library maintainers to make the migration. But the only thing that will really motivate many business users to migrate is an end of support. Which, in Java 8's case, means we'll start seeing more movement as 2030 looms closer. That's an entirely rational business decision. 2030 is a long way away. Anything could happen on that kind of a time scale, including things that would render a migration past Java 8 a waste of resources, like the project being canceled or migrated off of Java entirely.