[External] : Re: New informational JEP: 14: The Tip & Tail Model of Library Development

Karsten Silz karsten.silz at gmail.com
Thu Nov 28 07:25:10 UTC 2024


Alex, thank you very much for your long reply! 

I'm sorry for asking all these questions. But half a year ago, Mr. Goetz issued "a bit of a call to action" on T&T (https://www.youtube.com/watch?v=YBGVK5JuSJ8&t=2421s). I want to write about this for InfoQ, so I need to understand it before explaining it to my readers. But that call to action was light on details. The talk at the JVM summit had a bit more details (https://www.youtube.com/watch?v=NV4v7KXKQ-c&t=1320s) but still not enough for me. When I saw the JEP, I thought, "Well, finally, this is going to tell me how to do T&T". But it doesn't because it's just the philosophy, as you explained. 

I do not know if and when you guys will say more about T&T, apart from answering questions from annoying folks like me. :-) So, if you'll publish more details on T&T soon, please disregard my questions.

> On 25 Nov 2024, at 22:04, Alex Buckley <alex.buckley at oracle.com> wrote:
> 
> Those are the two assumptions of T&T: that users who deploy update releases of an older JDK (17, released three years ago) prefer stability over new functionality; and that users who wish to obtain new functionality can and will upgrade to newer libraries and JDKs.

Whoa, now you're really throwing me a curveball here! :-) I'm sorry, but I do not find either of these assumptions in the JEP. And I think that Spring Boo does not follow them.

The first assumption is that "users who deploy update releases of an older JDK (17, released three years ago) prefer stability over new functionality". This sounds like you cannot baseline your tip on an older LTS release, like JDK 17. But in the "Picking a JDK baseline" section, the JEP only says, "In the tip train, baseline each tip release on the JDK version that best supports the library's new features and enhancements." I read that as "A library is free to pick whichever JDK it wants as the baseline." Mr. Goetz' slide was more restrictive: It stated that the "latest version of a library [should be] baselined on selected recent JDK version". That "recent" is missing from the JEP.

A little further down, a bullet says: "It is typical to bump the JDK baseline of the tip train when the library needs new JDK features." I'm unsure if it is a general recommendation, as it's derived from an example in the JEP. Let's assume it is. It's still a recommendation to me, as it does not say, "Thou shall always bump the JDK baseline". So, if you do not bump the baseline, you may not be a "typical library", but you can still be T&T in my eyes.

The second assumption is that "users who wish to obtain new functionality can and will upgrade to newer libraries and JDKs". That sounds like a library must bundle new features with new JDK releases. Again, I don't see that in those JEP bullets I quoted above. 

