Skip to content

HADOOP-19970. Move the servlet API to javax.servlet-api 4.0.1. - #8699

Draft
joseluisll wants to merge 7 commits into
apache:trunkfrom
joseluisll:jetty-phase-a
Draft

joseluisll wants to merge 7 commits into
apache:trunkfrom
joseluisll:jetty-phase-a

Conversation

@joseluisll

@joseluisll joseluisll commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Description of PR

Note

Stacked PR: please review only the last commit, HADOOP-19970.
This branch carries the Jetty 12 phase A changes it depends on, in merge order, so that CI tests them together. The first five commits are reviewed in their own PRs and have the same content there:

  1. HADOOP-20012: HADOOP-20012. YARN - Exclude third-party Jetty and servlet API from the catalog-webapp and timelineservice-hbase tests #8890
  2. HADOOP-20014: HADOOP-20014. Run the Jersey tests on the JDK HTTP server instead of Jetty #8892 (without it, TestJettyClasspath#testSingleJettyRelease fails on the jetty-continuation 9.4.55 that the Jersey Jetty test provider brings)
  3. HADOOP-20013: HADOOP-20013. Remove the duplicate javax.annotation-api from the classpath #8891
  4. HADOOP-20015: HADOOP-20015. Stop using Jetty 9.4 APIs that Jetty 12 removes #8893
  5. HADOOP-20016: HADOOP-20016. Declare the Jetty artifacts each module imports directly #8894

Once those are merged, this branch will be rebased onto trunk and only the HADOOP-19970 commit will remain.

This PR leaves one servlet API on every module classpath and moves it to javax.servlet:javax.servlet-api 4.0.1.

javax.servlet:javax.servlet-api 3.1.0 (through jetty-server) and jakarta.servlet:jakarta.servlet-api 4.0.4 both publish the javax.servlet packages, so which one a module compiles and runs against depends on jar order. This manages javax.servlet:javax.servlet-api 4.0.1 in hadoop-project and drops jakarta.servlet-api 4.0.4 from Hadoop. javax.servlet:javax.servlet-api is the coordinate most downstream projects already declare (Hive, HBase, Phoenix, Ranger, Livy, and Spark and Kyuubi manage 4.0.1), so Maven mediates Hadoop's 4.0.1 with theirs, while org.eclipse.jetty.toolchain:jetty-servlet-api is used by almost none of them (Ozone is the exception) and would leave two copies of the same classes. A project that pins jakarta.servlet-api at 5.x/6.x in dependencyManagement would instead silently replace Hadoop's 4.x and lose the javax.servlet classes, so that coordinate is left for the move to jakarta.servlet (HADOOP-19395). The jetty-schemas addition that Jetty 12 ee8 needs for its web.xml schemas is part of HADOOP-19972, not this PR.

  • hadoop-project: add javax.servlet-api.version (4.0.1), manage javax.servlet:javax.servlet-api in place of jakarta.servlet:jakarta.servlet-api 4.0.4, and comment on why, and on what downstream projects need to do. The managed version also replaces the javax.servlet-api 3.1.0 that Jetty 9.4 depends on, so no exclusion is needed for it.
  • hadoop-project and hadoop-sls: drop the exclusion on jetty-server of org.eclipse.jetty:javax.servlet-api, a coordinate that matches nothing.
  • hadoop-common: declare javax.servlet-api (compile). HttpServer2 and its filters compile against javax.servlet, which today arrives only transitively, through jetty-server; the modules that use javax.servlet without declaring an API get it through hadoop-common.
  • The 17 module poms that declared jakarta.servlet-api move to javax.servlet-api. hadoop-client-minicluster drops its 4 exclusions of jakarta.servlet-api, and hadoop-yarn-common its exclusion on the Jersey test provider: nothing brings it any more. hadoop-client already excludes javax.servlet-api from hadoop-common, now the API that module declares.
  • hadoop-project: jersey-test-framework-core declares jakarta.servlet-api 4.x at compile scope. Exclude it on the managed entry; managed exclusions also apply where core arrives transitively (the Jersey test provider) and where it is declared with exclusions of its own (hadoop-client-minicluster), so the exclusion repeated on the managed Jersey test provider goes.
  • LICENSE-binary: javax.servlet:javax.servlet-api 3.1.0 becomes 4.0.1 (CDDL 1.1 + GPLv2 with classpath exception, as before), and jakarta.servlet:jakarta.servlet-api:4.0.4 drops out.
  • Tests: AbstractJettyClasspathTest (hadoop-common test jar), with an empty TestJettyClasspath subclass in hadoop-common, the shuffle handler, yarn-common, the ApplicationHistoryServer, the NodeManager and the Router. testSingleServletApi checks that exactly one jar provides javax/servlet/Servlet.class, with Bundle-SymbolicName javax.servlet-api and Specification-Version 4.0 (javax.servlet-api 3.1.0 has the same symbolic name). testSingleJettyRelease checks that every jar with classes under org/eclipse/jetty/, whatever its group, has the same Implementation-Version (or else Bundle-Version); the servlet API and the orbit jars carry only javax.* classes and are not counted. ClasspathTestUtils recognises jars by their contents and manifests, not by repository path, so the checks hold in a Maven repository, a Gradle cache or a flattened lib directory. hadoop-client-minicluster keeps AbstractJettyClasspathTest and ClasspathTestUtils out of its shaded jar: they are not named Test*.class, and they check a module's own test classpath, not a minicluster user's.

No Jetty version change. javax.servlet-api 4.0.1 and jakarta.servlet-api 4.0.4 ship the same javax.servlet 4.0 classes, a superset of 3.1, and Jetty 9.4 runs on Servlet 4.0.

Downstream: direct users of hadoop-common move from javax.servlet-api 3.1.0 to 4.0.1 on the same coordinate, mediated by Maven. Non-shaded artifacts no longer bring jakarta.servlet:jakarta.servlet-api 4.0.4, so projects that declared or excluded it on Hadoop artifacts need javax.servlet:javax.servlet-api instead; the JIRA has a release note. hadoop-client-runtime still relocates one servlet API, now taken from javax.servlet-api.

How was this patch tested?

  • TestJettyClasspath is added in hadoop-common, the shuffle handler, yarn-common, the ApplicationHistoryServer, the NodeManager and the Router; testSingleServletApi and testSingleJettyRelease run there with the rest of each module's tests.
  • The fork's Build of this head is running; Yetus will follow on this PR.

For code changes:

  • Does the title of this PR start with the corresponding JIRA issue id (e.g. 'HADOOP-17799. Your PR title ...')?
  • Object storage: Have the integration tests been executed and the endpoint declared according to the connector-specific documentation? (not applicable)
  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0? (no new dependency: javax.servlet-api was already bundled at 3.1.0 and moves to 4.0.1, CDDL 1.1 + GPLv2 with classpath exception; the jakarta.servlet-api 4.0.4 entry is removed)
  • If applicable, have you updated the LICENSE, LICENSE-binary, NOTICE-binary files?

AI Tooling

Contains content generated by Claude.

If an AI tool was used:

@hadoop-yetus

Copy link
Copy Markdown

