Skip to content

[pip] PIP-472: Migrate from javax.* to jakarta.* APIs#25700

Open
lhotari wants to merge 2 commits intoapache:masterfrom
lhotari:lh-pip-472
Open

[pip] PIP-472: Migrate from javax.* to jakarta.* APIs#25700
lhotari wants to merge 2 commits intoapache:masterfrom
lhotari:lh-pip-472

Conversation

@lhotari
Copy link
Copy Markdown
Member

@lhotari lhotari commented May 6, 2026

Motivation

I'd like to propose PIP-472, which migrates Apache Pulsar's source code
and dependencies from the legacy javax.* namespace (Jakarta EE 8 and
earlier) to the modern jakarta.* namespace (Jakarta EE 9+).

In 2017 Oracle transferred Java EE to the Eclipse Foundation, and from
Jakarta EE 9 onward (released 2020) every Jakarta EE specification
moved its package prefix from javax.* to jakarta.*. The two
namespaces are source- and binary-incompatible. The upstream ecosystem
has fully moved on: Jersey 3.x, Jetty 11+, Swagger Core 2.x, Spring 6,
Hibernate Validator 7+, and MicroProfile 5+ all require jakarta.*.
Pulsar cannot pick up upstream bug fixes, performance improvements, or
security advisories without leaving the javax.* namespace.

Pulsar's codebase still imports javax.* from approximately 1,620
Java files (660 javax.ws.rs, 368 javax.servlet, 48
javax.annotation, plus JDK packages that stay in javax.*
permanently and are out of scope). A partial migration is visible in
git history and PR #23905 is in flight, but the Jakarta-named API
artifacts in gradle/libs.versions.toml are still pinned to Jakarta
EE 8 versions that emit the javax.* namespace, and Jetty 12 is
configured with its ee8-* (javax-servlet compat) modules. The result
is a half-migrated state that is harder to reason about and extend
than either endpoint.

PIP-472 consolidates the migration into a coordinated, four-phase
plan: a preparation phase (OpenRewrite tooling and Checkstyle import
checks), a Phase 1 that atomically migrates the broker REST tier
(Jersey 2.42 → 3.1.10, Swagger 1.6.2 → 2.2.27, jetty-ee10-* added
alongside the retained jetty-ee8-*, Jakarta EE 10 API versions),
a Phase 2 that mechanically sweeps non-REST javax.* imports module
by module, and a Phase 3 cleanup of shading rules, LICENSE/NOTICE
files, and a migration guide.

The plan keeps existing AdditionalServlet plugins working without
recompilation by retaining the Jetty 12 ee8 environment alongside
ee10 and extending the AdditionalServlet SPI so plugins can
register jakarta.servlet handlers (preferred, routed to ee10) in
addition to javax.servlet handlers (legacy, routed to ee8).
Connectors and Functions running in NAR-isolated classloaders are
unaffected. The wire protocol and REST API are unchanged. Plugin
authors that contribute JAX-RS resources to the broker REST tier and
embedding consumers of pulsar-client-admin need to update their
javax.* imports to jakarta.* and recompile.

The benefits include unblocking dependency upgrades (Jersey 3, Jetty
ee10, Swagger 2), eliminating Pulsar's direct dependency on
javax.servlet:javax.servlet-api:3.1.0, ending the half-migrated
classpath, and aligning Pulsar 5.0 LTS with the modern Jakarta EE
ecosystem before the LTS branch is cut.

The full proposal can be found at: #25700
Rendered PIP document:
https://github.com/lhotari/pulsar/blob/lh-pip-472/pip/pip-472.md

I welcome your feedback and discussion on this proposal. Please share
your thoughts, concerns, or suggestions.

Mailing list discussion: https://lists.apache.org/thread/1crbw2y2zg89qsyyq7qnv3ldh640lpsy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant