Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策

AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策

Avatar for tnagao7

tnagao7

May 30, 2026

More Decks by tnagao7

Other Decks in Programming

Transcript

  1. 自己紹介 © 2026 Fujitsu Limited ⚫ 富士通株式会社 ソフトウェアエンジニア ⚫ アプリケーションサーバー製品の開発・保守

    ⚫ Jakarta EE/MicroProfile関連のOSS開発 ⚫ MicroProfileステコミ委員 ⚫ X (Twitter): @tnagao7 ⚫ JJUG CCC 2025 Fallなどで登壇 長尾 貴浩 2
  2. 目次 ⚫Java EE/Jakarta EEの移行とAIコーディングエージェント ⚫Jakarta EE移行へのAI適用ではまった落とし穴と解決策 ⚫Webサービス編 ⚫落とし穴①: スコープの仕様差異 ⚫落とし穴②:

    周辺技術との連携不足 ⚫EJB/CDI編 ⚫落とし穴③: トランザクションの仕様差異 ⚫落とし穴④: タイマー機能の仕様差異 © 2026 Fujitsu Limited 3
  3. Java EE/Jakarta EE技術の変遷 (1/5) © 2026 Fujitsu Limited 1999 2010

    2020 2025 CDI SOAP/ XML J2EE 1.4 J2EE 1.2 XML J2EE 1.3 Java EE 5 Java EE 6 Java EE 7 Java EE 8 Jakarta EE 8 Jakarta EE 9 Jakarta EE 10 Jakarta EE 11 MicroProfile REST/ JSON EJB アノテーション クラウド オンプレミス 4
  4. Java EE/Jakarta EE技術の変遷 (2/5) © 2026 Fujitsu Limited Java EE

    5 Platform (2006年) Jakarta EE 11 Platform (2025年) ⚫ Implementing Enterprise Web Services ⚫ Java API for XML-Based Web Services (JAX-WS) ⚫ Java API for XML-Based RPC (JAX-RPC) ⚫ Java Architecture for XML Binding (JAXB) ⚫ SOAP with Attachments API for Java (SAAJ) ⚫ Streaming API for XML ⚫ Web Service Metadata for the Java Platform ⚫ JavaServer Faces ⚫ JavaServer Pages ⚫ JavaServer Pages Standard Tag Library ⚫ Java Servlet ⚫ Common Annotations for the Java Platform ⚫ Enterprise JavaBeans ⚫ J2EE Connector Architecture ⚫ JavaBeans Activation Framework (JAF) ⚫ JavaMail ⚫ Java Message Service API ⚫ Java Persistence API ⚫ Java Transaction API (JTA) ⚫ J2EE Application Deployment ⚫ J2EE Management ⚫ Java Authorization Contract for Containers ⚫ Jakarta Activation ⚫ Jakarta Annotations ⚫ Jakarta Authentication ⚫ Jakarta Authorization ⚫ Jakarta Batch ⚫ Jakarta Concurrency ⚫ Jakarta Connectors ⚫ Jakarta Contexts and Dependency Injection ⚫ Jakarta Data ⚫ Jakarta Debugging Support for Other Languages ⚫ Jakarta Dependency Injection ⚫ Jakarta Enterprise Beans ⚫ Jakarta Expression Language ⚫ Jakarta Faces ⚫ Jakarta Interceptors ⚫ Jakarta JSON Processing ⚫ Jakarta JSON Binding ⚫ Jakarta Mail ⚫ Jakarta Messaging ⚫ Jakarta Pages ⚫ Jakarta Persistence ⚫ Jakarta RESTful Web Services ⚫ Jakarta Security ⚫ Jakarta Servlet ⚫ Jakarta Standard Tag Library ⚫ Jakarta Transactions ⚫ Jakarta Validation ⚫ Jakarta WebSocket https://www.oracle.com/java/technologies/javaee/javaeetechnologies.html https://jakarta.ee/specifications/platform/11/ 5
  5. Java EE 5 Platform Jakarta EE 11 Platform Java EE/Jakarta

    EE技術の変遷 (3/5) Jakarta Servlet Jakarta Enterprise Beans Jakarta Contexts and Dependency Injection (CDI) Jakarta JSON Binding Jakarta RESTful Web Services Jakarta XML Binding(*) Jakarta XML Web Services(*) (*)スタンドアロン仕様として一部実装で独自にサポート © 2026 Fujitsu Limited Enterprise JavaBeans (EJB) Java Servlet Java Architecture for XML Binding Java API for XML-Based Web Services 6
  6. Java EE 5 Platform Jakarta EE 11 Platform Java EE/Jakarta

    EE技術の変遷 (4/5) Jakarta Servlet Jakarta Enterprise Beans Jakarta Contexts and Dependency Injection (CDI) (*)スタンドアロン仕様として一部実装で独自にサポート © 2026 Fujitsu Limited Enterprise JavaBeans (EJB) Java Servlet SOAP/XMLから REST/JSONへ Jakarta JSON Binding Jakarta RESTful Web Services Jakarta XML Binding(*) Jakarta XML Web Services(*) Java Architecture for XML Binding Java API for XML-Based Web Services 7
  7. Java EE 5 Platform Jakarta EE 11 Platform Java EE/Jakarta

    EE技術の変遷 (5/5) Jakarta Servlet Jakarta JSON Binding Jakarta RESTful Web Services Jakarta XML Binding(*) Jakarta XML Web Services(*) (*)スタンドアロン仕様として一部実装で独自にサポート © 2026 Fujitsu Limited Java Servlet Java Architecture for XML Binding Java API for XML-Based Web Services EJBからCDIへ: 新しい機能はCDIに実装される Jakarta Enterprise Beans Jakarta Contexts and Dependency Injection (CDI) Enterprise JavaBeans (EJB) 8
  8. レガシーシステムの最新技術への移行の障壁 ⚫レガシーシステムの最新技術への移行には多くのメリットがある ⚫一方で移行を阻む様々な障壁が存在 © 2026 Fujitsu Limited Jakarta EE アプリケーション

    J2EE/Java EE アプリケーション ⚫ 生産性・アジリティ向上 ⚫ セキュリティ維持・向上 ⚫ 技術者確保 ⚫ 新旧仕様を知る技術者不足 ⚫ 品質面のリスク ⚫ 莫大な移行コスト など 9
  9. 移行ツールの例: Jakarta EEの名前空間変更 名前空間の変更を支援するツールの例 ⚫ Eclipse Transformer https://github.com/eclipse-transformer/transformer ⚫ Apache

    Tomcat Migration Tool https://github.com/apache/tomcat-jakartaee-migration © 2026 Fujitsu Limited import jakarta.servlet.*; import jakarta.servlet.annotation.*; import jakarta.servlet.http.*; @WebServlet("/hello") public class HelloServlet extends HttpServlet { ... } import javax.servlet.*; import javax.servlet.annotation.*; import javax.servlet.http.*; @WebServlet("/hello") public class HelloServlet extends HttpServlet { ... } Java EE 8 Jakarta EE 11 パッケージ名の変更 11
  10. 移行ツールの例: JUnitフレームワークの更新 JUnitフレームワークの更新を支援するツールの例 ⚫ junit-pioneer/convert-junit4-to-junit5 https://github.com/junit-pioneer/convert-junit4-to-junit5 ⚫ OpenRewriteのJUnit変換用レシピ https://docs.openrewrite.org/recipes/java/testing/junit ©

    2026 Fujitsu Limited import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; public class SampleTest { @Test public void test1() { Assertions.assertEquals( x, y, "message"); } } import org.junit.Assertions; import org.junit.Test; public class SampleTest { @Test public void test1() { Assertions.assertEquals( "message", x, y); } } JUnit 4 JUnit 5 引数順の変更 パッケージ名の変更 12
  11. 移行ツールの例: Webサービスの規約の移行 © 2026 Fujitsu Limited @WebService public class SampleService

    { @WebMethod public Data getData(String id) { // ... } // ... } Jakarta XML Web Services (SOAP/XML) Jakarta RESTful Web Services (REST/JSON) @Path("/sample") public class SampleResource { @GET @Produces(APPLICATION_JSON) public Data getData( @QueryParam("id") String id) { // ... } // ... } ? 13
  12. 移行ツールの基盤技術に基づく分類と特徴 ⚫ルールベースのツール ⚫仕組み: 事前定義したルールに基づいて動作 ⚫特徴: 特定技術への大量変換に強い / 非定型的な対応に弱い ⚫適用例: Eclipse

    Transformerを名前空間の変更に適用 ⚫機械学習ベースのツール ⚫仕組み: 学習データに基づいて動作 ⚫特徴: 文脈理解や柔軟な対応が可能 / 出力の不確実性の考慮が必要 ⚫適用例: LLMベースのAIコーディングエージェントをWebサービスの移行に適用 © 2026 Fujitsu Limited 14
  13. 目次 ⚫Java EE/Jakarta EEの移行とAIコーディングエージェント ⚫Jakarta EE移行へのAI適用ではまった落とし穴と解決策 ⚫Webサービス編 ⚫落とし穴①: スコープの仕様差異 ⚫落とし穴②:

    周辺技術との連携不足 ⚫EJB/CDI編 ⚫落とし穴③: トランザクションの仕様差異 ⚫落とし穴④: タイマー機能の仕様差異 © 2026 Fujitsu Limited 16
  14. Java EE 5 Platform Jakarta EE 11 Platform Java EE/Jakarta

    EE技術の変遷 【再掲】 Jakarta Servlet Jakarta Enterprise Beans Jakarta Contexts and Dependency Injection (CDI) (*)スタンドアロン仕様として一部実装で独自にサポート © 2026 Fujitsu Limited Enterprise JavaBeans (EJB) Java Servlet SOAP/XMLから REST/JSONへ Jakarta JSON Binding Jakarta RESTful Web Services Jakarta XML Binding(*) Jakarta XML Web Services(*) Java Architecture for XML Binding Java API for XML-Based Web Services 17
  15. SOAP/XMLからREST/JSONへの移行パス (代表例) SOAP/XML REST/JSON 型安全クライアント API仕様記述 Webサービス データバインディング Jakarta XML

    Web Services Jakarta RESTful Web Services MicroProfile Rest Client MicroProfile OpenAPI Jakarta XML Binding Jakarta JSON Binding © 2026 Fujitsu Limited 18
  16. Webサービスの移行実験概要 (1/3) ⚫ 実験内容: AIコーディングエージェントによってJakarta EEアプリケーションを変換 ⚫ 移行前の主な利用技術: Jakarta XML

    Web Services ⚫ 移行後の主な利用技術: Jakarta RESTful Web Service ⚫ 移行対象アプリケーション: Jakarta EEのサンプル集 “jakartaee-samples” (*1) に含まれる サンプルアプリケーション “ee7/jaxws” (実験用に一部改変(*2)) ⚫ AIコーディングエージェントのモデル: Claude Sonnet 4.6, Haiku 4.5, Codex GPT-5.4, ... (*1) https://github.com/javaee-samples/jakartaee-samples (*2) GlassFish 8に配備できるようにするための修正 (javax/jakarta変換など) と 本番運用を意識した修正 (エラー処理の追加、同期制御の追加など) © 2026 Fujitsu Limited 19
  17. Webサービスの移行実験概要 (2/3) 以下のアプリケーションを移行してください。 - 移行前: - 技術: Jakarta XML Web

    Services - 場所: original/jaxws/jaxws-endpoint - 移行後: - 技術: Jakarta RESTful Web Services - 場所: migrated/restful-ws/restful-ws-endpoint ⚫ コーディングエージェントへの入力: アプリケーションの移行を指示するプロンプトを使用 © 2026 Fujitsu Limited 移行前コードベース 移行後コードベース コーディングエージェント 20
  18. Webサービスの移行実験概要 (3/3) @WebService(...) public class EBookStoreImpl implements EBookStore { private

    Map<String, EBook> eBookCollection = new ConcurrentHashMap<>(); ... public EBook takeBook(String title) throws EBookStoreException { ... EBook found = eBookCollection.get(title); return found != null ? new EBook(found) : null; } public void saveBook(EBook eBook) throws EBookStoreException { ... eBookCollection.put(eBook.getTitle(), eBook); } } © 2026 Fujitsu Limited 移行前のWebサービス実装クラス リクエスト間で共有される データ構造 Webサービス実装メソッド (書籍情報の取得・保存処理) 21
  19. 落とし穴①: スコープの仕様差異 (1/5) @WebService(...) public class EBookStoreImpl ... { private

    Map<String, EBook> eBookCollection = new ConcurrentHashMap<>(); @Path("/ebookstore") public class EBookStoreResource { private static Map<String, EBook> eBookCollection = new ConcurrentHashMap<>(); @Path("/ebookstore") @ApplicationScoped public class EBookStoreResource { private Map<String, EBook> eBookCollection = new ConcurrentHashMap<>(); @Path("/ebookstore") public class EBookStoreResource { private Map<String, EBook> eBookCollection = new ConcurrentHashMap<>(); 移行後コード (試行2) ✘ 変数に格納したデータがリクエスト間で消失 移行後コード (試行1) 移行後コード (試行3) 移行前コード © 2026 Fujitsu Limited 22
  20. 落とし穴①: スコープの仕様差異 (2/5) By default a new resource class instance

    is created for each request to that resource. Jakarta RESTful Web Services 4.0規約 3.1.1. Lifecycle and Environment リクエスト1 リクエスト2 インスタンス1 インスタンス2 ? ? © 2026 Fujitsu Limited 原因: ⚫ 移行前後の技術の仕様差異をエージェントが認識していなかった/忘却していた ⚫Jakarta XML Web Services: サービス実装クラスのインスタンスが リクエストごとに生成されるかは実装依存 (規約で明記されていない) ⚫GlassFishでは、サービス実装クラスが非EJBの場合はシングルトンで動作 ⚫Jakarta RESTful Web Services: リソースクラスのインスタンスはデフォルトでリクエストごとに生成 (規約で明記) 「試行1」と「試行2」はリクエスト間でデータが消える問題を解決できているが 設計上の観点でどちらが適切かは検討の余地あり 補足 23
  21. 落とし穴①: スコープの仕様差異 (3/5) 移行前 コードベース 本体 https://github.com/javaee-samples/jakartaee-samples/blob/main/ ee7/jaxws/jaxws-endpoint/src/test/java/org/javaee7/jaxws/endpoint/EBookStoreTest.java テスト ©

    2026 Fujitsu Limited 原因 (続き): ⚫ コーディングエージェントはコードを変換するだけでテストを実行していなかった ⚫移行前資産に付随していたテストも変換して実行すれば検出できていた @Test public void test2SaveAndTakeBook() throws ... { EBookStore eBookStore = eBookStoreService.getPort(EBookStore.class); ... EBook response = eBookStore.takeBook("Oliver Twist"); assertEquals(eBook.getNumPages(), response.getNumPages()); } Webサービスのサンプルの実際のテスト (JUnit + Arquillian) Webサービスからの応答が 期待通りかを検証 Jakarta EE向け統合テストフレームワーク (アプリケーションサーバ上でテストを実行) 24
  22. 落とし穴①: スコープの仕様差異 (4/5) コーディング エージェント 移行後コードベース 移行後テスト結果 参照 移行後コード生成・ ビルド・テスト

    結果確認 本体 テスト 今回のケースに有効だった解決策: ⚫ テストで見つけられる問題をテストで見つけるためのプラクティスを適用した ⚫ 自律的なテスト実行と失敗時の調査・修正をエージェントへの指示に追加 移行前コードベース 本体 テスト レポート © 2026 Fujitsu Limited コーディングエージェントへの指示 (プロンプト、AGENTS.md、Skillsなど) mvn clean testでテストを実行して 正常に移行されたことを検証する。 失敗する場合は原因を調査し修正する。 25
  23. 落とし穴①: スコープの仕様差異 (5/5) 2つのテストが失敗しています。テストコードを確認して原因を調べます。 Read EBookStoreTest.java 原因が分かりました。EBookStoreResource の eBookCollection はインスタンスフィール

    ドですが、JAX-RSはデフォルトでリクエストごとに新しいインスタンスを生成します。そのため、 POSTで保存したデータがGETリクエスト時には消えてしまいます。 @ApplicationScoped を追加してCDIシングルトンにします。 Edit EBookStoreResource.java [ERROR] Tests run: 3, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.496 s <<< FAILURE! - in org.javaee7.jaxrs.endpoint.EBookStoreTest コーディングエージェントにテスト実行・バグ修正を任せたときの実際の出力 © 2026 Fujitsu Limited コーディングエージェントが プログラムを修正 26
  24. 落とし穴②: 周辺技術との連携不足 (1/3) EBook response1 = target.path(PATH) .resolveTemplate("title", "Title1") .request(MediaType.APPLICATION_JSON)

    .get(EBook.class); EBook response2 = target.path(PATH) .resolveTemplate("title", "Title2") .request(MediaType.APPLICATION_JSON) .get(EBook.class); EBook response1 = store.takeBook("Title1"); EBook response2 = store.takeBook("Title2"); 移行後コード 移行前コード クライアント側の移行後コードがMicroProfile Rest Clientでなく Jakarta RESTのクライアントで実装されたためボイラープレートコードが多発 © 2026 Fujitsu Limited 27
  25. 落とし穴②: 周辺技術との連携不足 (2/3) 移行後技術: Jakarta RESTful Web Services © 2026

    Fujitsu Limited 原因: ⚫ 移行後に利用してよい技術スタックを限定していた ⚫ 現状の移行後コードも誤りではないためテストでは検出できなかった 今回のケースに有効だった解決策: ⚫ コーディングエージェントに計画を立案させて作業を進めるプラクティスを適用した ⚫計画をレビューし設計指針や技術スタックについて意図と異なる部分を修正した アプリケーションを移行する 計画を立案して migration-plan.mdに まとめてください。... 移行後技術: Jakarta RESTful Web Services + MicroProfile Rest Client migration-plan.md コーディングエージェントへの入力 (プロンプト、AGENTS.md、Skills など) 計画を修正 計画・タスクのファイル管理は大規模開発のコンテキスト管理にも有効 28
  26. 落とし穴②: 周辺技術との連携不足 (3/3) EBook response1 = target.path(PATH) .resolveTemplate("title", "Title1") .request(MediaType.APPLICATION_JSON)

    .get(EBook.class); EBook response2 = target.path(PATH) .resolveTemplate("title", "Title2") .request(MediaType.APPLICATION_JSON) .get(EBook.class); 移行後コード (Jakarta RESTful Web Servicesの クライアントAPIを利用) EBook response1 = client.takeBook("Title1"); EBook response2 = client.takeBook("Title2"); 移行後コード (MicroProfile Rest Client APIを利用) ボイラープレートコードの 多発を解決 © 2026 Fujitsu Limited 29
  27. 目次 ⚫Java EE/Jakarta EEの移行とAIコーディングエージェント ⚫Jakarta EE移行へのAI適用ではまった落とし穴と解決策 ⚫Webサービス編 ⚫落とし穴①: スコープの仕様差異 ⚫落とし穴②:

    周辺技術との連携不足 ⚫EJB/CDI編 ⚫落とし穴③: トランザクションの仕様差異 ⚫落とし穴④: タイマー機能の仕様差異 © 2026 Fujitsu Limited 30
  28. Java EE 5 Platform Jakarta EE 11 Platform Java EE/Jakarta

    EE技術の変遷 【再掲】 Jakarta Servlet Jakarta JSON Binding Jakarta RESTful Web Services Jakarta XML Binding(*) Jakarta XML Web Services(*) (*)スタンドアロン仕様として一部実装で独自にサポート © 2026 Fujitsu Limited Java Servlet Java Architecture for XML Binding Java API for XML-Based Web Services EJBからCDIへ: 新しい機能はCDIに実装される Jakarta Enterprise Beans Jakarta Contexts and Dependency Injection (CDI) Enterprise JavaBeans (EJB) 31
  29. EJBからCDIへの移行パス (代表例) EJB CDI 非同期処理 サービス間通信 ビジネスロジック Jakarta Enterprise Beans

    Jakarta Contexts and Dependency Injection Jakarta Concurrency Jakarta RESTful Web Services © 2026 Fujitsu Limited 32
  30. EJB/CDIの移行実験概要 (1/2) ⚫ 実験内容: AIコーディングエージェントによってJakarta EEアプリケーションを変換 ⚫ 移行前の主な利用技術: Jakarta Enterprise

    Beans ⚫ 移行後の主な利用技術: Jakarta Contexts and Dependency Injection ⚫ 移行対象アプリケーション: Jakarta EEのサンプル集 “jakartaee-samples” (*1) に含まれる サンプルアプリケーション “ee7/ejb” (実験用に一部改変(*2)) ⚫ AIコーディングエージェントのモデル: Claude Sonnet 4.6, Haiku 4.5, Codex GPT-5.4, ... (*1) https://github.com/javaee-samples/jakartaee-samples (*2) GlassFish 8に配備できるようにするための修正 (javax/jakarta変換など) と 本番運用を意識した修正 (エラー処理の追加、同期制御の追加、データベース処理追加など) © 2026 Fujitsu Limited 33
  31. EJB/CDIの移行実験概要 (2/2) 移行前コードベース 移行後コードベース © 2026 Fujitsu Limited コーディングエージェント 以下のアプリケーションを移行してください。

    - 移行前: - 技術: Jakarta Enterprise Beans - 場所: original/ejb/stateless - 移行後: - 技術: Jakarta Contexts and Dependency Injection - 場所: migrated/cdi/stateless ⚫ コーディングエージェントへの入力: アプリケーションの移行を指示するプロンプトを使用 34
  32. @ApplicationScoped public class AccountSessionBean { public String withdraw(float amount) {

    // ... return "Withdrawn: " + amount; } @ApplicationScoped @Transactional public class AccountSessionBean { public String withdraw(float amount) { // ... return "Withdrawn: " + amount; } 移行後コード (試行2) 移行後コード (試行1) 移行前コード 落とし穴③: トランザクションの仕様差異 (1/4) © 2026 Fujitsu Limited トランザクション管理がなくなった @Stateless public class AccountSessionBean { public String withdraw( float amount) { // ... return "Withdrawn: " + amount; } 35
  33. 落とし穴③: トランザクションの仕様差異 (2/4) コンテナ提供機能 EJB CDI コンテナ管理トランザクション デフォルトで有効 デフォルトで無効 インスタンスのプーリング

    あり(*) なし コンテナによる同期制御 あり なし © 2026 Fujitsu Limited 原因: ⚫ 移行前後の技術の仕様差異をエージェントが認識していなかった/忘却していた ⚫ EJB/CDIコンテナの機能であるトランザクションのテストコードを書いていなかった ⚫ EJBとCDIのコンテナ提供機能にはさまざまな仕様差異がある ⚫ EJBと異なりCDIではトランザクションの明示的な有効化が必要 (*) ステートレスセッションBeanの典型的な実装の場合 36
  34. 落とし穴③: トランザクションの仕様差異 (3/4) # 移行時のレビュー観点 EJBコンテナが提供していた次のようなコンテナ機能の仕様が 移行後のアプリケーションでも同等の仕様で維持されているかを確認すること。 - トランザクション管理 -

    インスタンス管理 (スコープ、同期制御) - 非同期処理 - セキュリティ機能 © 2026 Fujitsu Limited 今回のケースに有効だった解決策: ⚫ テストで見逃しやすいポイント (コンテナ管理の機能、非機能仕様など) を レビュー観点として明文化してコーディングエージェントへのインプットに追加した 移行後コードのテストによる動作検証と相互補完的に機能 37
  35. 落とし穴③: トランザクションの仕様差異 (4/4) - @Transactionalアノテーション が正しく付与されているか。 ## 移行作業のルール - 移行作業は移行ガイド

    migration- guide.mdに沿って進めること。 - 移行作業で検出した問題は、 再発防止のために移行ガイド migration-guide.mdに反映すること。 migration-guide.md コーディングエージェントへの入力 (プロンプト、AGENTS.md、Skills など) リンク コーディングエージェント 参照/更新 参照 © 2026 Fujitsu Limited ⚫ 前ページのレビュー観点をより具体的にするために: 検出した問題の具体的情報をドキュメントに記録することで再発を防止する 38
  36. 落とし穴④: タイマー機能の仕様差異 (1/2) @Startup @Singleton public class SchedulesTimerBean { @Schedules({

    @Schedule(hour = "*", minute = "*", second = "*/5", info = ...), ... }) public void automaticallyScheduled( Timer timer) { ... } @ApplicationScoped public class SchedulesTimerBean { @Asynchronous(runAt = { @Schedule(cron = "*/5 * * * * *"), ... }) public void fire() { ... } 移行後コード (試行2) 移行後コード (試行1) 移行前コード @ApplicationScoped public class SchedulesTimerBean { @Resource(...) ManagedScheduledExecutorService scheduler; void init(@Observes...) { scheduler.scheduleAtFixedRate(..., 0, 5, SECONDS); ✘ アプリケーション起動後もイベントが発火せず © 2026 Fujitsu Limited 5秒間隔の実行を スケジュール 39
  37. 落とし穴④: タイマー機能の仕様差異 (2/2) © 2026 Fujitsu Limited 原因: ⚫ エージェントはコードを変換するだけでテストを実行していなかった

    ⚫ 移行前後の技術の仕様をエージェントが認識していなかった ⚫CDIの@Scheduleはそのままだと開始されない (規約の改善が議論されている) [Use Case]: Automatic start of Scheduled methods and more concise usage of @Schedule https://github.com/jakartaee/concurrency/issues/624 ⚫この問題を回避するにはCDIのイベントのオブザーブが必要 今回のケースに有効だった解決策: ⚫ テストの実行と失敗時の調査をコーディングエージェントへの指示に追加 ⚫ @Observesの注意事項をコーディングエージェントの入力に追加 (再発防止) @Asynchronous(runAt = { @Schedule(cron = "*/5 * * * * *"), ... }) public void fire(@Observes Startup event) { ... } 40
  38. まとめ J2EE/Java EE/Jakarta EE技術のトレンドは 四半世紀の歴史のなかで大きく変遷 ⚫SOAP/XMLからREST/JSONへ, EJBからCDIへ, ... 技術の移行にAIコーディングエージェントを利用する場合は 出力の非決定性に向き合いさまざまなアプローチから対策が必要

    ⚫設計指針や技術スタックをエージェントに入力 (Rest Clientなど周辺技術を活用) ⚫テストによる検証と修正をエージェントに任せる (Arquillianなどテストツールも活用) ⚫テストで見逃しやすい点 (コンテナ管理の機能など) をレビュー観点として明記 © 2026 Fujitsu Limited 世の中にある情報がAIの出力精度向上に直結します ぜひ皆さんのJava、Jakarta EEのノウハウを共有してください! 41