💔 -1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 1m 19s Docker mode activated.
_ Prechecks _
+1 💚 dupname 0m 0s No case conflicting files found.
+0 🆗 codespell 0m 0s codespell was not available.
+0 🆗 detsecrets 0m 0s detect-secrets was not available.
+0 🆗 xmllint 0m 0s xmllint was not available.
+0 🆗 shelldocs 0m 0s Shelldocs was not available.
+1 💚 @author 0m 0s The patch does not contain any @author tags.
-1 ❌ test4tests 0m 0s The patch doesn't appear to include any new or modified tests. Please justify why no new tests are needed for this patch. Also please list what manual steps were performed to verify this patch.
_ trunk Compile Tests _
+0 🆗 mvndep 2m 15s Maven dependency ordering for branch
+1 💚 mvninstall 42m 28s trunk passed
+1 💚 compile 16m 26s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 16m 36s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 mvnsite 18m 30s trunk passed
+1 💚 javadoc 9m 52s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 9m 45s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 shadedclient 46m 40s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+0 🆗 mvndep 0m 28s Maven dependency ordering for patch
+1 💚 mvninstall 39m 28s the patch passed
+1 💚 compile 16m 18s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 16m 18s the patch passed
+1 💚 compile 16m 42s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 16m 42s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
+1 💚 mvnsite 18m 12s the patch passed
+1 💚 shellcheck 0m 0s No new issues.
+1 💚 javadoc 9m 53s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 9m 37s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 shadedclient 48m 27s patch has no errors when building and testing our client artifacts.
_ Other Tests _
-1 ❌ unit 846m 40s /patch-unit-root.txt root in the patch failed.
-1 ❌ asflicense 1m 56s /results-asflicense.txt The patch generated 1 ASF License warnings.
1136m 48s
Reason Tests
Failed junit tests hadoop.hdfs.server.namenode.ha.TestStandbyCheckpoints
hadoop.yarn.service.TestYarnNativeServices
Subsystem Report/Notes
Docker ClientAPI=1.55 ServerAPI=1.55 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8699/1/artifact/out/Dockerfile
GITHUB PR #8699
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient codespell detsecrets xmllint shellcheck shelldocs
uname Linux 4f16061ebd3b 5.15.0-181-generic #191-Ubuntu SMP Fri May 22 19:09:02 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / ce75ddb
Default Java Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
Multi-JDK versions /usr/lib/jvm/java-21-openjdk-amd64:Ubuntu-21.0.11+10-1-24.04.2-Ubuntu /usr/lib/jvm/java-17-openjdk-amd64:Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
Test Results https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8699/1/testReport/
Max. process+thread count 4493 (vs. ulimit of 10000)
modules C: hadoop-project hadoop-common-project/hadoop-common hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-shuffle hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp . U: .
Console output https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8699/1/console
versions git=2.43.0 maven=3.9.15 shellcheck=0.9.0
Powered by Apache Yetus 0.14.1 https://yetus.apache.org

This message was automatically generated.

joseluisll added a commit to joseluisll/hadoop that referenced this pull request Aug 23, 2026
ShuffleChannelHandler is a Netty handler. It imported org.eclipse.jetty.http.
HttpHeader only to name the Connection and Keep-Alive headers, and the same
file already imports Netty's HttpHeaderNames.CONTENT_TYPE. Use HttpHeaderNames
and HttpHeaderValues throughout. That was the module's only Jetty reference in
main sources, so the module no longer uses Jetty at all outside tests.

Netty's constants are lowercase AsciiStrings, so the response now carries
"connection: keep-alive" where it carried "Connection: Keep-Alive". Field names
are case-insensitive per RFC 7230 section 3.2, connection options are
case-insensitive per section 6.1, and the response already carried Netty's
lowercase "content-length" from HttpUtil.setContentLength, so this makes the
response more internally consistent rather than less. No shuffle client reads
these headers by name; the fetcher uses HttpURLConnection, which is
case-insensitive.

