Insofar as that perception exists, I don't think it can be blamed on the
Java 8 compatibility baseline. Netty still used a compatibility baseline of
Java 6 (!) until Netty 4.2 came out last year and raised it to 8. The
correct way of viewing the bytecode upgrade is as a means to an end, not an
end to itself: what does it gain us? What goals would it allow us to
pursue? I'm not asking rhetorically; I can't think of a compelling answer,
but maybe someone else can.

It's worth pointing out that a lot of the other big projects in the Java
ecosystem that have performed a bytecode upgrade have done so
_incidentally_ as part of a major version bump that pursued other strategic
goals. Slf4j had to overhaul its logger discovery mechanism for Jigsaw
compatibility. Log4j needed to split up `log4j-core` and move optional
features into separate modules, and also deal with issues involving plugin
discovery and Jigsaw compatibility. Spring had a Java EE dependency and had
to migrate to Jakarta EE. I think we should also approach the Java 17
upgrade as part of a larger modernization effort, starting by writing down
what we want to do that isn't possible under the current backwards
compatibility constraints (including bytecode level).

As for Java HttpClient, it will cover a lot of basic use cases as
HttpsURLConnection did, but a standard library HTTP client will never
compete with a third-party client for feature-completeness,
customizability, extensibility, or independent upgradability. If you survey
other programming languages, it's rare for the "main" HTTP client to be the
one that ships with the standard library, rather than a more advanced
third-party client. (The main exception is Golang, and I've heard at least
one report of a team that was forced to fork Go in order to patch its
HTTP/2 implementation.) Standard libraries have some of the most extreme
backwards-compatibility constraints you'll encounter outside of kernel
development, so they tend to be highly conservative about which features
and APIs they expose.

Also, correct me if I'm wrong, but Java HttpClient seems to only support
low-level configuration in the form of global system properties, just like
HttpsURLConnection. This makes it almost totally unsuitable for library
developers: even if the option I need is available (it usually isn't), I
have no control over it. I'm still glad it exists, as it's convenient for
simple use cases, but I think the Apache client (particularly the classic
transport) is still the best option in the entire Java ecosystem for
building a robust real-world system.

I think over the next few years, we can stay on Java 8 while still
implementing various modernizations (I've previously suggested shipping
Graal and Jigsaw support, improved CompletableFuture support in the
non-fluent async API, etc). During that time, I expect major JDK
improvements to ship, in particular the Project Valhalla technology: value
types, Java nullability marking, immutable/frozen arrays, etc.; we may also
see transport layer additions, like a QUIC API. Then, HttpComponents 6
could leapfrog to _the latest_ version of Java, with a comprehensively
modernized API, Valhalla-derived runtime efficiencies, native support for
virtual threads and structured concurrency, support for pluggable custom
transport layers (mirroring the evolution of the HTTP spec and its
separation of semantics and transport details), all kinds of stuff. This
strategy is basically "last mover advantage:" since nothing is currently
forcing us to move off Java 8 or perform a major version bump, we can put
it off until really game-changing technologies are available.

On Sat, Mar 21, 2026 at 2:27 PM Oleg Kalnichevski <[email protected]> wrote:

> On Sat, 2026-03-21 at 12:29 -0700, Ryan Schmitt wrote:
> > > When do you think we could finally discontinue support for those
> > > versions?
> >
> > One question is what that buys us. We have a lot of API surface area,
> > so we
> > would struggle to adopt features like records without doing a major
> > version
> > bump. (For the same reason, we still mainly use our own pre-Java 8
> > async
> > abstractions rather than CompletableFuture.) There are some newer
> > language
> > features that we could use purely internally like switch expressions,
> > local
> > variable type inference, and text blocks, but that's a fairly minor
> > benefit
> > in the grand scheme of things.
> >
> > I think the Java 8 Maintenance Releases have been good to us; they've
> > backported TLSv1.3, ALPN, the socket keep-alive options, etc, and
> > we've
> > filled in other gaps like JEP380 using reflection or optional
> > dependencies.
> > Modern Java features like modules, Graal AOT compilation, and virtual
> > threads are also pretty easy to support while still targeting Java 8.
> > I
> > just upgraded our build toolchain to Java 17 without issue, and even
> > Java
> > 26 (released just days ago) still supports cross-compiling to Java 8.
> > This
> > support will eventually be dropped from a future version of Java, and
> > someday we will get to the point where no supported JDK version can
> > emit
> > Java 8 bytecode, but we are years away from a forced move like that.
> > For
> > example, Corretto 25 security support is scheduled to end on October
> > 31,
> > 2032: https://endoflife.date/amazon-corretto
> >
> > I think a big selling point of HttpComponents is that it's small and
> > highly
> > portable. It doesn't have a giant dependency graph, it doesn't pull
> > in the
> > Kotlin runtime, it doesn't need special permission to reflect into
> > JDK internals or load native libraries, it's compatible with old
> > Android
> > apps and build tools, it doesn't perform bytecode manipulation, etc.
> > The
> > project has a long track record of forward- and backward-
> > compatibility, so
> > it behooves us to be conservative about the runtime requirement. We
> > recently saw (HTTPCLIENT-2413) that someone running on IBM J9 was
> > broken
> > when we introduced the call to `ExtendedSocketOptions`, which was an
> > instructive example of just how much enterprise weirdness is out
> > there, and
> > the people we break will often not be in a position to "just" upgrade
> > their
> > runtime environments since they don't actually control them.
> >
> > Some other Java projects are going ahead with major version bumps to
> > drop
> > Java 8 support: Jackson, Log4j, Spring, and JUnit come to mind. I'd
> > like to
> > wait and see how it goes for them before we upgrade. There's ongoing
> > work
> > at Amazon to raise the minimum build-time JDK version from 8 to 11,
> > as well
> > as to deal with major version bumps more gracefully, but at the
> > moment I
> > have no way of pushing out an HC upgrade that requires Java 17. Note
> > the
> > implications of this: we would have to continue maintaining a Java
> > 8-compatible maintenance branch, and we would lose out on all the bug
> > reports that I surface from internal testing and production usage.
> > There's
> > also the matter of open source libraries like the AWS Java SDK v2,
> > which
> > recently published an HttpClient 5 integration. These libraries are
> > subject
> > to the constraints of _both_ ecosystems (internal and open source)
> > and will
> > probably be among the last to drop Java 8 support.
> >
>
> Ryan,
>
> I have no intention of antagonizing Amazon given it is one of the
> project's most visible consumers. At the same time, we are being
> perceived as a legacy project more and more. I personally hardly see
> any reason for choosing Apache HttpClient over Java HttpClient these
> days unless one is still stuck with Java 8. I am perfectly fine waiting
> a few years more years but there may be point when we all collectively
> have to decide if we are all better off having another hobby project.
>
> Oleg
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>

Reply via email to