Spring Boot, Quarkus, and Micronaut all have a JDK 17 baseline for the tip and deliver new features with that baseline today, not matching the first assumption. Helidon has a JDK 21 baseline, so it does match it. Spring Boot will even keep that JDK 17 baseline at least until November 2027: Spring 7, starting in November 2025, retains JDK 17 – but upgrades to Jakarta EE 11 and Kotlin 2. Mr. Hoeller announced this the day after you created the JEP (https://spring.io/blog/2024/10/01/from-spring-framework-6-2-to-7-0). 

Spring Boot (and Quarkus and Micronaut, I think) support new JDK versions quickly on the tip through multi-release JARs, but do not bump the baseline. So, users get new functionality without upgrading the JDK, not matching the second assumption, either.

Users cannot get new JDK functionality when staying on JDK 17. But for Spring Boot, barely any new functionality seems to depend on JDK versions greater than 17. Spring Boot 3.0 switched to JDK 17. The only new JDK feature I could find mentioned in the Spring Boot 3.1-3.4 release notes (go to https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes and then pick 3.2-3.4 on the right) was virtual threads: Introduced in 3.2, spreading to more places in 3.3 and 3.4. More features may require new JDK versions, but the release notes didn't say.

Could you point out where these two assumptions are expressed in the JEP? And does Spring Boot follow T&T, with a JDK 17 baseline on the tip, even after JDK 25 is released next year, and the use of multi-release JARs to support new JDK versions?

Here's a thought: OpenJDK does T&T. And T&T talks about the baseline. Do you consider the operating system the baseline for OpenJDK? :-)

If so, then the Oracle JDK does not follow these two assumptions. Oracle JDK 23 supports four macOS versions, three Windows server versions, two Windows Client versions, and a lot of Linux versions (https://www.oracle.com/java/technologies/javase/products-doc-jdk23certconfig.html). Oracle JDK 21 supports one macOS version that Apple does not support anymore and two Ubuntu versions that Canonical stopped supporting (https://www.oracle.com/java/technologies/javase/products-doc-jdk21certconfig.html). Finally, Oracle JDK 17 tops that with three unsupported Windows versions, three unsupported macOS versions, and six unsupported Linux versions (https://www.oracle.com/java/technologies/javase/products-doc-jdk17certconfig.html).  

> Since T&T wasn't known until recently, allow me to paint a picture of what would have happened with Spring Boot in a fully T&T universe. Spring Boot 3.2 and 3.3, having been released after JDK 21, would have been baselined on JDK 21 rather than JDK 17. Users who create new microservices would be upgrading from 3.0/3.1 to 3.2/3.3 to enjoy new features, and upgrading from JDK 17 to JDK 21 for exactly the same reason.

When you say, "in a fully T&T universe", does that mean that either now or in the future, T&T will require libraries to quickly baseline on new LTS JDK versions? Again, I didn't find that as a requirement in the JEP.

You suggest Spring and Spring Boot should change their Java baseline during a generation. Spring has not done this for a while, if ever. And the next generation will stick with JDK 17, as mentioned above. I got to ask Mr. Hoeller why. Here's his answer (https://www.infoq.com/news/2024/11/spring-6-2-spring-boot-3-4): 

"Our baseline is usually derived from technical concerns. Java 17 provided so much goodness over Java 11 (the alternative choice at the time) that we went with it for Spring Framework 6.0 right away, dramatically modernizing our codebase and pushing the industry overall – at the expense of making the upgrade path harder, in combination with the Jakarta EE namespace change at the same time.

For Spring Framework 7.0, there is hardly any technical benefit in a Java baseline upgrade. Specific features against newer Java versions can easily be provided through multi-release jars, as we do for Virtual Threads in Java 21 already. The current industry consensus is clearly around a Java 17 baseline, for example, with the Jakarta EE 11 APIs and the upcoming provider generation there. Since our current framework codebase would not benefit from a baseline upgrade, we are aiming to stay on a Java 17 baseline while providing first-class support for Java 21 as well as Java 25 in the same generation. Instead, our baseline raise comes with Jakarta EE 11 APIs, such as Jakarta Servlet 6.1 and Jakarta Persistence 3.2, as well as Kotlin 2.

We generally recommend the latest Java LTS generation for production deployment, independent from the underlying baseline, which is effectively just a technical minimum that the framework tolerates at runtime. For Spring Framework 7.0, despite a Java 17 baseline, our focus is clearly on embracing Java 25. Looking forward, we can see Java 25 becoming an attractive new baseline for the wider Java ecosystem at a later point. However, for the time being, the best we can do is to support it as part of our JDK version range."

Library authors may also be interested in reaching the widest audience possible. Especially commercial ones that depend on support & training fees. If Spring Boot 3.2 had switched to JDK 21 in November 2023, then in March 2024, four months after its release, only 1.4% of all Java users could have run it in production. That's compared to 35.4% that could run JDK 17 then. Even now, two years after Spring Boot 3.0 bumped the baseline to JDK 17, maybe only 50% of all Java users can run Spring Boot 3.x.

So, when libraries switch the tip to new JDK releases quickly, they restrict the tip releases to the few percent of Java that can actually run these new JDK versions in production. This may be fine for some or many libraries – Spring Boot did this with Spring Boot 3 and JDK 17. But I can understand why some librariy don't want to limit their audience that heavily and regularly.

I got the JDK distribution numbers from New Relic's "2024 State of the Java Ecosystem". The PDF download is at https://newrelic.com/resources/report/2024-state-of-the-java-ecosystem, then go to page 5. They probably collected the data in March 2024: "In the six months after the release of Java 21". New Relic's data "is based on data gathered from hundreds of thousands of applications reporting to New Relic that provide performance information". The report is obviously biased towards the kind of customers that use New Relic. But these numbers are the best ones I got. At Oracle, you may have other numbers.

I don't take surveys into account because I haven't seen many good ones in the Java world. For instance, the JRebel "2022 Java Developer Productivity Report" surprised the world by predicting that 37% of the surveyed Java developers want to upgrade to Java 17 by July 2022 – less than a year after its release (https://www.jrebel.com/resources/java-developer-productivity-report-2022): The survey ran from October 2021 to January 2022, and the answer was "Upgrade to Java 17 within the next six months". According to New Relic, Java 17 probably was indeed at 37% in July – but 2024, not 2022. :-)

> In the increasingly rare cases of tools and libraries that *still* don't support JDK 21, their issue trackers are often full of users trying to explain to maintainers that JDK 17 isn't the latest Java anymore -- and full of responses from maintainers about how they don't want to abandon users on JDK 17 by mandating JDK 21. This one-size-fits-all mentality by maintainers is exactly what T&T seeks to overcome. They can offer a 17 train at low cost because *it has no new features*, and offer a 21 train that adapts to whatever is new in JDK 21.

I do not speak for Spring Boot. But I've written about Spring Boot releases in the past. So, I can think of three reasons why Spring Boot users on JDK 17 are happy to get tip releases still.

First, a tip release has all the bug fixes, a tail release gets only the critical ones. Second, as mentioned above, most new Spring Boot features do not depend on new JDK features and are available on JDK 17. Third, Spring ecosystem projects (Spring Data, Spring Batch, Spring Security, Spring Integration, …) recommend or require new Spring Boot versions, as do non-Spring libraries with auto-configuration through Spring Boot. That may actually be the biggest reason to upgrade: Users want new library versions and must upgrade Spring Boot, even though they may not care much about it. And every couple of years, Spring Boot makes them upgrade Java – if they haven't done so by themselves.

I think the first two reasons may apply to other libraries. The last one may be specific to Spring.

> There are users running an Early Access of JDK 24 today in advance of deploying it next March. They're frustrated with tools and libraries that can't seem to grasp how there's a new production-ready feature release of the JDK every six months.

The JEP says, "It is not necessary to develop tip releases in lock step with the JDK's six-month tip releases." You seem to scold libraries that don't. So, is not being in "lock step with the JDK's six-month tip releases" still T&T?

Non-LTS JDK versions make up "less than 2%" in production, according to the New Relic report I quoted above. If you add up the numbers on page 5 of their report, it's 1.3%. They analyzed the data in March 2024, six months after JDK 21. But even if we assume that everybody in the 1.4% on JDK 21 came from JDK 20 and not JDK 17, that's still a total potential of only 3% for non-LTS versions today. Java frameworks have supported new JDK versions quickly for 2-3 years now. Do the 97% of Java users on LTS versions in production just not know about this today? Will they learn over the next few years? Or do they just not care enough?

Now, these numbers are different from what Oracle cited three years ago: "developer surveys show six-month (non-LTS) releases being used by between a quarter and half of developers surveyed, only about half of those note their use is in production" (https://blogs.oracle.com/java/post/moving-the-jdk-to-a-two-year-lts-cadence). That comes up to 6.5-12.5% using non-LTS versions in production. I don't know the survey he's referring to, but I am skeptical of surveys – see above.

While we're at it: I never understood this argument: "it makes sense to adjust our future LTS releases to a two year cadence.  [...]  It also makes the use of six-month releases more appealing as organizations know the next available LTS will always be less than two years away. " Why does a two-year cadence make non-LTS versions more appealing? Most Java users were happy to skip five non-LTS releases and wait three years for the next LTS release in the past. Why would they start using non-LTS now that they only have to skip three non-LTS releases and wait only two years?

> If this seems astonishing to you, look at Stream Gatherers -- JEP 485 -- and think about all the streams you've written where you wished for this feature. (And no, it won't be backported to JDK 21.)

I'm more of a loop guy. ;-)

Do you have any telemetry data or analysis of public Java code (e.g., on GitHub) that shows which percentage of Java programs use newer JDK features?


Regards,
Karsten Silz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jdk-dev/attachments/20241128/c0e4543c/attachment-0001.htm>


More information about the jdk-dev mailing list