Note for HADOOP-19970 (apache#8699): that PR adds a jetty-http dependency to this
module's pom for exactly this import. With the import gone the declaration is
no longer needed and should be dropped from that PR.

Contains content generated by Claude.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Aug 23, 2026
ShuffleChannelHandler is a Netty handler. It imported org.eclipse.jetty.http.
HttpHeader only to name the Connection and Keep-Alive headers, and the same
file already imports Netty's HttpHeaderNames.CONTENT_TYPE. Use HttpHeaderNames
and HttpHeaderValues throughout. That was the module's only Jetty reference in
main sources, so the module no longer uses Jetty at all outside tests.

Netty's constants are lowercase AsciiStrings, so the response now carries
"connection: keep-alive" where it carried "Connection: Keep-Alive". Field names
are case-insensitive per RFC 7230 section 3.2, connection options are
case-insensitive per section 6.1, and the response already carried Netty's
lowercase "content-length" from HttpUtil.setContentLength, so this makes the
response more internally consistent rather than less. No shuffle client reads
these headers by name; the fetcher uses HttpURLConnection, which is
case-insensitive.

Note for HADOOP-19970 (apache#8699): that PR adds a jetty-http dependency to this
module's pom for exactly this import. With the import gone the declaration is
no longer needed and should be dropped from that PR.

Contains content generated by Claude.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@slfan1989
slfan1989 self-requested a review August 24, 2026 01:27
@pan3793

pan3793 commented Aug 24, 2026

Copy link
Copy Markdown
Member

javax.servlet:javax.servlet-api and jakarta.servlet:jakarta.servlet-api both publish the javax.servlet

This is the beginning of chaos. And in practice, during the migration, it's likely that we need both javax.servlet and jakarta.servlet, in this case, the javax.servlet must be provided by javax.servlet:javax.servlet-api, right?

joseluisll added a commit to joseluisll/hadoop that referenced this pull request Aug 24, 2026
ShuffleChannelHandler is a Netty handler. It imported org.eclipse.jetty.http.
HttpHeader only to name the Connection and Keep-Alive headers. That was the
module's only Jetty reference in main sources, so with it gone the module does
not use Jetty at all, tests included.

The names are spelled out as constants rather than taken from Netty's
HttpHeaderNames and HttpHeaderValues, whose constants are lowercase
AsciiStrings: using those would have sent "connection: keep-alive" where this
handler has always sent "Connection: Keep-Alive". Field names and connection
options are both case-insensitive per RFC 7230, and Hadoop's own fetcher uses
HttpURLConnection, but the shuffle response is read by other projects too and
there is no reason to change a byte of it here.

Note for HADOOP-19970 (apache#8699): that PR adds a jetty-http dependency to this
module's pom for exactly this import. With the import gone the declaration is
no longer needed and should be dropped from that PR.

Contains content generated by Claude.

Co-Authored-By: Claude <noreply@anthropic.com>
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Aug 24, 2026
ShuffleChannelHandler is a Netty handler. It imported org.eclipse.jetty.http.
HttpHeader only to name the Connection and Keep-Alive headers. That was the
module's only Jetty reference in main sources, so with it gone the module does
not use Jetty at all, tests included.

The names are spelled out as constants rather than taken from Netty's
HttpHeaderNames and HttpHeaderValues, whose constants are lowercase
AsciiStrings: using those would have sent "connection: keep-alive" where this
handler has always sent "Connection: Keep-Alive". Field names and connection
options are both case-insensitive per RFC 7230, and Hadoop's own fetcher uses
HttpURLConnection, but the shuffle response is read by other projects too and
there is no reason to change a byte of it here.

Note for HADOOP-19970 (apache#8699): that PR adds a jetty-http dependency to this
module's pom for exactly this import. With the import gone the declaration is
no longer needed and should be dropped from that PR.

Contains content generated by Claude.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the TOOLS label Aug 24, 2026
@joseluisll joseluisll changed the title HADOOP-19970. Resolve a single Jetty release and servlet API on every module classpath Resolve one Jetty release and one servlet API on every module classpath Aug 24, 2026
@joseluisll joseluisll changed the title Resolve one Jetty release and one servlet API on every module classpath HADOOP-19970. Resolve one Jetty release and one servlet API on every module classpath Aug 24, 2026
@pjfanning

Copy link
Copy Markdown
Member

javax.servlet:javax.servlet-api and jakarta.servlet:jakarta.servlet-api both publish the javax.servlet

This is the beginning of chaos. And in practice, during the migration, it's likely that we need both javax.servlet and jakarta.servlet, in this case, the javax.servlet must be provided by javax.servlet:javax.servlet-api, right?

The jakarta.servlet groupId does not imply the jakarta.servlet package. Version 4.0.x was just the artifact rename under the Eclipse Foundation — the classes are still javax.servlet.http.HttpServlet. The actual package rename ("big bang") landed in 5.0.0. So if you see jakarta.servlet-api:4.0.4 on a classpath, your imports are still javax.*.

@joseluisll

joseluisll commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor Author

With the three substasks HADOOP-19970, HADOOP-19971 and HADOOP-19972, we have migrated to jetty12-ee8 as an intermediate step, not breaking downstream consumers. I'm still testing the pr's results, it would be convenient to create a specific subtask for compatibility testing before releasing the intermediate step. Any idea on how to approach the compatibility testing is welcome.

The breaking changes should be delivered in a future and additional release, giving time anf instructions for consumers to adapt to the namespace change, that is, using the jakarta instead of the javax classes.

This changes also introduce jdk-17 as a requirement, they are no longer jdk-8 compatible due to jetty12.

@pan3793

pan3793 commented Aug 25, 2026 •

Copy link
Copy Markdown
Member

The jakarta.servlet groupId does not imply the jakarta.servlet package. Version 4.0.x was just the artifact rename under the Eclipse Foundation — the classes are still javax.servlet.http.HttpServlet. The actual package rename ("big bang") landed in 5.0.0. So if you see jakarta.servlet-api:4.0.4 on a classpath, your imports are still javax.*.

@pjfanning that's true. so in the process of namespace migration, we might mix in javax.*. and jakarta.servlet at the same time, and we can not pull two versions of jakarta.servlet-api. that's why

in this case, the javax.servlet must be provided by javax.servlet:javax.servlet-api

but this might not be a real issue for hadoop project, since it stays near the root of the big data ecosystem dependency tree

@hadoop-yetus

Copy link
Copy Markdown

💔 -1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 56s Docker mode activated.
_ Prechecks _
+1 💚 dupname 0m 0s No case conflicting files found.
+0 🆗 codespell 0m 1s codespell was not available.
+0 🆗 detsecrets 0m 1s detect-secrets was not available.
+0 🆗 xmllint 0m 1s xmllint was not available.
+0 🆗 shelldocs 0m 1s Shelldocs was not available.
+1 💚 @author 0m 0s The patch does not contain any @author tags.
-1 ❌ test4tests 0m 0s The patch doesn't appear to include any new or modified tests. Please justify why no new tests are needed for this patch. Also please list what manual steps were performed to verify this patch.
_ trunk Compile Tests _
+0 🆗 mvndep 1m 48s Maven dependency ordering for branch
+1 💚 mvninstall 51m 42s trunk passed
+1 💚 compile 18m 10s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 18m 15s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 5m 55s trunk passed
+1 💚 mvnsite 20m 9s trunk passed
+1 💚 javadoc 10m 17s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 11m 32s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+0 🆗 spotbugs 0m 22s branch/hadoop-project no spotbugs output file (spotbugsXml.xml)
-1 ❌ spotbugs 41m 51s /branch-spotbugs-root-warnings.html root in trunk has 93 extant spotbugs warnings.
+0 🆗 spotbugs 0m 29s branch/hadoop-client-modules/hadoop-client-minicluster no spotbugs output file (spotbugsXml.xml)
+0 🆗 spotbugs 0m 31s branch/hadoop-client-modules/hadoop-client-runtime no spotbugs output file (spotbugsXml.xml)
-1 ❌ spotbugs 0m 44s /branch-spotbugs-hadoop-tools_hadoop-resourceestimator-warnings.html hadoop-tools/hadoop-resourceestimator in trunk has 12 extant spotbugs warnings.
-1 ❌ spotbugs 1m 43s /branch-spotbugs-hadoop-yarn-project_hadoop-yarn_hadoop-yarn-server_hadoop-yarn-server-nodemanager-warnings.html hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager in trunk has 1 extant spotbugs warnings.
+1 💚 shadedclient 34m 32s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+0 🆗 mvndep 0m 35s Maven dependency ordering for patch
+1 💚 mvninstall 70m 50s the patch passed
+1 💚 compile 17m 37s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 17m 37s the patch passed
+1 💚 compile 18m 21s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 18m 21s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
+1 💚 checkstyle 6m 12s the patch passed
+1 💚 mvnsite 19m 49s the patch passed
+1 💚 shellcheck 0m 0s No new issues.
+1 💚 javadoc 9m 46s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 9m 38s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+0 🆗 spotbugs 0m 22s hadoop-project has no data from spotbugs
+0 🆗 spotbugs 0m 26s hadoop-client-modules/hadoop-client-runtime has no data from spotbugs
+0 🆗 spotbugs 0m 26s hadoop-client-modules/hadoop-client-minicluster has no data from spotbugs
-1 ❌ shadedclient 69m 42s patch has errors when building and testing our client artifacts.
_ Other Tests _
-1 ❌ unit 838m 54s /patch-unit-root.txt root in the patch failed.
-1 ❌ asflicense 1m 50s /results-asflicense.txt The patch generated 1 ASF License warnings.
1339m 27s
Reason Tests
Failed junit tests hadoop.hdfs.server.namenode.ha.TestStandbyCheckpoints
hadoop.hdfs.server.balancer.TestBalancerWithHANameNodes
hadoop.yarn.service.TestYarnNativeServices
Subsystem Report/Notes
Docker ClientAPI=1.55 ServerAPI=1.55 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8699/6/artifact/out/Dockerfile
GITHUB PR #8699
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient codespell detsecrets xmllint spotbugs checkstyle shellcheck shelldocs
uname Linux 7a46e8a561f3 5.15.0-185-generic #195-Ubuntu SMP Fri Jun 19 17:11:50 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / 077558a
Default Java Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
Multi-JDK versions /usr/lib/jvm/java-21-openjdk-amd64:Ubuntu-21.0.11+10-1-24.04.2-Ubuntu /usr/lib/jvm/java-17-openjdk-amd64:Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
Test Results https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8699/6/testReport/
Max. process+thread count 4638 (vs. ulimit of 10000)
modules C: hadoop-project hadoop-common-project/hadoop-common hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client hadoop-mapreduce-project/hadoop-mapreduce-client hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-shuffle hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice-hbase-tests hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-globalpolicygenerator hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-catalog/hadoop-yarn-applications-catalog-webapp hadoop-mapreduce-project/hadoop-mapreduce-examples hadoop-tools/hadoop-resourceestimator hadoop-client-modules/hadoop-client-runtime hadoop-client-modules/hadoop-client-minicluster . U: .
Console output https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8699/6/console
versions git=2.43.0 maven=3.9.15 spotbugs=4.9.7 shellcheck=0.9.0
Powered by Apache Yetus 0.14.1 https://yetus.apache.org

This message was automatically generated.

@github-actions github-actions Bot added the HDFS label Aug 31, 2026
@joseluisll
joseluisll force-pushed the jetty-phase-a branch 2 times, most recently from 45defb4 to cfb6dbb Compare September 4, 2026 04:38
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Cloud-AWS manual trigger instructions: S3A tests must be manually triggered for fork pull requests. A maintainer should:

  • Confirm the PR does not contain risky changes to actions in .github/workflows and .github/actions.
  • Approve workflows for this fork PR if prompted.
  • Run Cloud-AWS workflow with pr_number=8699 (or via CLI: gh workflow run cloud_aws.yml -R apache/hadoop -f pr_number=8699)

fork head: joseluisll/hadoop@33792da8c812

joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 1, 2026
…he catalog-webapp and timelineservice-hbase tests.

catalog-webapp: on solr-core and solr-test-framework, exclude Solr's own
Jetty modules (jetty-alpn-server, jetty-alpn-java-server,
jetty-continuation, jetty-deploy, jetty-jmx, jetty-rewrite,
jetty-security, jetty-servlets, http2-server) and javax.servlet-api.
The tests reach Solr only through EmbeddedSolrServer, so only
${jetty.version} stays on the test classpath.

timelineservice-hbase-tests: on hbase-server and hbase-server:tests,
exclude javax.servlet:javax.servlet-api, as hbase-server-2 already does.

Also exclude jetty-alpn-java-client from solr-core and solr-test-framework.

Both Solr artifacts declare jetty-alpn-java-client 9.4.44. The managed
9.4.58 copy won only through Maven's declaration-order tie-break via
http2-http-client-transport. Exclude it, as solr-solrj already does.

Declare the Solr exclusions once, in catalog-webapp's dependencyManagement.

solr-core and solr-test-framework carried the same 22 exclusions, so a Solr
upgrade that adds a Jetty artifact had to be fixed in both places, and
missing one would bring back a second Jetty release (review on PR apache#8699).
They now live once, in a dependencyManagement section local to
hadoop-yarn-applications-catalog-webapp, with the Solr version; the two
test-scope dependencies only name the artifacts.

Local rather than in hadoop-project: only this module uses Solr, and it
keeps the change out of the root pom.

No change in what the module resolves: dependency:list (test scope) gives
the same 238 artifacts before and after, all Jetty at ${jetty.version} and
no javax.servlet-api 3.1.0.

Keep a single Solr exclusion list, on solr-test-framework.

The previous change moved both Solr artifacts into a local
dependencyManagement, but solr-core and solr-test-framework still each
carried the same 22 exclusions, so the list was not declared once.

The tests use solr-core only through EmbeddedSolrServer and NodeConfig,
and solr-test-framework already depends on solr-core. Drop the direct
solr-core declaration and the local dependencyManagement, and declare
solr-test-framework (test scope) once, with the only exclusion list.

The resolved test classpath of catalog-webapp is unchanged: the same
238 artifacts, solr-core 8.11.2 still at test scope, and no
javax.servlet-api 3.1.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 1, 2026
javax.servlet:javax.servlet-api 3.1.0 and jakarta.servlet:jakarta.servlet-api
4.0.4 both publish the javax.servlet packages, and which one a module
compiles and runs against depends on jar order. Leave one servlet API jar:
org.eclipse.jetty.toolchain:jetty-servlet-api, the one Jetty 12's ee8
environment depends on.

* hadoop-project: add jetty-servlet-api.version (4.0.9) and manage
  org.eclipse.jetty.toolchain:jetty-servlet-api in place of
  jakarta.servlet:jakarta.servlet-api 4.0.4.
* hadoop-common: declare jetty-servlet-api at compile scope. HttpServer2 and
  its filters compile against javax.servlet, which today arrives only as
  javax.servlet-api 3.1.0 through jetty-server; the modules that use
  javax.servlet without declaring an API get it through hadoop-common.
* hadoop-project and hadoop-sls: the exclusion on jetty-server named
  org.eclipse.jetty:javax.servlet-api, a coordinate that matches nothing.
  It now names javax.servlet:javax.servlet-api.
* hadoop-project: on javax-websocket-server-impl, also exclude
  javax.servlet:javax.servlet-api (through websocket-servlet).
* The 17 module poms that declare the servlet API, and the 5 exclusions of
  it (4 in hadoop-client-minicluster, 1 in hadoop-yarn-common), move to the
  new coordinate.
* hadoop-project: jersey-test-framework-core declares jakarta.servlet-api at
  compile scope; exclude it there and on the Jersey test provider.
* LICENSE-binary: replace jakarta.servlet:jakarta.servlet-api:4.0.4 with
  org.eclipse.jetty.toolchain:jetty-servlet-api:4.0.9 (Apache License 2.0 /
  EPL 2.0, like the other Jetty artifacts).
* LICENSE-binary and NOTICE-binary: drop javax.servlet:javax.servlet-api.

No Jetty version change. jetty-servlet-api and jakarta.servlet-api 4.0.4
ship the same javax.servlet 4.0 classes, a superset of 3.1, and Jetty 9.4
runs on Servlet 4.0.

Downstream: non-shaded artifacts now bring the servlet API as
org.eclipse.jetty.toolchain:jetty-servlet-api instead of
jakarta.servlet:jakarta.servlet-api, so exclusions of the old coordinate
need the new one; direct consumers of hadoop-common get jetty-servlet-api
4.0.9 instead of javax.servlet-api 3.1.0. hadoop-client-runtime still
relocates one servlet API, now taken from jetty-servlet-api.

Add classpath tests for one servlet API and one Jetty release.

hadoop-common, the shuffle handler, yarn-common, the ApplicationHistoryServer,
the NodeManager and the Router each get a TestJettyClasspath that checks
their test classpath: javax/servlet/Servlet.class comes from exactly one jar,
jetty-servlet-api, and every Jetty jar is from the same release.

Following the review on PR apache#8699:
* The tests live once, in AbstractJettyClasspathTest in hadoop-common's
  test jar, which every one of these modules already depends on. Each
  module's TestJettyClasspath is an empty subclass; JUnit 5 runs the
  inherited tests, so the modules cannot drift apart.
* ClasspathTestUtils recognises Jetty jars by the Maven repository layout,
  .../org/eclipse/jetty/[group/...]artifact/version/artifact-version.jar,
  in any Jetty group, so stale http2, fcgi or websocket jars beside
  ${jetty.version} fail the test. The groups whose artifacts are versioned
  on their own (toolchain, alpn, orbit) are left out.

With trunk's poms, testSingleServletApi fails in hadoop-common:
javax.servlet-api 3.1.0 provides javax/servlet/Servlet.class.

Exclude the jakarta.servlet-api of the Jersey test framework only once.

jersey-test-framework-core brings the servlet API as
jakarta.servlet:jakarta.servlet-api, and the managed jersey-test-framework-core
in hadoop-project already excludes it. Managed exclusions also apply where
core arrives transitively and where it is declared with exclusions of its
own, so the other declarations were redundant or dead (review on PR apache#8699):

- hadoop-project: drop the jakarta.servlet-api exclusion repeated on the
  managed jersey-test-framework-provider-jetty.
- hadoop-yarn-common and hadoop-client-minicluster: drop the exclusions
  of org.eclipse.jetty.toolchain:jetty-servlet-api from the Jersey test
  provider and from jersey-test-framework-core. The rename to
  jetty-servlet-api left them pointing at an artifact these Jersey jars
  never bring.

The comment on the managed exclusion now says it is the only one.

No change in what is resolved: dependency:list (test scope) is identical
for all 45 modules of the reactor that builds the Jersey test users and
the client modules. With the managed exclusion also removed,
jakarta.servlet-api comes back in 17 of them, so that one exclusion is
what keeps it out.

Recognise Jetty and servlet API jars by contents, not by repository path.

ClasspathTestUtils found Jetty jars and the servlet API by their Maven
repository path. Under a Gradle cache (.../files-2.1/<group>/<artifact>/
<version>/<hash>/...) or a flattened lib directory nothing matched, so
assertSingleJettyRelease failed with "no Jetty jars found" although Jetty
was there, and a stale Jetty jar in another layout next to repository
jars was not counted (review on PR apache#8699).

- assertSingleJettyRelease: a jar on the classpath is a Jetty jar when it
  has classes under org/eclipse/jetty/, whatever its group (http2,
  websocket, alpn, ...); its release is the Implementation-Version (or
  else Bundle-Version) of its manifest. jetty-servlet-api and the orbit
  jars carry only javax.* classes and are not counted, so no list of
  groups to skip is needed. The manifest vendor is not used: Jetty 8 and
  9.2 jars name the same vendor as jetty-servlet-api.
- assertSingleServletApi: the one provider of javax/servlet/Servlet.class
  must have Bundle-SymbolicName org.eclipse.jetty.servlet-api, instead of
  a file name fragment.

Checked outside Maven with jetty-util, jetty-server and http2-common
9.4.58 plus jetty-servlet-api 4.0.9 in a Maven layout, a Gradle cache
layout and a lib directory of renamed jars: the new checks pass in all
three, and fail when a jetty-http 9.2.29 or websocket-api 9.2.12 jar is
added in any of them, or when javax.servlet-api 3.1.0 is added or
replaces jetty-servlet-api. The old checks failed on the Gradle and
renamed layouts, and missed the stale jar in the Gradle layout.

In hadoop-common, TestJettyClasspath passes with this branch's poms; with
trunk's poms testSingleServletApi fails, naming javax.servlet-api as the
provider.

Say why jetty-servlet-api is the servlet API, and what downstream projects need to do.

Moving from jakarta.servlet-api / javax.servlet-api to
org.eclipse.jetty.toolchain:jetty-servlet-api changes the coordinate
downstream projects receive. One that also declares javax.servlet-api or
jakarta.servlet-api 4.x now gets two jars with the same javax.servlet
classes, because Maven cannot mediate between different coordinates
(review on PR apache#8699).

Comment on the managed entry in hadoop-project: jetty-servlet-api 4.0.9
is the artifact and version Jetty 12's ee8 environment manages (jetty-ee8
12.1.14, ee8.jetty.servlet.api.version), so the Jetty 12 move does not
change the coordinate again; downstream projects that declare another
servlet API should exclude one of them. The release note of HADOOP-19970
says the same.

No change in what is resolved.

Keep the classpath test support out of hadoop-client-minicluster.

hadoop-client-minicluster shades hadoop-common's test jar and keeps out the
test classes named Test*.class. AbstractJettyClasspathTest and
ClasspathTestUtils, the support classes of the TestJettyClasspath tests, do
not match that pattern, so they were shipped, unrelocated, to minicluster
users. They check a module's own test classpath and are not for them:
exclude both from hadoop-common in the minicluster's shade filters.

Built hadoop-client-minicluster from this pom against artifacts whose
hadoop-common test jar has both classes: neither is in the shaded jar; the
other 52 org.apache.hadoop.test classes are still there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 1, 2026
…spath.

Exclude javax.annotation:javax.annotation-api from javax-websocket-server-impl
(it arrives through jetty-annotations). jakarta.annotation-api 1.3.5, already
bundled through jersey-common, provides the same javax.annotation classes.

Update LICENSE-binary and NOTICE-binary to list
jakarta.annotation:jakarta.annotation-api:1.3.5 (EPL 2.0 + GPLv2 with
classpath exception) instead of javax.annotation:javax.annotation-api:1.3.2.

Add a test that the NodeManager's classpath has one javax.annotation API.

The NodeManager is the module that declares javax-websocket-server-impl,
whose jetty-annotations brought javax.annotation-api 1.3.2 beside
jakarta.annotation-api 1.3.5, two copies of the javax.annotation classes.
TestAnnotationApiClasspath checks that javax/annotation/PostConstruct.class
comes from exactly one jar, jakarta.annotation-api.

With trunk's poms it fails: both jars provide the class.

Self-contained, so it does not depend on HADOOP-19970's ClasspathTestUtils;
it was the NodeManager-only test in PR apache#8699's TestJettyClasspath.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@apache apache deleted a comment from hadoop-yetus Nov 4, 2026
@apache apache deleted a comment from hadoop-yetus Nov 4, 2026
@apache apache deleted a comment from hadoop-yetus Nov 4, 2026
@apache apache deleted a comment from hadoop-yetus Nov 4, 2026
@apache apache deleted a comment from hadoop-yetus Nov 4, 2026
@pan3793

pan3793 commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

every module resolves one servlet API (jetty-servlet-api 4.0.9) ...

I'm concerned about the selection of jetty-servlet-api, I think we should choose either

  • javax.servlet:javax.servlet-api, if we allow mixing javax.servlet.*, jakarta.servlet.* in our classpath, or
  • jakarta.servlet:jakarta.servlet-api:4.x, if we disallow mixing javax.servlet.*, jakarta.servlet.* in our classpath

the above two are adopted widely, while jetty-servlet-api is rarely used; if we choose jetty-servlet-api, downstream projects will likely need to exclude it manually and switch to their already pulled javax.servlet:javax.servlet-api or jakarta.servlet:jakarta.servlet-api

BTW, I think allowing vendors to provide their own implementations of JSR APIs is a poor decision; having identical classes present in JARs with different groupId:artifactId coordinates creates a serious risk of conflicts.

@joseluisll

Copy link
Copy Markdown
Contributor Author

@pan3793 thanks for your review. I agree that jetty-servlet-api is the wrong choice for downstream projects. Between your two options I'd go with javax.servlet:javax.servlet-api (4.0.1). The risk I see with the jakarta.servlet coordinate is that if a downstream project pulls servlet API 5.x or 6.x, Maven resolves a single jakarta.servlet-api version, Hadoop's javax.servlet classes disappear, and the failure only shows at runtime.

I checked the root POMs of the main downstream projects to see whether that risk is real:

Project (branch) Hadoop Jetty Servlet API in the root POM
Spark (master) 3.5.0 12.1.13 jakarta.servlet-api 6.0.0 and javax.servlet-api 4.0.1, both in dependencyManagement
Spark (branch-4.0) 3.4.1 11.0.24 jakarta.servlet-api 5.0.0 and javax.servlet-api 4.0.1, both managed
Spark (branch-3.5) 3.3.4 9.4.58 jakarta.servlet-api 4.0.3
Kyuubi (master) 3.4.3 9.4.57 jakarta.servlet-api 5.0.0 (6.0.0 in two profiles) and javax.servlet-api 4.0.1, both managed
Hive (master, branch-4.0) — 9.4.x javax.servlet-api 3.1.0
HBase (master) 3.4.3 — javax.servlet-api 4.0.1
HBase (branch-2.6) 3.4.3 — javax.servlet-api 3.1.0
Phoenix (master) 3.3.6 9.4.58 javax.servlet-api 3.1.0
Ranger (master) 3.4.2 9.4.56 javax.servlet-api 4.0.1
Livy (master) 3.3.4 9.4.58 javax.servlet-api 3.1.0
Tez (master) 3.5.0 — jakarta.servlet-api 4.0.4
Ozone (master) 3.4.3 12.1.14 jetty-servlet-api 4.0.9; excludes javax.servlet-api from the Hadoop artifacts
Oozie (master) 2.8.5 9.4.44 javax.servlet:servlet-api 2.5

Hudi, Drill, Flink and Zeppelin don't declare a servlet API in their root POM.

What this shows:

  1. javax.servlet:javax.servlet-api is what most of the ecosystem declares: Hive, HBase, Phoenix, Ranger and Livy, plus Spark and Kyuubi, which manage it next to jakarta.servlet-api. If Hadoop ships it, Maven mediates with all of them, and every one of them gets the javax.servlet classes Hadoop needs, whichever version wins.

  2. The projects already on the jakarta.servlet namespace pin jakarta.servlet-api 5.x or 6.x in dependencyManagement (Spark 4.0 and master, Kyuubi). A managed version overrides every transitive one. If Hadoop's only source of javax.servlet were jakarta.servlet-api 4.0.4, then in a module of those projects that uses the non-shaded Hadoop artifacts, Maven would silently replace it with 5.0.0 or 6.0.0, with no javax.servlet.* classes left. Today they're saved because Hadoop also brings javax.servlet-api (3.1.0 through jetty-server), and Spark and Kyuubi manage it to 4.0.1. That is the mixed-namespace classpath from your first option, and it already happens in practice. Your earlier point, that the javax classes must come from javax.servlet:javax.servlet-api, is exactly what keeps those builds working. The shaded clients aren't affected, but not everyone uses them.

  3. jakarta.servlet-api 4.x in the javax namespace is the minority: Spark 3.5 (4.0.3) and Tez (4.0.4, which follows Hadoop's current managed version). For them, a switch to javax.servlet-api gives two copies of the same classes until they exclude one, the same cost the release note already describes. That's one maintained branch that is moving off this coordinate, plus Tez, which tracks Hadoop.

  4. Ozone is the only project here that uses jetty-servlet-api. It already runs on Jetty 12 ee8 and excludes javax.servlet-api from the Hadoop artifacts, so it is the one place where the current PR fits as it is. With javax.servlet-api 4.0.1, Ozone keeps its existing exclusion and adds jetty-servlet-api to it, or drops its own.

So I'll switch the PR to javax.servlet:javax.servlet-api 4.0.1:

  • Manage javax.servlet-api 4.0.1 in hadoop-project. It replaces the 3.1.0 that jetty-server brings, and the YARN, HDFS and KMS modules that declare jakarta.servlet-api 4.0.4 today move to it, so each classpath has one servlet API jar.
  • Drop jakarta.servlet-api 4.x from Hadoop entirely. When HADOOP-19395 moves Hadoop to the jakarta.servlet namespace, Hadoop takes jakarta.servlet-api 6.x, so the coordinate changes exactly when the namespace does, and the two can coexist on a classpath during the migration.
  • In HADOOP-19972, exclude jetty-servlet-api from jetty-ee8-nested, the only Jetty 12 ee8 artifact that depends on it.
  • Keep TestJettyClasspath, checking for javax.servlet-api, and update the release note: direct users of hadoop-common move from 3.1.0 to 4.0.1 (same coordinate, mediated by Maven), and projects that excluded or declared jakarta.servlet-api 4.x need the javax coordinate instead.

@pan3793

pan3793 commented Nov 4, 2026

Copy link
Copy Markdown
Member

@joseluisll, thanks for the survey, the direction sounds good to me.

joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 4, 2026
…he catalog-webapp and timelineservice-hbase tests.

catalog-webapp: the tests reach Solr only through EmbeddedSolrServer,
which runs no servlet container, so Solr's own Jetty (9.4.44) and
servlet API do not belong on the test classpath.

solr-test-framework already depends on solr-core, where
EmbeddedSolrServer and NodeConfig live, so drop the direct solr-core
declaration and keep solr-test-framework as the only Solr test
dependency. It carries the single exclusion list: Solr's Jetty modules
(jetty-io, jetty-xml, jetty-http, jetty-client, jetty-alpn-client,
jetty-alpn-java-client, jetty-alpn-server, jetty-alpn-java-server,
jetty-continuation, jetty-deploy, jetty-jmx, jetty-rewrite,
jetty-security, jetty-servlets, http2-*), javax.servlet-api,
commons-collections and jcl-over-slf4j. A Solr upgrade that adds a
Jetty artifact needs one entry (review on PR apache#8699).

jetty-alpn-java-client is excluded too: Solr declares 9.4.44, and the
managed 9.4.58 copy won only through Maven's declaration-order
tie-break via http2-http-client-transport. solr-solrj already excludes
it.

timelineservice-hbase-tests: on hbase-server and hbase-server:tests,
exclude javax.servlet:javax.servlet-api, as hbase-server-2 already does.

dependency:list (test scope) of catalog-webapp resolves 238 artifacts,
solr-core 8.11.2 still at test scope, all Jetty at ${jetty.version} and
no javax.servlet-api 3.1.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c43c4e9)
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 4, 2026
…spath.

Exclude javax.annotation:javax.annotation-api from javax-websocket-server-impl
(it arrives through jetty-annotations). jakarta.annotation-api 1.3.5, already
bundled through jersey-common, provides the same javax.annotation classes.

Update LICENSE-binary and NOTICE-binary to list
jakarta.annotation:jakarta.annotation-api:1.3.5 (EPL 2.0 + GPLv2 with
classpath exception) instead of javax.annotation:javax.annotation-api:1.3.2.

Add a test that the NodeManager's classpath has one javax.annotation API.

The NodeManager is the module that declares javax-websocket-server-impl,
whose jetty-annotations brought javax.annotation-api 1.3.2 beside
jakarta.annotation-api 1.3.5, two copies of the javax.annotation classes.
TestAnnotationApiClasspath checks that javax/annotation/PostConstruct.class
comes from exactly one jar, jakarta.annotation-api.

With trunk's poms it fails: both jars provide the class.

Self-contained, so it does not depend on HADOOP-19970's ClasspathTestUtils;
it was the NodeManager-only test in PR apache#8699's TestJettyClasspath.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 63d9fd0)
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 4, 2026
…as of 2026-11-04.

The code of each PR rules. Records the 2026-11-04 rescope of HADOOP-20015
(Java only, apache#8893) and HADOOP-20016 (poms only, apache#8894), the servlet API
decision (javax.servlet-api 4.0.1, plus jetty-schemas 4.0.3 on ee8) and that
apache#8699 still carries jetty-servlet-api 4.0.9, the 6 port commits of apache#8704 and
its stale prerequisite commits, and HADOOP-19971 (apache#8703) as jakarta
preparation to land with HADOOP-19395 rather than a candidate to discard.
Corrects the PR table's head/Yetus columns and the open items.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@joseluisll joseluisll changed the title HADOOP-19970. Resolve one Jetty release and one servlet API on every module classpath HADOOP-19970. Move the servlet API to javax.servlet-api 4.0.1. Nov 4, 2026
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 4, 2026
…he catalog-webapp and timelineservice-hbase tests.

catalog-webapp: on solr-core and solr-test-framework, exclude Solr's own
Jetty modules (jetty-alpn-server, jetty-alpn-java-server,
jetty-continuation, jetty-deploy, jetty-jmx, jetty-rewrite,
jetty-security, jetty-servlets, http2-server) and javax.servlet-api.
The tests reach Solr only through EmbeddedSolrServer, so only
${jetty.version} stays on the test classpath.

timelineservice-hbase-tests: on hbase-server and hbase-server:tests,
exclude javax.servlet:javax.servlet-api, as hbase-server-2 already does.

Also exclude jetty-alpn-java-client from solr-core and solr-test-framework.

Both Solr artifacts declare jetty-alpn-java-client 9.4.44. The managed
9.4.58 copy won only through Maven's declaration-order tie-break via
http2-http-client-transport. Exclude it, as solr-solrj already does.

Declare the Solr exclusions once, in catalog-webapp's dependencyManagement.

solr-core and solr-test-framework carried the same 22 exclusions, so a Solr
upgrade that adds a Jetty artifact had to be fixed in both places, and
missing one would bring back a second Jetty release (review on PR apache#8699).
They now live once, in a dependencyManagement section local to
hadoop-yarn-applications-catalog-webapp, with the Solr version; the two
test-scope dependencies only name the artifacts.

Local rather than in hadoop-project: only this module uses Solr, and it
keeps the change out of the root pom.

No change in what the module resolves: dependency:list (test scope) gives
the same 238 artifacts before and after, all Jetty at ${jetty.version} and
no javax.servlet-api 3.1.0.

Keep a single Solr exclusion list, on solr-test-framework.

The previous change moved both Solr artifacts into a local
dependencyManagement, but solr-core and solr-test-framework still each
carried the same 22 exclusions, so the list was not declared once.

The tests use solr-core only through EmbeddedSolrServer and NodeConfig,
and solr-test-framework already depends on solr-core. Drop the direct
solr-core declaration and the local dependencyManagement, and declare
solr-test-framework (test scope) once, with the only exclusion list.

The resolved test classpath of catalog-webapp is unchanged: the same
238 artifacts, solr-core 8.11.2 still at test scope, and no
javax.servlet-api 3.1.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 4, 2026
…spath.

Exclude javax.annotation:javax.annotation-api from javax-websocket-server-impl
(it arrives through jetty-annotations). jakarta.annotation-api 1.3.5, already
bundled through jersey-common, provides the same javax.annotation classes.

Update LICENSE-binary and NOTICE-binary to list
jakarta.annotation:jakarta.annotation-api:1.3.5 (EPL 2.0 + GPLv2 with
classpath exception) instead of javax.annotation:javax.annotation-api:1.3.2.

Add a test that the NodeManager's classpath has one javax.annotation API.

The NodeManager is the module that declares javax-websocket-server-impl,
whose jetty-annotations brought javax.annotation-api 1.3.2 beside
jakarta.annotation-api 1.3.5, two copies of the javax.annotation classes.
TestAnnotationApiClasspath checks that javax/annotation/PostConstruct.class
comes from exactly one jar, jakarta.annotation-api.

With trunk's poms it fails: both jars provide the class.

Self-contained, so it does not depend on HADOOP-19970's ClasspathTestUtils;
it was the NodeManager-only test in PR apache#8699's TestJettyClasspath.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
joseluisll added a commit to joseluisll/hadoop that referenced this pull request Nov 4, 2026
javax.servlet:javax.servlet-api 3.1.0 and jakarta.servlet:jakarta.servlet-api
4.0.4 both publish the javax.servlet packages, and which one a module
compiles and runs against depends on jar order. Leave one servlet API jar:
org.eclipse.jetty.toolchain:jetty-servlet-api, the one Jetty 12's ee8
environment depends on.

* hadoop-project: add jetty-servlet-api.version (4.0.9) and manage
  org.eclipse.jetty.toolchain:jetty-servlet-api in place of
  jakarta.servlet:jakarta.servlet-api 4.0.4.
* hadoop-common: declare jetty-servlet-api at compile scope. HttpServer2 and
  its filters compile against javax.servlet, which today arrives only as
  javax.servlet-api 3.1.0 through jetty-server; the modules that use
  javax.servlet without declaring an API get it through hadoop-common.
* hadoop-project and hadoop-sls: the exclusion on jetty-server named
  org.eclipse.jetty:javax.servlet-api, a coordinate that matches nothing.
  It now names javax.servlet:javax.servlet-api.
* hadoop-project: on javax-websocket-server-impl, also exclude
  javax.servlet:javax.servlet-api (through websocket-servlet).
* The 17 module poms that declare the servlet API, and the 5 exclusions of
  it (4 in hadoop-client-minicluster, 1 in hadoop-yarn-common), move to the
  new coordinate.
* hadoop-project: jersey-test-framework-core declares jakarta.servlet-api at
  compile scope; exclude it there and on the Jersey test provider.
* LICENSE-binary: replace jakarta.servlet:jakarta.servlet-api:4.0.4 with
  org.eclipse.jetty.toolchain:jetty-servlet-api:4.0.9 (Apache License 2.0 /
  EPL 2.0, like the other Jetty artifacts).
* LICENSE-binary and NOTICE-binary: drop javax.servlet:javax.servlet-api.

No Jetty version change. jetty-servlet-api and jakarta.servlet-api 4.0.4
ship the same javax.servlet 4.0 classes, a superset of 3.1, and Jetty 9.4
runs on Servlet 4.0.

Downstream: non-shaded artifacts now bring the servlet API as
org.eclipse.jetty.toolchain:jetty-servlet-api instead of
jakarta.servlet:jakarta.servlet-api, so exclusions of the old coordinate
need the new one; direct consumers of hadoop-common get jetty-servlet-api
4.0.9 instead of javax.servlet-api 3.1.0. hadoop-client-runtime still
relocates one servlet API, now taken from jetty-servlet-api.

Add classpath tests for one servlet API and one Jetty release.

hadoop-common, the shuffle handler, yarn-common, the ApplicationHistoryServer,
the NodeManager and the Router each get a TestJettyClasspath that checks
their test classpath: javax/servlet/Servlet.class comes from exactly one jar,
jetty-servlet-api, and every Jetty jar is from the same release.

Following the review on PR apache#8699:
* The tests live once, in AbstractJettyClasspathTest in hadoop-common's
  test jar, which every one of these modules already depends on. Each
  module's TestJettyClasspath is an empty subclass; JUnit 5 runs the
  inherited tests, so the modules cannot drift apart.
* ClasspathTestUtils recognises Jetty jars by the Maven repository layout,
  .../org/eclipse/jetty/[group/...]artifact/version/artifact-version.jar,
  in any Jetty group, so stale http2, fcgi or websocket jars beside
  ${jetty.version} fail the test. The groups whose artifacts are versioned
  on their own (toolchain, alpn, orbit) are left out.

With trunk's poms, testSingleServletApi fails in hadoop-common:
javax.servlet-api 3.1.0 provides javax/servlet/Servlet.class.

Exclude the jakarta.servlet-api of the Jersey test framework only once.

jersey-test-framework-core brings the servlet API as
jakarta.servlet:jakarta.servlet-api, and the managed jersey-test-framework-core
in hadoop-project already excludes it. Managed exclusions also apply where
core arrives transitively and where it is declared with exclusions of its
own, so the other declarations were redundant or dead (review on PR apache#8699):

- hadoop-project: drop the jakarta.servlet-api exclusion repeated on the
  managed jersey-test-framework-provider-jetty.
- hadoop-yarn-common and hadoop-client-minicluster: drop the exclusions
  of org.eclipse.jetty.toolchain:jetty-servlet-api from the Jersey test
  provider and from jersey-test-framework-core. The rename to
  jetty-servlet-api left them pointing at an artifact these Jersey jars
  never bring.

The comment on the managed exclusion now says it is the only one.

No change in what is resolved: dependency:list (test scope) is identical
for all 45 modules of the reactor that builds the Jersey test users and
the client modules. With the managed exclusion also removed,
jakarta.servlet-api comes back in 17 of them, so that one exclusion is
what keeps it out.

Recognise Jetty and servlet API jars by contents, not by repository path.

ClasspathTestUtils found Jetty jars and the servlet API by their Maven
repository path. Under a Gradle cache (.../files-2.1/<group>/<artifact>/
<version>/<hash>/...) or a flattened lib directory nothing matched, so
assertSingleJettyRelease failed with "no Jetty jars found" although Jetty
was there, and a stale Jetty jar in another layout next to repository
jars was not counted (review on PR apache#8699).

- assertSingleJettyRelease: a jar on the classpath is a Jetty jar when it
  has classes under org/eclipse/jetty/, whatever its group (http2,
  websocket, alpn, ...); its release is the Implementation-Version (or
  else Bundle-Version) of its manifest. jetty-servlet-api and the orbit
  jars carry only javax.* classes and are not counted, so no list of
  groups to skip is needed. The manifest vendor is not used: Jetty 8 and
  9.2 jars name the same vendor as jetty-servlet-api.
- assertSingleServletApi: the one provider of javax/servlet/Servlet.class
  must have Bundle-SymbolicName org.eclipse.jetty.servlet-api, instead of
  a file name fragment.

Checked outside Maven with jetty-util, jetty-server and http2-common
9.4.58 plus jetty-servlet-api 4.0.9 in a Maven layout, a Gradle cache
layout and a lib directory of renamed jars: the new checks pass in all
three, and fail when a jetty-http 9.2.29 or websocket-api 9.2.12 jar is
added in any of them, or when javax.servlet-api 3.1.0 is added or
replaces jetty-servlet-api. The old checks failed on the Gradle and
renamed layouts, and missed the stale jar in the Gradle layout.

In hadoop-common, TestJettyClasspath passes with this branch's poms; with
trunk's poms testSingleServletApi fails, naming javax.servlet-api as the
provider.

Say why jetty-servlet-api is the servlet API, and what downstream projects need to do.

Moving from jakarta.servlet-api / javax.servlet-api to
org.eclipse.jetty.toolchain:jetty-servlet-api changes the coordinate
downstream projects receive. One that also declares javax.servlet-api or
jakarta.servlet-api 4.x now gets two jars with the same javax.servlet
classes, because Maven cannot mediate between different coordinates
(review on PR apache#8699).

Comment on the managed entry in hadoop-project: jetty-servlet-api 4.0.9
is the artifact and version Jetty 12's ee8 environment manages (jetty-ee8
12.1.14, ee8.jetty.servlet.api.version), so the Jetty 12 move does not
change the coordinate again; downstream projects that declare another
servlet API should exclude one of them. The release note of HADOOP-19970
says the same.

No change in what is resolved.

Keep the classpath test support out of hadoop-client-minicluster.

hadoop-client-minicluster shades hadoop-common's test jar and keeps out the
test classes named Test*.class. AbstractJettyClasspathTest and
ClasspathTestUtils, the support classes of the TestJettyClasspath tests, do
not match that pattern, so they were shipped, unrelocated, to minicluster
users. They check a module's own test classpath and are not for them:
exclude both from hadoop-common in the minicluster's shade filters.

Built hadoop-client-minicluster from this pom against artifacts whose
hadoop-common test jar has both classes: neither is in the shaded jar; the
other 52 org.apache.hadoop.test classes are still there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
joseluisll and others added 7 commits November 4, 2026 19:22
…he catalog-webapp and timelineservice-hbase tests.

catalog-webapp: the tests reach Solr only through EmbeddedSolrServer,
which runs no servlet container, so Solr's own Jetty (9.4.44) and
servlet API do not belong on the test classpath.

solr-test-framework already depends on solr-core, where
EmbeddedSolrServer and NodeConfig live, so drop the direct solr-core
declaration and keep solr-test-framework as the only Solr test
dependency. It carries the single exclusion list: Solr's Jetty modules
(jetty-io, jetty-xml, jetty-http, jetty-client, jetty-alpn-client,
jetty-alpn-java-client, jetty-alpn-server, jetty-alpn-java-server,
jetty-continuation, jetty-deploy, jetty-jmx, jetty-rewrite,
jetty-security, jetty-servlets, http2-*), javax.servlet-api,
commons-collections and jcl-over-slf4j. A Solr upgrade that adds a
Jetty artifact needs one entry (review on PR apache#8699).

jetty-alpn-java-client is excluded too: Solr declares 9.4.44, and the
managed 9.4.58 copy won only through Maven's declaration-order
tie-break via http2-http-client-transport. solr-solrj already excludes
it.

timelineservice-hbase-tests: on hbase-server and hbase-server:tests,
exclude javax.servlet:javax.servlet-api, as hbase-server-2 already does.

dependency:list (test scope) of catalog-webapp resolves 238 artifacts,
solr-core 8.11.2 still at test scope, all Jetty at ${jetty.version} and
no javax.servlet-api 3.1.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Jetty.

Switch JerseyTest from jersey-test-framework-provider-jetty to
jersey-test-framework-provider-jdk-http. Jersey 2 has no container for
Jetty 12, so this has to land before the Jetty 12 upgrade (HADOOP-19972).
Production HTTP is untouched; HttpServer2 stays on Jetty 9.4.

* hadoop-project: manage provider-jdk-http in place of provider-jetty,
  keeping the javax.servlet-api exclusion.
* Module poms: switch the artifactId.
* hadoop-client-minicluster: bundle the jdk-http provider; declare
  jetty-util directly as optional, since its only copy used to arrive
  through provider-jetty; do not relocate the JDK's com/sun/net/httpserver
  classes.
* LICENSE-binary: update the provider entry.

Address review: list jersey-container-jdk-http, fix stale comment.

* LICENSE-binary: add jersey-container-jdk-http, which the jdk-http
  provider brings in and hadoop-client-minicluster bundles.
* hadoop-client-minicluster: the "jetty-util is in client" comment is
  stale; hadoop-client-runtime does not shade it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…spath.

Exclude javax.annotation:javax.annotation-api from javax-websocket-server-impl
(it arrives through jetty-annotations). jakarta.annotation-api 1.3.5, already
bundled through jersey-common, provides the same javax.annotation classes.

Update LICENSE-binary and NOTICE-binary to list
jakarta.annotation:jakarta.annotation-api:1.3.5 (EPL 2.0 + GPLv2 with
classpath exception) instead of javax.annotation:javax.annotation-api:1.3.2.

Add a test that the NodeManager's classpath has one javax.annotation API.

The NodeManager is the module that declares javax-websocket-server-impl,
whose jetty-annotations brought javax.annotation-api 1.3.2 beside
jakarta.annotation-api 1.3.5, two copies of the javax.annotation classes.
TestAnnotationApiClasspath checks that javax/annotation/PostConstruct.class
comes from exactly one jar, jakarta.annotation-api.

With trunk's poms it fails: both jars provide the class.

Self-contained, so it does not depend on HADOOP-19970's ClasspathTestUtils;
it was the NodeManager-only test in PR apache#8699's TestJettyClasspath.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jetty 10 and later drop org.eclipse.jetty.util.log.Log, and Jetty 12
drops ConcurrentHashSet and MultiException. Stop using them and two
other Jetty types the code did not need:

- FSMainOperationsBaseTest, ViewFileSystemTestSetup, ViewFsTestSetup,
  TestAuthenticationSessionCookie, TestAMRMClient, TestYarnCLI,
  TestRollingLevelDBTimelineStore and MockNM log through SLF4J instead
  of Jetty's Log.
- TestDockerCommandExecutor has its own logger instead of borrowing
  GzipHttpOutputInterceptor's.
- FederationInterceptor uses ConcurrentHashMap.newKeySet() instead of
  Jetty's ConcurrentHashSet.
- TestLogAggregationService batches its assertion failures in a list
  and throws one AssertionError carrying all of them, instead of using
  Jetty's MultiException.
- HttpServer2#inferMimeType calls ServletContext#getMimeType directly
  instead of casting to a Jetty context type.

No change on Jetty 9.4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
These modules import Jetty classes but only received the artifacts
transitively. Declare them, so each module states the Jetty it uses
directly through the Jetty 12 ee8 upgrade and the later jakarta
migration, where hadoop-common may stop exporting some of them:

- hadoop-project: manage jetty-http and jetty-io at ${jetty.version}.
- hadoop-common, hadoop-mapreduce-client-shuffle, hadoop-hdfs-httpfs:
  declare jetty-http as optional. hadoop-sls: declare it provided, like
  its jetty-server.
- yarn-common, applicationhistoryservice, resourcemanager, router:
  declare jetty-webapp, and jetty-servlet in applicationhistoryservice.
- hadoop-hdfs: declare jetty-io as optional.
- hadoop-hdfs-httpfs: declare jetty-servlet, and jetty-util as
  optional.
- hadoop-mapreduce-client-jobclient: declare jetty-server and
  jetty-servlet, provided.
- nodemanager: declare jetty-servlet.
- router: declare jetty-server, jetty-servlet and jetty-util.
- web-proxy: declare jetty-servlet, provided, and jetty-util.

jetty-http is optional so that what downstream projects resolve does not
change. At compile scope, Maven's nearest-wins mediation changed it: a
downstream project with jetty-client 9.4.40 next to hadoop-common
resolved jetty-http 9.4.58 instead of 9.4.40. jetty-io in hadoop-hdfs
and jetty-util in hadoop-hdfs-httpfs reached those modules only through
jetty-server, and are optional for the same reason.

Every declaration uses the scope the module already resolved the
artifact at, so each module's dependency tree is unchanged: the same
Jetty artifacts, versions and scopes.

No version change on Jetty 9.4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
javax.servlet:javax.servlet-api 3.1.0 and jakarta.servlet:jakarta.servlet-api
4.0.4 both publish the javax.servlet packages, and which one a module
compiles and runs against depends on jar order. Leave one servlet API jar:
javax.servlet:javax.servlet-api 4.0.1.

That coordinate only ever carries the javax.servlet namespace, so Maven
mediates it safely against the javax.servlet-api that Jetty 9.4 and
downstream projects (Hive, HBase, Phoenix, Ranger, Livy; Spark and Kyuubi
manage 4.0.1) declare. jakarta.servlet-api moved to the jakarta.servlet
namespace in 5.0, and projects that pin it at 5.x/6.x in
dependencyManagement would silently replace a jakarta.servlet-api 4.x of
Hadoop's and drop its javax.servlet classes; that coordinate is left for
the move to jakarta.servlet (HADOOP-19395).

* hadoop-project: add javax.servlet-api.version (4.0.1) and manage
  javax.servlet:javax.servlet-api in place of
  jakarta.servlet:jakarta.servlet-api 4.0.4. The managed version also
  applies to the javax.servlet-api 3.1.0 that jetty-server and
  javax-websocket-server-impl bring, so no exclusion is needed for them.
* hadoop-project and hadoop-sls: drop the exclusion on jetty-server of
  org.eclipse.jetty:javax.servlet-api, a coordinate that matches nothing.
* hadoop-common: declare javax.servlet-api at compile scope. HttpServer2 and
  its filters compile against javax.servlet, which so far arrived only
  transitively, through jetty-server; the modules that use javax.servlet
  without declaring an API get it through hadoop-common.
* The 17 module poms that declared jakarta.servlet-api move to
  javax.servlet-api. hadoop-client-minicluster drops its 4 exclusions of
  jakarta.servlet-api, and hadoop-yarn-common its exclusion on the Jersey
  test provider: nothing brings it any more (see below). hadoop-client
  already excludes javax.servlet-api from hadoop-common, now the API that
  module declares.
* hadoop-project: jersey-test-framework-core declares jakarta.servlet-api
  4.x at compile scope; exclude it on the managed entry. Managed exclusions
  also apply where core arrives transitively (the Jersey test provider) and
  where it is declared with exclusions of its own (hadoop-client-minicluster),
  so the exclusion repeated on the managed Jersey test provider goes.
* LICENSE-binary: javax.servlet:javax.servlet-api 3.1.0 becomes 4.0.1 (CDDL
  1.1 + GPLv2 with classpath exception, as before); drop
  jakarta.servlet:jakarta.servlet-api:4.0.4.

Add classpath tests for one servlet API and one Jetty release:
AbstractJettyClasspathTest in hadoop-common's test jar, with an empty
TestJettyClasspath subclass in hadoop-common, the shuffle handler,
yarn-common, the ApplicationHistoryServer, the NodeManager and the Router,
so the modules cannot drift apart. ClasspathTestUtils recognises jars by
their contents and manifests, not by repository path, so the checks hold
in a Maven repository, a Gradle cache or a flattened lib directory:
* testSingleServletApi: exactly one jar provides javax/servlet/Servlet.class,
  with Bundle-SymbolicName javax.servlet-api and Specification-Version 4.0
  (javax.servlet-api 3.1.0 has the same symbolic name).
* testSingleJettyRelease: every jar with classes under org/eclipse/jetty/,
  whatever its group, has the same Implementation-Version (or else
  Bundle-Version). The servlet API and the orbit jars carry only javax.*
  classes and are not counted.
hadoop-client-minicluster keeps AbstractJettyClasspathTest and
ClasspathTestUtils out of its shaded jar: they are not named Test*.class,
and they check a module's own test classpath, not a minicluster user's.

No Jetty version change. javax.servlet-api 4.0.1 and jakarta.servlet-api
4.0.4 ship the same javax.servlet 4.0 classes, a superset of 3.1, and
Jetty 9.4 runs on Servlet 4.0.

Tests: mvn install -DskipTests; dependency:tree of hadoop-common,
hadoop-hdfs, hadoop-yarn-common, the NodeManager, the ResourceManager,
hadoop-kms and hadoop-client shows javax.servlet-api 4.0.1 as the only
servlet API, and dependency:list over the whole reactor shows no
jakarta.servlet-api, jetty-servlet-api or other javax.servlet-api version.
hadoop-client-check-invariants and hadoop-client-check-test-invariants
pass. testSingleServletApi passes in every module with a
TestJettyClasspath.

Downstream: direct users of hadoop-common move from javax.servlet-api 3.1.0
to 4.0.1 on the same coordinate. Non-shaded artifacts no longer bring
jakarta.servlet:jakarta.servlet-api 4.0.4; projects that declared or
excluded it on Hadoop artifacts need javax.servlet:javax.servlet-api.
hadoop-client-runtime still relocates one servlet API, now taken from
javax.servlet-api.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous Jenkins build (PR-8699/31) aborted during 'setup sources' with a
git pack permission error before precommit ran, so no results were produced.

Co-Authored-By: Claude Code <noreply@anthropic.com>

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants