Skip to content

Migrate from Java 8 to Java 21 with Jakarta EE 10#2

Open
devin-ai-integration[bot] wants to merge 2 commits intomasterfrom
devin/1776184712-migrate-java8-to-java21
Open

Migrate from Java 8 to Java 21 with Jakarta EE 10#2
devin-ai-integration[bot] wants to merge 2 commits intomasterfrom
devin/1776184712-migrate-java8-to-java21

Conversation

@devin-ai-integration
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot commented Apr 14, 2026

Summary

Full migration of the project from Java 8 / Java EE (javax namespace) to Java 21 / Jakarta EE 10 (jakarta namespace). This touches every layer: Maven compiler settings, dependencies, Jetty plugin, XML descriptors, and Java source imports.

Key changes:

  • Parent POM: Compiler source/target → 21, added maven.compiler.release=21
  • Dependencies: javax.servlet-api:3.1.0jakarta.servlet-api:6.0.0, cdi-api:1.2jakarta.enterprise.cdi-api:4.0.1
  • Plugins: maven-war-plugin 2.5 → 3.4.0, jetty-maven-plugin 9.x → jetty-ee10-maven-plugin 12.0.14, weld-servlet 2.x → weld-servlet-shaded 5.1.2.Final
  • XML configs: web.xml/web-overwrite.xml updated to Jakarta EE 10 schema (version 6.0); jetty-env.xml and jetty-context.xml updated for Jetty 12 EE10 class names
  • Java sources: All javax.servlet.*, javax.inject.*, javax.enterprise.*, javax.annotation.* imports → jakarta.* equivalents. javax.naming.* (JDK) correctly left unchanged.
  • READMEs: Updated version references and documentation links

Build compiles cleanly with mvn clean install under JDK 21.

Updates since last revision

  • Fixed jetty-context.xml: Changed <Set name="hiddenClassMatcher"> to <Get name="hiddenClassMatcher"> so that exclude() is called on the existing ClassMatcher object rather than on the WebAppContext (which has no exclude() method). Caught by Devin Review.

Review & Testing Checklist for Human

  • Verify jetty-context.xml Jetty 12 classloader config — the old Jetty 9 serverClasses negative pattern was replaced with <Get name="hiddenClassMatcher"><Call name="exclude"> for DecoratingListener. The <Set><Get> bug was fixed, but the overall approach (class name, exclude pattern) still needs runtime validation to confirm Weld integrates correctly with Jetty 12's classloading.
  • Verify contextXml placement inside <webApp> in the Jetty EE10 Maven plugin config — it was moved from a top-level plugin config element to nested under <webApp>. Confirm this matches the Jetty 12 EE10 plugin API.
  • Verify ManagerObjectFactory class namejetty-env.xml references org.jboss.weld.resources.ManagerObjectFactory which was correct for Weld 2.x. Confirm this factory class still exists in Weld 5.1.2.Final.
  • Run mvn jetty:run in jetty-maven-cdi/ and hit http://localhost:8080/ — compilation passed but CDI/Weld/Jetty runtime wiring was NOT tested. Verify the page renders "Hello web-overwrite.xml!" (confirming JNDI + CDI injection both work).
  • Check console output for BeanManager injection succeeded and BeanManager JNDI lookup succeeded during Jetty startup — this confirms the JNDI binding in jetty-env.xml is wired correctly with the new Jakarta class references.

Notes

  • javax.naming.* imports in DefaultGreeting.java are intentionally unchanged — these are JDK classes, not Jakarta EE.
  • The old javax.el exclusion on cdi-api was removed since the Jakarta CDI API no longer bundles it.
  • beans.xml is empty and was left unchanged (still valid for CDI discovery).

Link to Devin session: https://app.devin.ai/sessions/f5b0f927228b4f749afaacbc48a1d173
Requested by: @jerryoliphant-cog


Open with Devin

- Update parent pom.xml: compiler source/target to 21, add maven.compiler.release=21
- Migrate javax.servlet:javax.servlet-api to jakarta.servlet:jakarta.servlet-api:6.0.0
- Migrate javax.enterprise:cdi-api to jakarta.enterprise:jakarta.enterprise.cdi-api:4.0.1
- Upgrade maven-war-plugin from 2.5 to 3.4.0
- Replace jetty-maven-plugin 9.x with jetty-ee10-maven-plugin 12.0.14
- Replace weld-servlet 2.x with weld-servlet-shaded 5.1.2.Final (CDI 4.0)
- Update web.xml and web-overwrite.xml to Jakarta EE 10 namespace (version 6.0)
- Update jetty-env.xml and jetty-context.xml for Jetty 12 EE10 classes
- Migrate all Java imports from javax.* to jakarta.* (servlet, inject, enterprise)
- Update README files with Java 21 and current dependency versions

Co-Authored-By: Jerry Oliphant <jerry.oliphant@cognition.ai>
@devin-ai-integration
Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Copy Markdown
Author

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Comment on lines 4 to 12
<Set name="hiddenClassMatcher">
<Call name="exclude">
<Arg>
<Array type="java.lang.String">
<Item>org.eclipse.jetty.ee10.servlet.DecoratingListener</Item>
</Array>
</Arg>
</Call>
</Set>
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 <Set> used instead of <Get> in jetty-context.xml causes exclude() to be called on wrong object

In Jetty XML configuration, <Set name="hiddenClassMatcher"> evaluates its child elements in the scope of the parent WebAppContext object, then calls setHiddenClassMatcher(result). The nested <Call name="exclude"> therefore tries to call exclude() on the WebAppContext (which has no such method) rather than on the ClassMatcher object. This will fail at runtime, preventing the CDI/Weld integration from being correctly configured.

The fix is to use <Get> instead of <Set>, which retrieves the existing ClassMatcher via getHiddenClassMatcher() and makes it the target for the nested <Call name="exclude">.

Suggested change
<Set name="hiddenClassMatcher">
<Call name="exclude">
<Arg>
<Array type="java.lang.String">
<Item>org.eclipse.jetty.ee10.servlet.DecoratingListener</Item>
</Array>
</Arg>
</Call>
</Set>
<Get name="hiddenClassMatcher">
<Call name="exclude">
<Arg>
<Array type="java.lang.String">
<Item>org.eclipse.jetty.ee10.servlet.DecoratingListener</Item>
</Array>
</Arg>
</Call>
</Get>
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — <Set> would call exclude() on the WebAppContext which doesn't have that method. Fixed in 343f882 by changing to <Get> so that the existing ClassMatcher is retrieved first and exclude() is called on it.

<Set> would call exclude() on the WebAppContext (which has no such method).
<Get> retrieves the existing ClassMatcher and calls exclude() on it correctly.

Co-Authored-By: Jerry Oliphant <jerry.oliphant@cognition.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants