[{"data":1,"prerenderedAt":3134},["ShallowReactive",2],{"/ja-jp/blog/modernize-java-with-cursor-and-gitlab":3,"navigation-ja-jp":2361,"banner-ja-jp":2786,"footer-ja-jp":2794,"blog-post-authors-ja-jp-Michael Friedrich":3036,"blog-related-posts-ja-jp-modernize-java-with-cursor-and-gitlab":3051,"blog-promotions-ja-jp":3073,"next-steps-ja-jp":3125},{"id":4,"title":5,"authors":6,"body":8,"category":2341,"date":2342,"description":2343,"extension":2344,"externalUrl":2345,"faq":2345,"featured":137,"heroImage":2346,"meta":2347,"navigation":137,"path":2348,"seo":2349,"slug":2352,"stem":2353,"tags":2354,"template":2358,"updatedDate":2359,"__hash__":2360},"blogPosts/ja-jp/blog/modernize-java-with-cursor-and-gitlab.md","Cursor×GitLabで、安全に速くJavaをモダナイズする",[7],"Michael Friedrich",{"type":9,"value":10,"toc":2318},"minimark",[11,15,18,34,37,59,62,83,226,230,283,288,291,305,346,353,360,364,375,378,384,388,391,402,409,415,418,427,430,433,439,447,453,456,462,465,468,481,485,488,497,501,510,518,557,623,634,640,643,646,650,657,663,666,669,685,692,698,701,707,710,719,722,728,735,741,744,747,753,756,773,776,782,801,811,815,818,824,831,837,840,846,861,865,868,874,877,883,887,890,893,913,928,934,940,943,948,957,967,1340,1344,1362,1559,1562,1565,1574,1583,1592,2261,2264,2273,2276,2279,2314],[12,13,14],"p",{},"「Java 8をJava 21にモダナイズする」と言うと、単一のタスクのように聞こえます。しかし実際はそうではありません。ビルド、ランタイム、依存関係、API、並行処理、テスト、コンテナ、本番環境での挙動など、複数の要素が同時に絡み合う作業です。これらすべてを1つのプロンプトでエージェントに任せてしまうと、誰も安全にレビューできないほど巨大なマージリクエストができあがってしまいます。",[12,16,17],{},"AIコーディングエージェントであるCursorは、こうした問題のうち焦点を絞った部分を得意としています。失敗しているテストや範囲が限定されたイシューを1つ渡せば、実装を調査し、何が問題だったのかを説明し、修正案を提示し、開発フローから離れることなくテストを実行できます。しかし、複数ステップにわたる移行全体で「安全」が何を意味するかは、Cursorが単独で判断できるものではありません。",[12,19,20,21,27,28,33],{},"ここで登場するのがGitLabです。",[22,23,26],"a",{"href":24,"rel":25},"https://about.gitlab.com/ja-jp/gitlab-duo-agent-platform/",[],"Duo Agent Platform","がソフトウェアライフサイクルの残りの部分でAIワークフローをオーケストレーションし、コーディングエージェントの作業を検証できるよう設計されています。エピックによるイシューの階層構造により、計画は永続的でレビュー可能なものになります。GitLab Model Context Protocol（",[22,29,32],{"href":30,"rel":31},"https://about.gitlab.com/topics/ai/model-context-protocol/",[],"MCP","）サーバーは、こうしたソフトウェア開発ライフサイクルのコンテキストをCursorに取り込みます。CI/CD、セキュリティスキャン、コードレビュー、影響分析、そしてサービス横断的なテストが、本番環境での挙動を変更する前に必要となるエビデンスを提供します。",[12,35,36],{},"このチュートリアルでは、CursorとGitLabを使った3つのユースケースを解説します。",[38,39,40,47,53],"ol",{},[41,42,43],"li",{},[22,44,46],{"href":45},"#fix-a-failing-end-to-end-test-with-cursor","Cursorで失敗しているJavaのエンドツーエンドテストを修正する",[41,48,49],{},[22,50,52],{"href":51},"#prepare-quality-gates-for-java-21-modernization","Java 8から21へのモダナイズに向けて品質ゲートを準備する",[41,54,55],{},[22,56,58],{"href":57},"#modernize-http-connection-handling-with-java-21","Java 21でHTTP接続処理をモダナイズする",[12,60,61],{},"この進め方には意味があります。まず小さく始め、プロジェクトのコンテキストを加え、そのうえで1つの境界をモダナイズする。Cursorはその境界の中で高速に動きます。そのスピードを安全に保っているのが、Code Review Flow、Developer Flow、CI/CD、コードオーナーの承認、そして影響分析です。これらは省略可能なチェックポイントではなく、エージェントが作成したすべてのマージリクエストを他と同じ基準に保つための仕組みです。",[12,63,64,65,70,71,76,77,82],{},"3つのユースケースすべてで、Tanuki IoT Platformの",[22,66,69],{"href":67,"rel":68},"https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector",[],"Java HTTPメトリクスコレクター","を使用します。このコレクターはHTTPエンドポイントをチェックし、レスポンスステータスや応答時間などのメトリクスを記録して、",[22,72,75],{"href":73,"rel":74},"https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/backend/rust-metrics-store",[],"Rustメトリクスバックエンド","に読み取り値を送信します。これにより、モダナイズ対象となる目に見えるアプリケーション境界と、検証すべき実際のバックエンド契約が得られます。以前、",[22,78,81],{"href":79,"rel":80},"https://about.gitlab.com/ja-jp/blog/fix-bugs-with-codex-and-gitlab/",[],"Codex and GitLabのチュートリアル","でこのRustバックエンドを構築しており、現在は本番アーキテクチャの一部として機能しています。",[84,85,90],"pre",{"className":86,"code":87,"language":88,"meta":89,"style":89},"language-mermaid shiki shiki-themes github-light","flowchart LR\n  subgraph sources[\"HTTP metric sources\"]\n    direction TB\n    health[\"Health endpoint\"]\n    maintenance[\"Maintenance endpoint\"]\n  end\n\n  java[\"Java HTTP metrics collector\"]\n  rust[(\"Rust metrics-store backend\")]\n\n  java -->|\"GET\"| health\n  java -->|\"GET\"| maintenance\n  java -->|\"POST /api/metrics\"| rust\n  rust -->|\"HTTP response\"| java\n\n  classDef source fill:#f8fafc,stroke:#64748b,stroke-width:2px,color:#0f172a\n  classDef focus fill:#dcfce7,stroke:#16a34a,stroke-width:3px,color:#0f172a\n  classDef backend fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0f172a\n\n  class health,maintenance source\n  class java focus\n  class rust backend\n","mermaid","",[91,92,93,102,108,114,120,126,132,139,145,151,156,162,168,174,180,185,191,197,203,208,214,220],"code",{"__ignoreMap":89},[94,95,98],"span",{"class":96,"line":97},"line",1,[94,99,101],{"class":100},"sgsFI","flowchart LR\n",[94,103,105],{"class":96,"line":104},2,[94,106,107],{"class":100},"  subgraph sources[\"HTTP metric sources\"]\n",[94,109,111],{"class":96,"line":110},3,[94,112,113],{"class":100},"    direction TB\n",[94,115,117],{"class":96,"line":116},4,[94,118,119],{"class":100},"    health[\"Health endpoint\"]\n",[94,121,123],{"class":96,"line":122},5,[94,124,125],{"class":100},"    maintenance[\"Maintenance endpoint\"]\n",[94,127,129],{"class":96,"line":128},6,[94,130,131],{"class":100},"  end\n",[94,133,135],{"class":96,"line":134},7,[94,136,138],{"emptyLinePlaceholder":137},true,"\n",[94,140,142],{"class":96,"line":141},8,[94,143,144],{"class":100},"  java[\"Java HTTP metrics collector\"]\n",[94,146,148],{"class":96,"line":147},9,[94,149,150],{"class":100},"  rust[(\"Rust metrics-store backend\")]\n",[94,152,154],{"class":96,"line":153},10,[94,155,138],{"emptyLinePlaceholder":137},[94,157,159],{"class":96,"line":158},11,[94,160,161],{"class":100},"  java -->|\"GET\"| health\n",[94,163,165],{"class":96,"line":164},12,[94,166,167],{"class":100},"  java -->|\"GET\"| maintenance\n",[94,169,171],{"class":96,"line":170},13,[94,172,173],{"class":100},"  java -->|\"POST /api/metrics\"| rust\n",[94,175,177],{"class":96,"line":176},14,[94,178,179],{"class":100},"  rust -->|\"HTTP response\"| java\n",[94,181,183],{"class":96,"line":182},15,[94,184,138],{"emptyLinePlaceholder":137},[94,186,188],{"class":96,"line":187},16,[94,189,190],{"class":100},"  classDef source fill:#f8fafc,stroke:#64748b,stroke-width:2px,color:#0f172a\n",[94,192,194],{"class":96,"line":193},17,[94,195,196],{"class":100},"  classDef focus fill:#dcfce7,stroke:#16a34a,stroke-width:3px,color:#0f172a\n",[94,198,200],{"class":96,"line":199},18,[94,201,202],{"class":100},"  classDef backend fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0f172a\n",[94,204,206],{"class":96,"line":205},19,[94,207,138],{"emptyLinePlaceholder":137},[94,209,211],{"class":96,"line":210},20,[94,212,213],{"class":100},"  class health,maintenance source\n",[94,215,217],{"class":96,"line":216},21,[94,218,219],{"class":100},"  class java focus\n",[94,221,223],{"class":96,"line":222},22,[94,224,225],{"class":100},"  class rust backend\n",[227,228,229],"h2",{"id":229},"前提条件",[38,231,232,240,248,251,254,263],{},[41,233,234,239],{},[22,235,238],{"href":236,"rel":237},"https://www.cursor.com/",[],"Cursor","がインストール・設定済みであること。本チュートリアルではCursor IDEを使用します。",[41,241,242,243,247],{},"Javaコレクターのソース、イシュー、モダナイズ用の作業アイテムを含むGitLabプロジェクト。",[22,244,246],{"href":67,"rel":245},[],"Tanuki IoT PlatformのJava HTTPメトリクスコレクター","を使用できます。",[41,249,250],{},"最初のユースケース用にJava 8、モダナイズ作業用にJava 21",[41,252,253],{},"ローカルビルドと機能テスト用のMaven、Docker、Docker Compose",[41,255,256,257,262],{},"GitLabインスタンスまたはトップレベルグループで",[22,258,261],{"href":259,"rel":260},"https://docs.gitlab.com/user/model_context_protocol/mcp_server/",[],"有効化","されたGitLab MCPサーバー",[41,264,265,266,271,272,277,278,282],{},"Javaコレクタープロジェクトで有効化された",[22,267,270],{"href":268,"rel":269},"https://docs.gitlab.com/user/duo_agent_platform/flows/foundational_flows/code_review/",[],"GitLab Duo Code Review Flow","、",[22,273,276],{"href":274,"rel":275},"https://docs.gitlab.com/user/duo_agent_platform/flows/foundational_flows/developer/",[],"Developer Flow","、そして",[22,279,281],{"href":280},"#automate-impact-analysis-for-modernization-breaking-changes","破壊的変更の影響分析用カスタムフロー","。これらのフローは、エージェントが作成するすべてのマージリクエストにプロジェクトのガードレールを適用します。",[284,285,287],"h3",{"id":286},"gitlabプロジェクトを準備する","GitLabプロジェクトを準備する",[12,289,290],{},"自分の環境でこのワークフローを再現したい場合は、まずプロジェクトをインポート・クローンし、Cursorでプロジェクトを開くところから始めます。",[38,292,293,299,302],{},[41,294,295,298],{},[22,296,246],{"href":67,"rel":297},[],"を、未解決のイシューも含めてGitLab環境にインポートします。",[41,300,301],{},"プロジェクトをローカル環境にクローンし、そのディレクトリに移動します。",[41,303,304],{},"Cursorでプロジェクトを開きます。",[84,306,310],{"className":307,"code":308,"language":309,"meta":89,"style":89},"language-shell shiki shiki-themes github-light","git clone https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector.git\ncd java-http-metrics-collector\n\ncursor .\n","shell",[91,311,312,325,334,338],{"__ignoreMap":89},[94,313,314,318,322],{"class":96,"line":97},[94,315,317],{"class":316},"s7eDp","git",[94,319,321],{"class":320},"sYBdl"," clone",[94,323,324],{"class":320}," https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector.git\n",[94,326,327,331],{"class":96,"line":104},[94,328,330],{"class":329},"sYu0t","cd",[94,332,333],{"class":320}," java-http-metrics-collector\n",[94,335,336],{"class":96,"line":110},[94,337,138],{"emptyLinePlaceholder":137},[94,339,340,343],{"class":96,"line":116},[94,341,342],{"class":316},"cursor",[94,344,345],{"class":320}," .\n",[12,347,348,349,352],{},"このプロジェクトには、リポジトリの指示とMavenコマンドが記載された",[91,350,351],{},"AGENTS.md","ファイルが含まれています。Cursorはこのローカルの指示を利用して、プロジェクトの構成や変更のテスト方法を理解できます。",[12,354,355],{},[356,357],"img",{"alt":358,"src":359},"CursorでAGENTS.mdの指示とともに開かれたJava HTTPメトリクスコレクター","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784733478/l4hqhlzxekmhobu2qg0v.png",[227,361,363],{"id":362},"cursorで失敗しているエンドツーエンドテストを修正する","Cursorで失敗しているエンドツーエンドテストを修正する",[12,365,366,367,370,371,374],{},"このコレクターでは、エンドポイントから期待するHTTPステータスコードをユーザーが設定できます。しかし実装上は、すべての",[91,368,369],{},"2xx","レスポンスを成功として扱ってしまい、",[91,372,373],{},"503","エラーは期待どおりに設定されていても常に失敗として扱われていました。",[12,376,377],{},"エンドツーエンドテストはすでにこの不整合を検出していますが、CI/CDジョブは失敗が許容される設定になっています。そのため、本来役立つはずのシグナルが、当たり前に受け入れられる背景ノイズになってしまっていました。",[12,379,380],{},[356,381],{"alt":382,"src":383},"失敗しているエンドツーエンドテストと、失敗が許容されているCI/CDジョブ","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784733536/uaxqalqoceujyja7usmv.png",[284,385,387],{"id":386},"cursorで再現修正する","Cursorで再現・修正する",[12,389,390],{},"この問題はローカル環境で再現できます。Cursor IDEで新しいチャットを開き、まずはプロンプトで観測された問題を直接説明することから始めます。",[84,392,396],{"className":393,"code":394,"language":395,"meta":89,"style":89},"language-markdown shiki shiki-themes github-light","Can you help me fix the end-to-end tests in this project? Please create an analysis first, then fix it, and run the tests again.\n","markdown",[91,397,398],{"__ignoreMap":89},[94,399,400],{"class":96,"line":97},[94,401,394],{"class":100},[12,403,404,405,408],{},"Cursorはまず、エンドポイントの設定を",[91,406,407],{},"HttpCollector","と失敗しているエンドツーエンドテストまで遡って調査し、根本原因を特定します。",[12,410,411],{},[356,412],{"alt":413,"src":414},"問題と根本原因を分析するCursor","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784733605/ojz2pzcftwjfcfscjtwg.png",[12,416,417],{},"対象のテストとMavenのテストスイート全体が通過したら、ブランチとマージリクエストを作成します。これまで失敗が許容されていたエンドツーエンドジョブは、決定的に成功する状態になれば、必須ジョブに変更できます。",[84,419,421],{"className":393,"code":420,"language":395,"meta":89,"style":89},"Can you create a git branch and merge request?\n",[91,422,423],{"__ignoreMap":89},[94,424,425],{"class":96,"line":97},[94,426,420],{"class":100},[284,428,429],{"id":429},"レビューとマージ",[12,431,432],{},"マージリクエストを作成すると、CI/CDのビルドとテスト、セキュリティスキャンが自動的にトリガーされます。",[12,434,435],{},[356,436],{"alt":437,"src":438},"エンドツーエンドテストが修正されたマージリクエスト","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784733663/koz3yb3zq5ewwl6vrbgk.png",[12,440,441,442,446],{},"続いて、",[22,443,445],{"href":268,"rel":444},[],"GitLab Duo Code Review","が、プロジェクト固有のJavaレビュー指示に基づいて、対象の変更をレビューします。",[12,448,449],{},[356,450],{"alt":451,"src":452},"コードレビューのフィードバック","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784733717/cjxeoecb4fa7yrvy7i90.png",[12,454,455],{},"レビューで具体的な問題が指摘された場合は、マージする前にDeveloper Flowを通じて対応します。ここが重要なポイントです。Code Review Flowは、Cursorがどれだけ速く生成したものであっても、エージェントが作成したすべてのマージリクエストが他と同じ基準を満たすことを保証します。マージリクエストは、あくまでコラボレーションと意思決定の場であり続けます。",[12,457,458],{},[356,459],{"alt":460,"src":461},"レビューのフィードバックに対応するDeveloper Flow","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784733848/wehjrbkhhyhze8vtkaby.png",[12,463,464],{},"この修正により、動作面のベースラインが得られます。ランタイムの移行と混在させることなく、実際のバグを修正できたことで、テストは今後のモダナイズ作業を通じて期待ステータスの契約を守ってくれます。",[12,466,467],{},"Cursorが期待どおりのエンドツーエンドテストをどのように調査・修正するかは、以下の動画で確認できます。",[469,470,473,474],"figure",{"className":471},[472],"video_container","\n  ",[475,476,480],"iframe",{"src":477,"frameBorder":478,"allowFullScreen":479},"https://www.youtube.com/embed/vpPt8TICiZY","0","true"," ",[227,482,484],{"id":483},"java-21へのモダナイズに向けて品質ゲートを準備する","Java 21へのモダナイズに向けて品質ゲートを準備する",[12,486,487],{},"最初の修正は、リポジトリのコンテキストだけで完結しました。次のリクエストははるかに大規模です。コレクターをJava 8からJava 21へモダナイズすることです。",[12,489,490,491,496],{},"この作業については、すでに",[22,492,495],{"href":493,"rel":494},"https://gitlab.com/groups/gitlab-da/demo-environments/tanuki-iot-platform/-/work_items/13",[],"Javaモダナイズのエピック","に計画のコンテキストがそろっています。子の作業アイテム、チームでの議論、マージリクエストを伴う調査、パイプラインの履歴、依存関係、セキュリティの検出結果などです。これらの詳細はローカルのチェックアウトには存在しません。そのすべてを1つの巨大なプロンプトにコピーするのではなく、MCPを使ってGitLabのコンテキストをCursorに取り込むことができます。",[284,498,500],{"id":499},"cursorでgitlab-mcpサーバーを設定する","CursorでGitLab MCPサーバーを設定する",[12,502,503,504,509],{},"GitLab MCPサーバーが、自分のインスタンスまたはトップレベルグループで",[22,505,508],{"href":506,"rel":507},"https://docs.gitlab.com/user/gitlab_duo/model_context_protocol/mcp_server/#prerequisites",[],"有効化されている","ことを確認してください。Cursorは、追加の依存関係なしに直接接続できるHTTPトランスポートを使用します。",[12,511,512,517],{},[22,513,516],{"href":514,"rel":515},"https://docs.gitlab.com/user/gitlab_duo/model_context_protocol/mcp_server/#connect-cursor-to-the-gitlab-mcp-server",[],"CursorをGitLab MCPサーバーに接続する","には、以下の手順に従います。",[38,519,520,528,538],{},[41,521,522,523,527],{},"Cursorで、",[524,525,526],"strong",{},"Settings > Cursor Settings > Tools & MCP","に移動します。",[41,529,530,533,534,537],{},[524,531,532],{},"Installed MCP Servers","の下にある",[524,535,536],{},"New MCP Server","を選択します。",[41,539,540,541,544,545,548,549,552,553,556],{},"開かれた",[91,542,543],{},"mcp.json","ファイルの",[91,546,547],{},"mcpServers","キーに、以下の定義を追加します。GitLab.comの場合は",[91,550,551],{},"\u003Cgitlab.example.com>","を",[91,554,555],{},"gitlab.com","に置き換えてください。GitLab Self-ManagedまたはDedicatedの場合は、自分のGitLabインスタンスのURLを使用してください。",[84,558,562],{"className":559,"code":560,"language":561,"meta":89,"style":89},"language-json shiki shiki-themes github-light","{\n  \"mcpServers\": {\n    \"GitLab\": {\n      \"type\": \"http\",\n      \"url\": \"https://\u003Cgitlab.example.com>/api/v4/mcp\"\n    }\n  }\n}\n","json",[91,563,564,569,577,584,598,608,613,618],{"__ignoreMap":89},[94,565,566],{"class":96,"line":97},[94,567,568],{"class":100},"{\n",[94,570,571,574],{"class":96,"line":104},[94,572,573],{"class":329},"  \"mcpServers\"",[94,575,576],{"class":100},": {\n",[94,578,579,582],{"class":96,"line":110},[94,580,581],{"class":329},"    \"GitLab\"",[94,583,576],{"class":100},[94,585,586,589,592,595],{"class":96,"line":116},[94,587,588],{"class":329},"      \"type\"",[94,590,591],{"class":100},": ",[94,593,594],{"class":320},"\"http\"",[94,596,597],{"class":100},",\n",[94,599,600,603,605],{"class":96,"line":122},[94,601,602],{"class":329},"      \"url\"",[94,604,591],{"class":100},[94,606,607],{"class":320},"\"https://\u003Cgitlab.example.com>/api/v4/mcp\"\n",[94,609,610],{"class":96,"line":128},[94,611,612],{"class":100},"    }\n",[94,614,615],{"class":96,"line":134},[94,616,617],{"class":100},"  }\n",[94,619,620],{"class":96,"line":141},[94,621,622],{"class":100},"}\n",[38,624,625,628,631],{"start":116},[41,626,627],{},"ファイルを保存し、ブラウザでOAuth認証ページが開くのを待ちます。開かない場合は、Cursorを終了して再起動してください。",[41,629,630],{},"ブラウザで認証リクエストを確認し、承認します。",[41,632,633],{},"Cursorに戻り、表示されているツールの一覧を確認します。",[12,635,636],{},[356,637],{"alt":638,"src":639},"OAuth認証後、Cursorに接続されたGitLab MCPサーバー","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784733928/anreghjemkrnuezohhzh.png",[12,641,642],{},"これで新しいチャットを開始し、利用可能なGitLab MCPツールに基づいて質問できるようになります。",[12,644,645],{},"CursorがGitLab MCPで認証すると、既存のGitLabアイデンティティとして動作します。アクセスできるのは、自分がすでにアクセス権を持つプロジェクトやリソースに限られます。MCPは承認済みのコンテキストをIDEに取り込むものであり、GitLabの権限をバイパスするものではありません。",[284,647,649],{"id":648},"java-21モダナイズに向けて環境を準備する","Java 21モダナイズに向けて環境を準備する",[12,651,652,656],{},[22,653,655],{"href":493,"rel":654},[],"Java 8から21へのモダナイズのエピック","では、必要な計画がより小さなイテレーションに分割されており、各成果物と変更がそれぞれ単独でテスト可能になっています。",[12,658,659],{},[356,660],{"alt":661,"src":662},"子イシューを持つGitLabエピック","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784733989/thwfzpvbs7tcm0un2xg6.png",[12,664,665],{},"最初のステップは、CI/CDインフラでJava 8と21の両方を並行してテストできるようにすることです。各モダナイズタスクの開始時点からテストカバレッジを高めていくことも必須です。",[12,667,668],{},"Cursor IDEを開き、以下のプロンプトを使って計画のコンテキストを取得します。",[84,670,672],{"className":393,"code":671,"language":395,"meta":89,"style":89},"Please help me modernize this sensor from Java 8 to 21. We want to start with the base line for CI/CD builds in work item 14, and then also look into test coverage from 21. Start the implementation in a new Git branch called `maint-java-21` so we can continue testing different scenarios.\n",[91,673,674],{"__ignoreMap":89},[94,675,676,679,682],{"class":96,"line":97},[94,677,678],{"class":100},"Please help me modernize this sensor from Java 8 to 21. We want to start with the base line for CI/CD builds in work item 14, and then also look into test coverage from 21. Start the implementation in a new Git branch called ",[94,680,681],{"class":329},"`maint-java-21`",[94,683,684],{"class":100}," so we can continue testing different scenarios.\n",[12,686,687,688,691],{},"CIビルドの可視化に関するイシューの作業が完了したら、Cursorは",[91,689,690],{},"create_workitem_note","のMCPツールを使って、イシューに要約コメントを追加することもできます。",[12,693,694],{},[356,695],{"alt":696,"src":697},"GitLab MCPサーバーのツール呼び出しによるCursorの要約","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734071/bks4lwnncddardc05r3e.png",[12,699,700],{},"新しいマージリクエストは、CI/CDパイプラインとCode Review Flowの両方をトリガーします。Code Review Flowは、開発スタイルガイドが要求するドキュメント化についてコメントを残します。",[12,702,703],{},[356,704],{"alt":705,"src":706},"マージリクエストにおけるコードレビューのフィードバック","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734168/z7ootq0wqmom3yxmdexj.png",[12,708,709],{},"Developer Flowのサービスアカウントにメンションすることで、GitLabのUI上でフィードバックにすぐ対応できます。",[84,711,713],{"className":393,"code":712,"language":395,"meta":89,"style":89},"@duo-developer-\u003Cgroup-name> Can you help address the review feedback?\n",[91,714,715],{"__ignoreMap":89},[94,716,717],{"class":96,"line":97},[94,718,712],{"class":100},[12,720,721],{},"このプロンプトによって新しいバックグラウンドセッションが開始されるため、その間は他のタスクに集中できます。あるいは、Cursor IDEに戻り、チャットでマージリクエストのレビューフィードバックに対応するよう指示することもできます。",[12,723,724],{},[356,725],{"alt":726,"src":727},"Cursor IDEのプロンプト「MRにレビューフィードバックがあります。修正を手伝ってください」","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734264/n5ky8nj73bpb1imzrj6h.png",[12,729,730,731,734],{},"Cursorは変更を実装し、",[91,732,733],{},"create_merge_request_note","のMCPツールを使って、マージリクエストのスレッドにコメントを追加します。",[12,736,737],{},[356,738],{"alt":739,"src":740},"コードレビューのコメントに対応したGitLabマージリクエスト","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734337/hah0qxe8ei5h6iefzqz4.png",[12,742,743],{},"この変更では、一時的なJava 8のベースラインを維持しつつ、Java 21向けの独立したビルドとテスト検証を追加します。これにより、ソースコードがJava 21専用のAPIを使い始める前の段階で、互換性がパイプライン上で可視化されます。こうした品質ゲートが整えば、以降のエージェント主導のすべての変更は、レビューされ、テストされ、追跡可能になります。これは他のマージリクエストと同じ基準であり、だからこそCursorを安心して高速に動かせるのです。",[12,745,746],{},"CursorがGitLab MCPを使って品質ゲートを準備し、コードレビューのフィードバックに対応する様子は、以下の動画で確認できます。",[469,748,473,750],{"className":749},[472],[475,751,480],{"src":752,"frameBorder":478,"allowFullScreen":479},"https://www.youtube.com/embed/bqT2exfE5Go",[227,754,58],{"id":755},"java-21でhttp接続処理をモダナイズする",[12,757,758,759,762,763,766,767,772],{},"Java HTTPメトリクスコレクターは現在、Java 8の従来型API",[91,760,761],{},"HttpURLConnection","を使用しています。Java 21ではHTTPライブラリが",[91,764,765],{},"java.net.http.HttpClient","にモダナイズされましたが、これは単なる機械的なリネームではありません。リダイレクト、制限付きヘッダー、タイムアウトの範囲、レスポンスボディ、割り込み、接続の再利用など、挙動が異なりうる要素は多岐にわたります。だからこそ、この実装は1つの範囲が限定された作業アイテム、",[22,768,771],{"href":769,"rel":770},"https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector/-/work_items/16",[],"Replace HttpURLConnection with java.net.http.HttpClient","に閉じています。実際にやってみましょう。",[12,774,775],{},"Cursor IDEで新しいチャットを開き、変更の実装を依頼します。",[12,777,778,781],{},[524,779,780],{},"注:"," このユースケースでは、変更の検証にローカルのDocker Compose環境を使用します。この挙動を再現したい場合はDockerとDocker Composeをインストールしてください。不要な場合は2つ目のプロンプトを省略してください。",[84,783,785],{"className":393,"code":784,"language":395,"meta":89,"style":89},"We want to continue modernizing the app to Java 21 - use the same maint-java-21 branch, and start implementing issue 16.\n\nVerify the changes locally using the docker compose setup, after making the changes.\n",[91,786,787,792,796],{"__ignoreMap":89},[94,788,789],{"class":96,"line":97},[94,790,791],{"class":100},"We want to continue modernizing the app to Java 21 - use the same maint-java-21 branch, and start implementing issue 16.\n",[94,793,794],{"class":96,"line":104},[94,795,138],{"emptyLinePlaceholder":137},[94,797,798],{"class":96,"line":110},[94,799,800],{"class":100},"Verify the changes locally using the docker compose setup, after making the changes.\n",[12,802,803,804,806,807,810],{},"GitLab MCPサーバーは、イシューのコンテキスト、受け入れ基準、依存関係、関連する議論を提供します。最初のコードモダナイズのイシューは、意図的に同期的かつ限定的な範囲にとどめています。",[91,805,761],{},"を、再利用可能な1つの",[91,808,809],{},"HttpClient","に置き換えるだけで、仮想スレッドの追加や時間モデルの変更、関連のない依存関係の修正は行いません。これらは価値のあるフォローアップですが、一緒に行ってしまうと、挙動の変更を切り分けてレビューし、ロールバックすることが難しくなります。",[284,812,814],{"id":813},"ローカルで実装検証する","ローカルで実装・検証する",[12,816,817],{},"対象を絞ったローカルのHTTPサーバーテストでは、メソッド、ヘッダー、期待されるステータスコードと想定外のステータスコード、リダイレクト、タイムアウト、レスポンスのメタデータ、接続の失敗、割り込みをカバーします。",[12,819,820],{},[356,821],{"alt":822,"src":823},"ローカルのMavenテストを実行するCursor","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734391/fuxi3jcrcg5alhuqcrje.png",[12,825,826,827,830],{},"続いてDocker Composeの機能テストにより、認証済みの読み取り値が",[91,828,829],{},"rust-metrics-store","バックエンドに引き続き到達することを確認します。",[12,832,833],{},[356,834],{"alt":835,"src":836},"Rustバックエンドを使ってローカルのDocker Composeを実行するCursor","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734439/w83djmi4df9dfynb9dfj.png",[12,838,839],{},"変更後にCI/CDパイプラインが失敗している場合は、GitLab MCPサーバーのツールを活用し、コンテキストを切り替えることなくCursor IDE上で直接調査・修正できます。",[12,841,842],{},[356,843],{"alt":844,"src":845},"CI/CDジョブのログを取得するGitLab MCPサーバーのツール呼び出しを含むCursor IDE","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734501/g4mfs2zdrffzb9pd8v09.png",[12,847,848,849,854,855,860],{},"GitLabのUIでは、",[22,850,853],{"href":851,"rel":852},"https://docs.gitlab.com/user/duo_agent_platform/flows/foundational_flows/fix_pipeline/",[],"Fix CI/CD Pipeline Flow","を使用するか、",[22,856,859],{"href":857,"rel":858},"https://docs.gitlab.com/user/duo_agent_platform/agents/foundational_agents/ci_expert_agent/",[],"CI Expertエージェント","に助けを求めることができます。",[284,862,864],{"id":863},"cicdとレビューのエビデンス","CI/CDとレビューのエビデンス",[12,866,867],{},"GitLab CI/CD、GitLab Duo Code Review、セキュリティスキャン、そしてAIによる影響分析が、マージリクエストにおける最終的なエビデンスとなります。それでも、微妙な境界においては人によるレビューが最も重要です。意図的な挙動の違いは、デプロイ後に発覚するのではなく、マージリクエストの時点で明示されているべきです。",[12,869,870],{},[356,871],{"alt":872,"src":873},"影響分析を伴うDeveloper Flow","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734549/jxqds2bwzcedn7yafdvr.png",[12,875,876],{},"CursorとGitLabがコレクターのHTTPライブラリをJava 21にどのようにモダナイズするかは、以下の動画で確認できます。",[469,878,473,880],{"className":879},[472],[475,881,480],{"src":882,"frameBorder":478,"allowFullScreen":479},"https://www.youtube.com/embed/AZEDvb474n0",[227,884,886],{"id":885},"cursorとgitlabを使うためのヒント","CursorとGitLabを使うためのヒント",[12,888,889],{},"CursorとGitLabを組み合わせて使うためのヒントを紹介します。",[284,891,892],{"id":892},"モダナイズに伴う破壊的変更の影響分析を自動化する",[12,894,895,900,901,906,907,912],{},[22,896,899],{"href":897,"rel":898},"https://www.youtube.com/watch?v=AZEDvb474n0",[],"3つ目のユースケース","では、Developer Flowが破壊的変更の影響分析を行う様子を紹介しました。このワークフローは、マージリクエストの準備が整ったとき、あるいはパイプラインが正常なときにトリガーされる自動化された",[22,902,905],{"href":903,"rel":904},"https://docs.gitlab.com/user/duo_agent_platform/flows/custom/",[],"カスタムフロー","に変えることができます。追加のコンテキストは、コード、作業アイテム、マージリクエスト、脆弱性などを横断するコンテキストグラフを提供する",[22,908,911],{"href":909,"rel":910},"https://about.gitlab.com/ja-jp/blog/introducing-gitlab-orbit/",[],"GitLab Orbit","から取得できます。",[12,914,915,916,921,922,927],{},"サンプルのフローは、AI Catalogの",[22,917,920],{"href":918,"rel":919},"https://gitlab.com/explore/ai-catalog/flows/1013017/",[],"MR Impact analysis (Orbit)","から確認できます。着想をくれたチームメイトのFatima Sarah Kalidに感謝します。カスタムフローは",[22,923,926],{"href":924,"rel":925},"https://about.gitlab.com/ja-jp/blog/multi-step-software-delivery-with-agentic-flows/",[],"GitLab 19.2","で一般提供されています。",[12,929,930],{},[356,931],{"alt":932,"src":933},"AI Catalogにおけるカスタムフロー","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734604/nk2faraxdhghiktndrs5.png",[12,935,936],{},[356,937],{"alt":938,"src":939},"GitLab Duo Agent PlatformとOrbitにおけるカスタムフローを使ったマージリクエストの影響分析","https://res.cloudinary.com/about-gitlab-com/image/upload/v1784734740/app3pnjwqzoyulojkomq.png",[284,941,942],{"id":942},"エージェント向けにガイドラインと境界を明文化する",[944,945,947],"h4",{"id":946},"javaのためのagentsmd","JavaのためのAGENTS.md",[12,949,950,956],{},[22,951,954],{"href":952,"rel":953},"https://docs.gitlab.com/user/duo_agent_platform/customize/agents_md/",[],[91,955,351],{},"ファイルは、プロジェクトのアーキテクチャ、コマンド、コードスタイル、テストに関する期待、境界をCursorや他のコーディングエージェントが理解する助けとなります。こうした指示はコードのそばに置き、検証できる程度に具体的にしておきましょう。",[12,958,959,966],{},[22,960,963,964],{"href":961,"rel":962},"https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector/-/blob/main/AGENTS.md?ref_type=heads",[],"Java HTTPメトリクスコレクタープロジェクトの",[91,965,351],{},"からの例です。",[84,968,970],{"className":393,"code":969,"language":395,"meta":89,"style":89},"# Java HTTP Metrics Collector - Agent Instructions\n\n## Overview\n\nThe Java HTTP Metrics Collector is a REST API metrics collection sensor for the Tanuki IoT Platform. It monitors HTTP endpoints, collects performance metrics (response time, status codes, content length), and exports them in Prometheus text format. The application runs continuously with configurable collection intervals and supports concurrent endpoint monitoring.\n\n## Code Style and Standards\n\n### Java 8 Compatibility\n\n- Do not modernize Java 8 code to Java 11+ features unless there is a GitLab issue or task specifically requesting modernization\n- Target Java 8 for source and compilation: `maven.compiler.source=1.8` and `maven.compiler.target=1.8`\n- Use Java 8 compatible patterns (e.g., anonymous inner classes instead of lambdas where appropriate)\n\n### Documentation\n\n- All public classes must have Javadoc describing purpose and usage\n- All public methods must have Javadoc with `@param` and `@return` tags\n- Include code examples in main class Javadoc\n\n### Class Organization\n\n- **Main entry point**: `HttpMetricsCollector` - orchestrates configuration loading, metric collection, and export\n- **Collector**: `HttpCollector` - performs HTTP requests and collects metrics\n- **Exporter**: `PrometheusExporter` - exports metrics in Prometheus text format\n- **Models**: `CollectorConfig`, `EndpointConfig`, `HttpMetric` - data transfer objects\n\n### Dependency Management\n\n- Always use Maven for dependency management\n- Use property-based version management for dependencies (e.g., `${jackson.version}`)\n- Keep dependencies up-to-date in `pom.xml`\n\n### Error Handling\n\n- Use try-catch blocks with proper resource management (try-with-resources where applicable)\n- Log errors using SLF4J Logger\n- Gracefully handle configuration loading failures\n- Implement proper shutdown hooks for resource cleanup\n\n### Concurrency\n\n- Use `ExecutorService` for concurrent HTTP requests\n- Thread pool size is limited to the minimum of endpoint count and 10\n- Properly shutdown executor service with timeout handling\n- Use `Future` objects to collect results from concurrent tasks\n",[91,971,972,978,982,987,991,996,1000,1005,1009,1014,1018,1027,1043,1050,1054,1059,1063,1070,1088,1095,1099,1104,1108,1125,1141,1157,1184,1189,1195,1200,1208,1222,1233,1238,1244,1249,1257,1265,1273,1281,1286,1292,1297,1311,1319,1327],{"__ignoreMap":89},[94,973,974],{"class":96,"line":97},[94,975,977],{"class":976},"surfw","# Java HTTP Metrics Collector - Agent Instructions\n",[94,979,980],{"class":96,"line":104},[94,981,138],{"emptyLinePlaceholder":137},[94,983,984],{"class":96,"line":110},[94,985,986],{"class":976},"## Overview\n",[94,988,989],{"class":96,"line":116},[94,990,138],{"emptyLinePlaceholder":137},[94,992,993],{"class":96,"line":122},[94,994,995],{"class":100},"The Java HTTP Metrics Collector is a REST API metrics collection sensor for the Tanuki IoT Platform. It monitors HTTP endpoints, collects performance metrics (response time, status codes, content length), and exports them in Prometheus text format. The application runs continuously with configurable collection intervals and supports concurrent endpoint monitoring.\n",[94,997,998],{"class":96,"line":128},[94,999,138],{"emptyLinePlaceholder":137},[94,1001,1002],{"class":96,"line":134},[94,1003,1004],{"class":976},"## Code Style and Standards\n",[94,1006,1007],{"class":96,"line":141},[94,1008,138],{"emptyLinePlaceholder":137},[94,1010,1011],{"class":96,"line":147},[94,1012,1013],{"class":976},"### Java 8 Compatibility\n",[94,1015,1016],{"class":96,"line":153},[94,1017,138],{"emptyLinePlaceholder":137},[94,1019,1020,1024],{"class":96,"line":158},[94,1021,1023],{"class":1022},"sqxcx","-",[94,1025,1026],{"class":100}," Do not modernize Java 8 code to Java 11+ features unless there is a GitLab issue or task specifically requesting modernization\n",[94,1028,1029,1031,1034,1037,1040],{"class":96,"line":164},[94,1030,1023],{"class":1022},[94,1032,1033],{"class":100}," Target Java 8 for source and compilation: ",[94,1035,1036],{"class":329},"`maven.compiler.source=1.8`",[94,1038,1039],{"class":100}," and ",[94,1041,1042],{"class":329},"`maven.compiler.target=1.8`\n",[94,1044,1045,1047],{"class":96,"line":170},[94,1046,1023],{"class":1022},[94,1048,1049],{"class":100}," Use Java 8 compatible patterns (e.g., anonymous inner classes instead of lambdas where appropriate)\n",[94,1051,1052],{"class":96,"line":176},[94,1053,138],{"emptyLinePlaceholder":137},[94,1055,1056],{"class":96,"line":182},[94,1057,1058],{"class":976},"### Documentation\n",[94,1060,1061],{"class":96,"line":187},[94,1062,138],{"emptyLinePlaceholder":137},[94,1064,1065,1067],{"class":96,"line":193},[94,1066,1023],{"class":1022},[94,1068,1069],{"class":100}," All public classes must have Javadoc describing purpose and usage\n",[94,1071,1072,1074,1077,1080,1082,1085],{"class":96,"line":199},[94,1073,1023],{"class":1022},[94,1075,1076],{"class":100}," All public methods must have Javadoc with ",[94,1078,1079],{"class":329},"`@param`",[94,1081,1039],{"class":100},[94,1083,1084],{"class":329},"`@return`",[94,1086,1087],{"class":100}," tags\n",[94,1089,1090,1092],{"class":96,"line":205},[94,1091,1023],{"class":1022},[94,1093,1094],{"class":100}," Include code examples in main class Javadoc\n",[94,1096,1097],{"class":96,"line":210},[94,1098,138],{"emptyLinePlaceholder":137},[94,1100,1101],{"class":96,"line":216},[94,1102,1103],{"class":976},"### Class Organization\n",[94,1105,1106],{"class":96,"line":222},[94,1107,138],{"emptyLinePlaceholder":137},[94,1109,1111,1113,1117,1119,1122],{"class":96,"line":1110},23,[94,1112,1023],{"class":1022},[94,1114,1116],{"class":1115},"sbYKK"," **Main entry point**",[94,1118,591],{"class":100},[94,1120,1121],{"class":329},"`HttpMetricsCollector`",[94,1123,1124],{"class":100}," - orchestrates configuration loading, metric collection, and export\n",[94,1126,1128,1130,1133,1135,1138],{"class":96,"line":1127},24,[94,1129,1023],{"class":1022},[94,1131,1132],{"class":1115}," **Collector**",[94,1134,591],{"class":100},[94,1136,1137],{"class":329},"`HttpCollector`",[94,1139,1140],{"class":100}," - performs HTTP requests and collects metrics\n",[94,1142,1144,1146,1149,1151,1154],{"class":96,"line":1143},25,[94,1145,1023],{"class":1022},[94,1147,1148],{"class":1115}," **Exporter**",[94,1150,591],{"class":100},[94,1152,1153],{"class":329},"`PrometheusExporter`",[94,1155,1156],{"class":100}," - exports metrics in Prometheus text format\n",[94,1158,1160,1162,1165,1167,1170,1173,1176,1178,1181],{"class":96,"line":1159},26,[94,1161,1023],{"class":1022},[94,1163,1164],{"class":1115}," **Models**",[94,1166,591],{"class":100},[94,1168,1169],{"class":329},"`CollectorConfig`",[94,1171,1172],{"class":100},", ",[94,1174,1175],{"class":329},"`EndpointConfig`",[94,1177,1172],{"class":100},[94,1179,1180],{"class":329},"`HttpMetric`",[94,1182,1183],{"class":100}," - data transfer objects\n",[94,1185,1187],{"class":96,"line":1186},27,[94,1188,138],{"emptyLinePlaceholder":137},[94,1190,1192],{"class":96,"line":1191},28,[94,1193,1194],{"class":976},"### Dependency Management\n",[94,1196,1198],{"class":96,"line":1197},29,[94,1199,138],{"emptyLinePlaceholder":137},[94,1201,1203,1205],{"class":96,"line":1202},30,[94,1204,1023],{"class":1022},[94,1206,1207],{"class":100}," Always use Maven for dependency management\n",[94,1209,1211,1213,1216,1219],{"class":96,"line":1210},31,[94,1212,1023],{"class":1022},[94,1214,1215],{"class":100}," Use property-based version management for dependencies (e.g., ",[94,1217,1218],{"class":329},"`${jackson.version}`",[94,1220,1221],{"class":100},")\n",[94,1223,1225,1227,1230],{"class":96,"line":1224},32,[94,1226,1023],{"class":1022},[94,1228,1229],{"class":100}," Keep dependencies up-to-date in ",[94,1231,1232],{"class":329},"`pom.xml`\n",[94,1234,1236],{"class":96,"line":1235},33,[94,1237,138],{"emptyLinePlaceholder":137},[94,1239,1241],{"class":96,"line":1240},34,[94,1242,1243],{"class":976},"### Error Handling\n",[94,1245,1247],{"class":96,"line":1246},35,[94,1248,138],{"emptyLinePlaceholder":137},[94,1250,1252,1254],{"class":96,"line":1251},36,[94,1253,1023],{"class":1022},[94,1255,1256],{"class":100}," Use try-catch blocks with proper resource management (try-with-resources where applicable)\n",[94,1258,1260,1262],{"class":96,"line":1259},37,[94,1261,1023],{"class":1022},[94,1263,1264],{"class":100}," Log errors using SLF4J Logger\n",[94,1266,1268,1270],{"class":96,"line":1267},38,[94,1269,1023],{"class":1022},[94,1271,1272],{"class":100}," Gracefully handle configuration loading failures\n",[94,1274,1276,1278],{"class":96,"line":1275},39,[94,1277,1023],{"class":1022},[94,1279,1280],{"class":100}," Implement proper shutdown hooks for resource cleanup\n",[94,1282,1284],{"class":96,"line":1283},40,[94,1285,138],{"emptyLinePlaceholder":137},[94,1287,1289],{"class":96,"line":1288},41,[94,1290,1291],{"class":976},"### Concurrency\n",[94,1293,1295],{"class":96,"line":1294},42,[94,1296,138],{"emptyLinePlaceholder":137},[94,1298,1300,1302,1305,1308],{"class":96,"line":1299},43,[94,1301,1023],{"class":1022},[94,1303,1304],{"class":100}," Use ",[94,1306,1307],{"class":329},"`ExecutorService`",[94,1309,1310],{"class":100}," for concurrent HTTP requests\n",[94,1312,1314,1316],{"class":96,"line":1313},44,[94,1315,1023],{"class":1022},[94,1317,1318],{"class":100}," Thread pool size is limited to the minimum of endpoint count and 10\n",[94,1320,1322,1324],{"class":96,"line":1321},45,[94,1323,1023],{"class":1022},[94,1325,1326],{"class":100}," Properly shutdown executor service with timeout handling\n",[94,1328,1330,1332,1334,1337],{"class":96,"line":1329},46,[94,1331,1023],{"class":1022},[94,1333,1304],{"class":100},[94,1335,1336],{"class":329},"`Future`",[94,1338,1339],{"class":100}," objects to collect results from concurrent tasks\n",[944,1341,1343],{"id":1342},"javaのコードレビュー指示","Javaのコードレビュー指示",[12,1345,1346,1347,1355,1356,1361],{},"GitLab Duo Code Review Flowは、スタイルガイドと境界を維持する助けとなります。そのためには、",[22,1348,1351,1354],{"href":1349,"rel":1350},"https://docs.gitlab.com/user/duo_agent_platform/customize/review_instructions/",[],[91,1352,1353],{},".gitlab/duo/mr-review-instructions.yaml","ファイル","に具体的な指示が必要です。例えば",[22,1357,1360],{"href":1358,"rel":1359},"https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector/-/blob/main/.gitlab/duo/mr-review-instructions.yaml?ref_type=heads",[],"Java向け","は次のとおりです。",[84,1363,1367],{"className":1364,"code":1365,"language":1366,"meta":89,"style":89},"language-yaml shiki shiki-themes github-light","# Custom instructions for GitLab Duo Code Review\n\ninstructions:\n  # General guidelines\n\n  - name: Code Review\n    instructions: |\n      1. Focus on correctness and performance\n      2. Ensure code comments and documentation are clear and concise\n      3. Be respectful and constructive in comments\n\n  - name: CI/CD Configuration\n    fileFilters:\n      - \".gitlab-ci.yml\"\n    instructions: |\n      1. Do not use YAML anchors\n      2. Always use rules in jobs, avoid using `only`\n\n  # Java style guide\n\n  - name: Java Style Guide\n    fileFilters:\n      - \"**/*.java\"\n    instructions: |\n      1. Do not modernize Java 8 code to Java 11+ features, unless there is a GitLab issue or task specifically requesting modernization\n      2. All public classes must have Javadoc describing purpose and usage\n      3. All public methods must have Javadoc with @param and @return tags\n      4. Include code examples in main class Javadoc\n      5. All public methods must have at least one test case\n      6. Use httpbun.com for test endpoints (status codes, delays, JSON responses)\n","yaml",[91,1368,1369,1375,1379,1388,1393,1397,1410,1421,1426,1431,1436,1440,1451,1458,1466,1474,1479,1484,1488,1493,1497,1508,1514,1521,1529,1534,1539,1544,1549,1554],{"__ignoreMap":89},[94,1370,1371],{"class":96,"line":97},[94,1372,1374],{"class":1373},"sAwPA","# Custom instructions for GitLab Duo Code Review\n",[94,1376,1377],{"class":96,"line":104},[94,1378,138],{"emptyLinePlaceholder":137},[94,1380,1381,1385],{"class":96,"line":110},[94,1382,1384],{"class":1383},"shJU0","instructions",[94,1386,1387],{"class":100},":\n",[94,1389,1390],{"class":96,"line":116},[94,1391,1392],{"class":1373},"  # General guidelines\n",[94,1394,1395],{"class":96,"line":122},[94,1396,138],{"emptyLinePlaceholder":137},[94,1398,1399,1402,1405,1407],{"class":96,"line":128},[94,1400,1401],{"class":100},"  - ",[94,1403,1404],{"class":1383},"name",[94,1406,591],{"class":100},[94,1408,1409],{"class":320},"Code Review\n",[94,1411,1412,1415,1417],{"class":96,"line":134},[94,1413,1414],{"class":1383},"    instructions",[94,1416,591],{"class":100},[94,1418,1420],{"class":1419},"sD7c4","|\n",[94,1422,1423],{"class":96,"line":141},[94,1424,1425],{"class":320},"      1. Focus on correctness and performance\n",[94,1427,1428],{"class":96,"line":147},[94,1429,1430],{"class":320},"      2. Ensure code comments and documentation are clear and concise\n",[94,1432,1433],{"class":96,"line":153},[94,1434,1435],{"class":320},"      3. Be respectful and constructive in comments\n",[94,1437,1438],{"class":96,"line":158},[94,1439,138],{"emptyLinePlaceholder":137},[94,1441,1442,1444,1446,1448],{"class":96,"line":164},[94,1443,1401],{"class":100},[94,1445,1404],{"class":1383},[94,1447,591],{"class":100},[94,1449,1450],{"class":320},"CI/CD Configuration\n",[94,1452,1453,1456],{"class":96,"line":170},[94,1454,1455],{"class":1383},"    fileFilters",[94,1457,1387],{"class":100},[94,1459,1460,1463],{"class":96,"line":176},[94,1461,1462],{"class":100},"      - ",[94,1464,1465],{"class":320},"\".gitlab-ci.yml\"\n",[94,1467,1468,1470,1472],{"class":96,"line":182},[94,1469,1414],{"class":1383},[94,1471,591],{"class":100},[94,1473,1420],{"class":1419},[94,1475,1476],{"class":96,"line":187},[94,1477,1478],{"class":320},"      1. Do not use YAML anchors\n",[94,1480,1481],{"class":96,"line":193},[94,1482,1483],{"class":320},"      2. Always use rules in jobs, avoid using `only`\n",[94,1485,1486],{"class":96,"line":199},[94,1487,138],{"emptyLinePlaceholder":137},[94,1489,1490],{"class":96,"line":205},[94,1491,1492],{"class":1373},"  # Java style guide\n",[94,1494,1495],{"class":96,"line":210},[94,1496,138],{"emptyLinePlaceholder":137},[94,1498,1499,1501,1503,1505],{"class":96,"line":216},[94,1500,1401],{"class":100},[94,1502,1404],{"class":1383},[94,1504,591],{"class":100},[94,1506,1507],{"class":320},"Java Style Guide\n",[94,1509,1510,1512],{"class":96,"line":222},[94,1511,1455],{"class":1383},[94,1513,1387],{"class":100},[94,1515,1516,1518],{"class":96,"line":1110},[94,1517,1462],{"class":100},[94,1519,1520],{"class":320},"\"**/*.java\"\n",[94,1522,1523,1525,1527],{"class":96,"line":1127},[94,1524,1414],{"class":1383},[94,1526,591],{"class":100},[94,1528,1420],{"class":1419},[94,1530,1531],{"class":96,"line":1143},[94,1532,1533],{"class":320},"      1. Do not modernize Java 8 code to Java 11+ features, unless there is a GitLab issue or task specifically requesting modernization\n",[94,1535,1536],{"class":96,"line":1159},[94,1537,1538],{"class":320},"      2. All public classes must have Javadoc describing purpose and usage\n",[94,1540,1541],{"class":96,"line":1186},[94,1542,1543],{"class":320},"      3. All public methods must have Javadoc with @param and @return tags\n",[94,1545,1546],{"class":96,"line":1191},[94,1547,1548],{"class":320},"      4. Include code examples in main class Javadoc\n",[94,1550,1551],{"class":96,"line":1197},[94,1552,1553],{"class":320},"      5. All public methods must have at least one test case\n",[94,1555,1556],{"class":96,"line":1202},[94,1557,1558],{"class":320},"      6. Use httpbun.com for test endpoints (status codes, delays, JSON responses)\n",[12,1560,1561],{},"コードのモダナイズを進める過程で、Java 8の強制に関する最初のガイドラインは更新が必要になります。",[284,1563,1564],{"id":1564},"実証済みのワークフローをエージェントスキルにする",[12,1566,1567,1568,1573],{},"専門的なワークフローが繰り返し使えるようになったら、それを",[22,1569,1572],{"href":1570,"rel":1571},"https://docs.gitlab.com/user/duo_agent_platform/customize/agent_skills/",[],"エージェントスキル","として記録します。スキルはオンデマンドで読み込まれ、デフォルトではコンテキストウィンドウを占有しません。",[12,1575,1576,1577,1582],{},"エージェントスキルが、未検証の計画ではなく実証済みの実践を反映したものになるよう、まずは動作するCI/CD、テスト、レビュー済みの意思決定から始めましょう。モダナイズのエピックにおける",[22,1578,1581],{"href":1579,"rel":1580},"https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector/-/work_items/24",[],"イシュー24","は、このアプローチを、範囲を絞ったJava 21以降向けのモダナイズ用エージェントスキルとしてまとめています。これは、現在のマージリクエストを超えた価値をもたらします。今後のエージェントセッションは、過去の議論から再構築するのではなく、同じ安全境界を再利用できるのです。",[12,1584,1585,1586,1591],{},"既存の",[22,1587,1590],{"href":1588,"rel":1589},"https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector/-/blob/main/skills/java8-maven-maintenance/SKILL.md?ref_type=heads",[],"Java 8 Maven保守スキル","に着想を得た、以下のサンプルスキル実装を試してみてください。",[84,1593,1595],{"className":393,"code":1594,"language":395,"meta":89,"style":89},"---\nname: java21-modernization\ndescription: >-\n  Guide incremental Java 8 to Java 21+ modernization for the HTTP metrics\n  collector. Use when a GitLab work item asks for Java 21 CI visibility,\n  runtime/image upgrades, HttpClient migration, dependency or source API\n  modernization, or review of maint-java-21 style merge requests. Do not use\n  for routine Java 8 maintenance; prefer java8-maven-maintenance instead.\ncompatibility: Requires Maven, Docker Compose, and access to the owning GitLab work item.\n---\n\n# Java 21 Modernization\n\n## Overview\n\nModernize in small, reviewable steps. The owning work item is authoritative.\nPreserve collector → Rust metrics-store behavior unless the issue says otherwise.\n\nCompanion skill: `skills/java8-maven-maintenance/` for the Java 8 default path.\n\n## Before editing\n\n1. Read the owning issue/epic, `AGENTS.md`, `.gitlab-ci.yml`, `pom.xml`,\n   `Dockerfile`, and affected tests.\n2. Record the current baseline:\n   - `maven.compiler.source` / `target`\n   - default CI image vs any `*:java-21` jobs\n   - container base image\n   - observable CLI/Compose behavior\n3. Classify the change into **one** lane:\n   - CI visibility only\n   - runtime / image switch\n   - source / API modernization\n   - dependency upgrade\n   - tests / contract checks\n\nDo not combine lanes in one MR unless the work item explicitly requires it.\n\n## Workflow\n\nCopy and track:\n\n```text\nModernization progress:\n- [ ] Baseline recorded\n- [ ] Scoped to owning work item\n- [ ] Target-JDK CI evidence available before JDK-only APIs\n- [ ] Java 8 lane preserved until exit criteria say otherwise\n- [ ] Unit / IT / Compose checks run\n- [ ] MR documents risks, rollback, human decisions\n```\n\n## Guardrails\n\n- Do not remove Java 8 compatibility unless the work item authorizes it.\n- Do not introduce Java 21-only APIs before target-JDK CI evidence exists.\n- Do not mix runtime upgrades with unrelated refactors.\n- Do not claim performance wins without measurements.\n- Preserve the Java → Rust API and authentication contract.\n- Stop for a human decision when support policy, rollback, data format, or downstream compatibility is unclear.\n\n## Validation\n\n```bash\nmvn -Dmaven.repo.local=.m2/repository test\nmvn -Dmaven.repo.local=.m2/repository clean package\n```\n\nIf Compose or container files change:\n\n```bash\ndocker compose config --quiet\nTANUKI_INGESTION_TOKEN=replace-me docker compose up -d --build\n# confirm metric_sample logs and authenticated ingest still work\ndocker compose down -v\n```\n\n## Completion report\n\nIn the MR description, include:\n\n1. Baseline before the change\n2. Lane changed (CI / runtime / source / deps / tests)\n3. Evidence run (commands + CI jobs)\n4. Remaining risks and rollback\n5. Human decisions still open\n\n## Out of scope\n\n- Broad \"modernize everything to Java 21\" prompts\n- HTTP endpoint semantics unrelated to the JDK migration\n  (use `skills/http-endpoint-collector-behavior/`)\n- Security triage unrelated to the migration slice\n  (use `skills/security-triage-java-sensor/`)\n",[91,1596,1597,1602,1611,1621,1626,1631,1636,1641,1646,1656,1660,1664,1669,1673,1677,1681,1686,1691,1695,1706,1710,1715,1719,1742,1750,1758,1772,1785,1792,1799,1813,1820,1827,1834,1841,1848,1852,1857,1861,1866,1870,1875,1879,1884,1889,1894,1899,1905,1911,1917,1923,1929,1934,1940,1945,1953,1961,1969,1977,1985,1993,1998,2004,2009,2015,2027,2040,2045,2050,2056,2061,2066,2081,2107,2113,2126,2131,2136,2142,2147,2153,2158,2166,2174,2182,2191,2200,2205,2211,2216,2224,2232,2243,2251],{"__ignoreMap":89},[94,1598,1599],{"class":96,"line":97},[94,1600,1601],{"class":100},"---\n",[94,1603,1604,1606,1608],{"class":96,"line":104},[94,1605,1404],{"class":1383},[94,1607,591],{"class":100},[94,1609,1610],{"class":320},"java21-modernization\n",[94,1612,1613,1616,1618],{"class":96,"line":110},[94,1614,1615],{"class":1383},"description",[94,1617,591],{"class":100},[94,1619,1620],{"class":1419},">-\n",[94,1622,1623],{"class":96,"line":116},[94,1624,1625],{"class":320},"  Guide incremental Java 8 to Java 21+ modernization for the HTTP metrics\n",[94,1627,1628],{"class":96,"line":122},[94,1629,1630],{"class":320},"  collector. Use when a GitLab work item asks for Java 21 CI visibility,\n",[94,1632,1633],{"class":96,"line":128},[94,1634,1635],{"class":320},"  runtime/image upgrades, HttpClient migration, dependency or source API\n",[94,1637,1638],{"class":96,"line":134},[94,1639,1640],{"class":320},"  modernization, or review of maint-java-21 style merge requests. Do not use\n",[94,1642,1643],{"class":96,"line":141},[94,1644,1645],{"class":320},"  for routine Java 8 maintenance; prefer java8-maven-maintenance instead.\n",[94,1647,1648,1651,1653],{"class":96,"line":147},[94,1649,1650],{"class":1383},"compatibility",[94,1652,591],{"class":100},[94,1654,1655],{"class":320},"Requires Maven, Docker Compose, and access to the owning GitLab work item.\n",[94,1657,1658],{"class":96,"line":153},[94,1659,1601],{"class":100},[94,1661,1662],{"class":96,"line":158},[94,1663,138],{"emptyLinePlaceholder":137},[94,1665,1666],{"class":96,"line":164},[94,1667,1668],{"class":976},"# Java 21 Modernization\n",[94,1670,1671],{"class":96,"line":170},[94,1672,138],{"emptyLinePlaceholder":137},[94,1674,1675],{"class":96,"line":176},[94,1676,986],{"class":976},[94,1678,1679],{"class":96,"line":182},[94,1680,138],{"emptyLinePlaceholder":137},[94,1682,1683],{"class":96,"line":187},[94,1684,1685],{"class":100},"Modernize in small, reviewable steps. The owning work item is authoritative.\n",[94,1687,1688],{"class":96,"line":193},[94,1689,1690],{"class":100},"Preserve collector → Rust metrics-store behavior unless the issue says otherwise.\n",[94,1692,1693],{"class":96,"line":199},[94,1694,138],{"emptyLinePlaceholder":137},[94,1696,1697,1700,1703],{"class":96,"line":205},[94,1698,1699],{"class":100},"Companion skill: ",[94,1701,1702],{"class":329},"`skills/java8-maven-maintenance/`",[94,1704,1705],{"class":100}," for the Java 8 default path.\n",[94,1707,1708],{"class":96,"line":210},[94,1709,138],{"emptyLinePlaceholder":137},[94,1711,1712],{"class":96,"line":216},[94,1713,1714],{"class":976},"## Before editing\n",[94,1716,1717],{"class":96,"line":222},[94,1718,138],{"emptyLinePlaceholder":137},[94,1720,1721,1724,1727,1730,1732,1735,1737,1740],{"class":96,"line":1110},[94,1722,1723],{"class":1022},"1.",[94,1725,1726],{"class":100}," Read the owning issue/epic, ",[94,1728,1729],{"class":329},"`AGENTS.md`",[94,1731,1172],{"class":100},[94,1733,1734],{"class":329},"`.gitlab-ci.yml`",[94,1736,1172],{"class":100},[94,1738,1739],{"class":329},"`pom.xml`",[94,1741,597],{"class":100},[94,1743,1744,1747],{"class":96,"line":1127},[94,1745,1746],{"class":329},"   `Dockerfile`",[94,1748,1749],{"class":100},", and affected tests.\n",[94,1751,1752,1755],{"class":96,"line":1143},[94,1753,1754],{"class":1022},"2.",[94,1756,1757],{"class":100}," Record the current baseline:\n",[94,1759,1760,1763,1766,1769],{"class":96,"line":1159},[94,1761,1762],{"class":1022},"   -",[94,1764,1765],{"class":329}," `maven.compiler.source`",[94,1767,1768],{"class":100}," / ",[94,1770,1771],{"class":329},"`target`\n",[94,1773,1774,1776,1779,1782],{"class":96,"line":1186},[94,1775,1762],{"class":1022},[94,1777,1778],{"class":100}," default CI image vs any ",[94,1780,1781],{"class":329},"`*:java-21`",[94,1783,1784],{"class":100}," jobs\n",[94,1786,1787,1789],{"class":96,"line":1191},[94,1788,1762],{"class":1022},[94,1790,1791],{"class":100}," container base image\n",[94,1793,1794,1796],{"class":96,"line":1197},[94,1795,1762],{"class":1022},[94,1797,1798],{"class":100}," observable CLI/Compose behavior\n",[94,1800,1801,1804,1807,1810],{"class":96,"line":1202},[94,1802,1803],{"class":1022},"3.",[94,1805,1806],{"class":100}," Classify the change into ",[94,1808,1809],{"class":1115},"**one**",[94,1811,1812],{"class":100}," lane:\n",[94,1814,1815,1817],{"class":96,"line":1210},[94,1816,1762],{"class":1022},[94,1818,1819],{"class":100}," CI visibility only\n",[94,1821,1822,1824],{"class":96,"line":1224},[94,1823,1762],{"class":1022},[94,1825,1826],{"class":100}," runtime / image switch\n",[94,1828,1829,1831],{"class":96,"line":1235},[94,1830,1762],{"class":1022},[94,1832,1833],{"class":100}," source / API modernization\n",[94,1835,1836,1838],{"class":96,"line":1240},[94,1837,1762],{"class":1022},[94,1839,1840],{"class":100}," dependency upgrade\n",[94,1842,1843,1845],{"class":96,"line":1246},[94,1844,1762],{"class":1022},[94,1846,1847],{"class":100}," tests / contract checks\n",[94,1849,1850],{"class":96,"line":1251},[94,1851,138],{"emptyLinePlaceholder":137},[94,1853,1854],{"class":96,"line":1259},[94,1855,1856],{"class":100},"Do not combine lanes in one MR unless the work item explicitly requires it.\n",[94,1858,1859],{"class":96,"line":1267},[94,1860,138],{"emptyLinePlaceholder":137},[94,1862,1863],{"class":96,"line":1275},[94,1864,1865],{"class":976},"## Workflow\n",[94,1867,1868],{"class":96,"line":1283},[94,1869,138],{"emptyLinePlaceholder":137},[94,1871,1872],{"class":96,"line":1288},[94,1873,1874],{"class":100},"Copy and track:\n",[94,1876,1877],{"class":96,"line":1294},[94,1878,138],{"emptyLinePlaceholder":137},[94,1880,1881],{"class":96,"line":1299},[94,1882,1883],{"class":100},"```text\n",[94,1885,1886],{"class":96,"line":1313},[94,1887,1888],{"class":100},"Modernization progress:\n",[94,1890,1891],{"class":96,"line":1321},[94,1892,1893],{"class":100},"- [ ] Baseline recorded\n",[94,1895,1896],{"class":96,"line":1329},[94,1897,1898],{"class":100},"- [ ] Scoped to owning work item\n",[94,1900,1902],{"class":96,"line":1901},47,[94,1903,1904],{"class":100},"- [ ] Target-JDK CI evidence available before JDK-only APIs\n",[94,1906,1908],{"class":96,"line":1907},48,[94,1909,1910],{"class":100},"- [ ] Java 8 lane preserved until exit criteria say otherwise\n",[94,1912,1914],{"class":96,"line":1913},49,[94,1915,1916],{"class":100},"- [ ] Unit / IT / Compose checks run\n",[94,1918,1920],{"class":96,"line":1919},50,[94,1921,1922],{"class":100},"- [ ] MR documents risks, rollback, human decisions\n",[94,1924,1926],{"class":96,"line":1925},51,[94,1927,1928],{"class":100},"```\n",[94,1930,1932],{"class":96,"line":1931},52,[94,1933,138],{"emptyLinePlaceholder":137},[94,1935,1937],{"class":96,"line":1936},53,[94,1938,1939],{"class":976},"## Guardrails\n",[94,1941,1943],{"class":96,"line":1942},54,[94,1944,138],{"emptyLinePlaceholder":137},[94,1946,1948,1950],{"class":96,"line":1947},55,[94,1949,1023],{"class":1022},[94,1951,1952],{"class":100}," Do not remove Java 8 compatibility unless the work item authorizes it.\n",[94,1954,1956,1958],{"class":96,"line":1955},56,[94,1957,1023],{"class":1022},[94,1959,1960],{"class":100}," Do not introduce Java 21-only APIs before target-JDK CI evidence exists.\n",[94,1962,1964,1966],{"class":96,"line":1963},57,[94,1965,1023],{"class":1022},[94,1967,1968],{"class":100}," Do not mix runtime upgrades with unrelated refactors.\n",[94,1970,1972,1974],{"class":96,"line":1971},58,[94,1973,1023],{"class":1022},[94,1975,1976],{"class":100}," Do not claim performance wins without measurements.\n",[94,1978,1980,1982],{"class":96,"line":1979},59,[94,1981,1023],{"class":1022},[94,1983,1984],{"class":100}," Preserve the Java → Rust API and authentication contract.\n",[94,1986,1988,1990],{"class":96,"line":1987},60,[94,1989,1023],{"class":1022},[94,1991,1992],{"class":100}," Stop for a human decision when support policy, rollback, data format, or downstream compatibility is unclear.\n",[94,1994,1996],{"class":96,"line":1995},61,[94,1997,138],{"emptyLinePlaceholder":137},[94,1999,2001],{"class":96,"line":2000},62,[94,2002,2003],{"class":976},"## Validation\n",[94,2005,2007],{"class":96,"line":2006},63,[94,2008,138],{"emptyLinePlaceholder":137},[94,2010,2012],{"class":96,"line":2011},64,[94,2013,2014],{"class":100},"```bash\n",[94,2016,2018,2021,2024],{"class":96,"line":2017},65,[94,2019,2020],{"class":316},"mvn",[94,2022,2023],{"class":329}," -Dmaven.repo.local=.m2/repository",[94,2025,2026],{"class":320}," test\n",[94,2028,2030,2032,2034,2037],{"class":96,"line":2029},66,[94,2031,2020],{"class":316},[94,2033,2023],{"class":329},[94,2035,2036],{"class":320}," clean",[94,2038,2039],{"class":320}," package\n",[94,2041,2043],{"class":96,"line":2042},67,[94,2044,1928],{"class":100},[94,2046,2048],{"class":96,"line":2047},68,[94,2049,138],{"emptyLinePlaceholder":137},[94,2051,2053],{"class":96,"line":2052},69,[94,2054,2055],{"class":100},"If Compose or container files change:\n",[94,2057,2059],{"class":96,"line":2058},70,[94,2060,138],{"emptyLinePlaceholder":137},[94,2062,2064],{"class":96,"line":2063},71,[94,2065,2014],{"class":100},[94,2067,2069,2072,2075,2078],{"class":96,"line":2068},72,[94,2070,2071],{"class":316},"docker",[94,2073,2074],{"class":320}," compose",[94,2076,2077],{"class":320}," config",[94,2079,2080],{"class":329}," --quiet\n",[94,2082,2084,2087,2090,2093,2096,2098,2101,2104],{"class":96,"line":2083},73,[94,2085,2086],{"class":100},"TANUKI_INGESTION_TOKEN",[94,2088,2089],{"class":1419},"=",[94,2091,2092],{"class":320},"replace-me",[94,2094,2095],{"class":316}," docker",[94,2097,2074],{"class":320},[94,2099,2100],{"class":320}," up",[94,2102,2103],{"class":329}," -d",[94,2105,2106],{"class":329}," --build\n",[94,2108,2110],{"class":96,"line":2109},74,[94,2111,2112],{"class":1373},"# confirm metric_sample logs and authenticated ingest still work\n",[94,2114,2116,2118,2120,2123],{"class":96,"line":2115},75,[94,2117,2071],{"class":316},[94,2119,2074],{"class":320},[94,2121,2122],{"class":320}," down",[94,2124,2125],{"class":329}," -v\n",[94,2127,2129],{"class":96,"line":2128},76,[94,2130,1928],{"class":100},[94,2132,2134],{"class":96,"line":2133},77,[94,2135,138],{"emptyLinePlaceholder":137},[94,2137,2139],{"class":96,"line":2138},78,[94,2140,2141],{"class":976},"## Completion report\n",[94,2143,2145],{"class":96,"line":2144},79,[94,2146,138],{"emptyLinePlaceholder":137},[94,2148,2150],{"class":96,"line":2149},80,[94,2151,2152],{"class":100},"In the MR description, include:\n",[94,2154,2156],{"class":96,"line":2155},81,[94,2157,138],{"emptyLinePlaceholder":137},[94,2159,2161,2163],{"class":96,"line":2160},82,[94,2162,1723],{"class":1022},[94,2164,2165],{"class":100}," Baseline before the change\n",[94,2167,2169,2171],{"class":96,"line":2168},83,[94,2170,1754],{"class":1022},[94,2172,2173],{"class":100}," Lane changed (CI / runtime / source / deps / tests)\n",[94,2175,2177,2179],{"class":96,"line":2176},84,[94,2178,1803],{"class":1022},[94,2180,2181],{"class":100}," Evidence run (commands + CI jobs)\n",[94,2183,2185,2188],{"class":96,"line":2184},85,[94,2186,2187],{"class":1022},"4.",[94,2189,2190],{"class":100}," Remaining risks and rollback\n",[94,2192,2194,2197],{"class":96,"line":2193},86,[94,2195,2196],{"class":1022},"5.",[94,2198,2199],{"class":100}," Human decisions still open\n",[94,2201,2203],{"class":96,"line":2202},87,[94,2204,138],{"emptyLinePlaceholder":137},[94,2206,2208],{"class":96,"line":2207},88,[94,2209,2210],{"class":976},"## Out of scope\n",[94,2212,2214],{"class":96,"line":2213},89,[94,2215,138],{"emptyLinePlaceholder":137},[94,2217,2219,2221],{"class":96,"line":2218},90,[94,2220,1023],{"class":1022},[94,2222,2223],{"class":100}," Broad \"modernize everything to Java 21\" prompts\n",[94,2225,2227,2229],{"class":96,"line":2226},91,[94,2228,1023],{"class":1022},[94,2230,2231],{"class":100}," HTTP endpoint semantics unrelated to the JDK migration\n",[94,2233,2235,2238,2241],{"class":96,"line":2234},92,[94,2236,2237],{"class":100},"  (use ",[94,2239,2240],{"class":329},"`skills/http-endpoint-collector-behavior/`",[94,2242,1221],{"class":100},[94,2244,2246,2248],{"class":96,"line":2245},93,[94,2247,1023],{"class":1022},[94,2249,2250],{"class":100}," Security triage unrelated to the migration slice\n",[94,2252,2254,2256,2259],{"class":96,"line":2253},94,[94,2255,2237],{"class":100},[94,2257,2258],{"class":329},"`skills/security-triage-java-sensor/`",[94,2260,1221],{"class":100},[227,2262,2263],{"id":2263},"まとめ",[12,2265,2266,2267,2269,2270,2272],{},"このチュートリアルで紹介した3つのユースケースは、それぞれが積み重なっています。まずCursorは、リポジトリのコンテキストだけを使って、受け入れられていたエンドツーエンドテストの失敗を修正しました。次にGitLab MCPサーバーがモダナイズ計画を取り込み、Cursorは品質ゲートを整備しつつ、IDEから直接Duoのレビューフィードバックへの対応を完結させることができました。そして最後に、Cursorは",[91,2268,761],{},"を再利用可能な",[91,2271,809],{},"に置き換えるという、1つの範囲が限定されたJava 21の変更を行い、対象を絞ったテスト、サービス横断的な取り込みの実行、パイプライン、セキュリティスキャン、ソフトウェア部品表、レビューのエビデンス、影響分析によって裏付けました。",[12,2274,2275],{},"レガシーなJava 8のコードベースは、エージェントがコードを書いているからといって、モダナイズが安全になるわけではありません。安全になるのは、すべての変更が範囲を限定され、レビューされ、Java 8とJava 21の両方に対してテストされ、その背後にある意思決定とエビデンスとともに作業アイテムまで追跡できるからです。実装を担うのはCursorです。そして、その証明を担うのがGitLabです。両者が組み合わさることで、この移行はチームが信頼できるものになります。",[12,2277,2278],{},"このワークフローを試してみたい場合は、レガシーなアプリケーションで受け入れられている失敗を明らかにする1つのテストから始めてください。そのテストを信頼できるものにし、より大きなモダナイズ計画をGitLabに記録し、独立して変更・証明できる1つの境界を選びます。そうすることで、エージェントには焦点を絞ったタスクが、チームにはレビューできるエビデンスが与えられます。",[2280,2281,2282,2290,2299],"blockquote",{},[12,2283,2284,2285,2289],{},"もしまだGitLab Duo Agent Platformを利用していない場合は、",[22,2286,2288],{"href":24,"rel":2287},[],"無料トライアル","から始められます。",[12,2291,2292,2293,2298],{},"すでに無料プランでGitLabを利用している場合は、",[22,2294,2297],{"href":2295,"rel":2296},"https://docs.gitlab.com/subscriptions/gitlab_credits/#for-the-free-tier-on-gitlabcom",[],"簡単な手順","に沿って、GitLab Duo Agent Platformに申し込めます。",[12,2300,2301,2302,2307,2308,2313],{},"そして、すでにGitLab PremiumまたはUltimateをご利用中の場合は、",[22,2303,2306],{"href":2304,"rel":2305},"https://docs.gitlab.com/user/duo_agent_platform/turn_on_off/",[],"Duo Agent Platformを有効化","するだけで、サブスクリプションに",[22,2309,2312],{"href":2310,"rel":2311},"https://docs.gitlab.com/subscriptions/gitlab_credits/#included-credits",[],"含まれているGitLabクレジット","を使い始められます。",[2315,2316,2317],"style",{},"html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .surfw, html code.shiki .surfw{--shiki-default:#005CC5;--shiki-default-font-weight:bold}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html pre.shiki code .sbYKK, html code.shiki .sbYKK{--shiki-default:#24292E;--shiki-default-font-weight:bold}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}",{"title":89,"searchDepth":104,"depth":104,"links":2319},[2320,2323,2327,2331,2335,2340],{"id":229,"depth":104,"text":229,"children":2321},[2322],{"id":286,"depth":110,"text":287},{"id":362,"depth":104,"text":363,"children":2324},[2325,2326],{"id":386,"depth":110,"text":387},{"id":429,"depth":110,"text":429},{"id":483,"depth":104,"text":484,"children":2328},[2329,2330],{"id":499,"depth":110,"text":500},{"id":648,"depth":110,"text":649},{"id":755,"depth":104,"text":58,"children":2332},[2333,2334],{"id":813,"depth":110,"text":814},{"id":863,"depth":110,"text":864},{"id":885,"depth":104,"text":886,"children":2336},[2337,2338,2339],{"id":892,"depth":110,"text":892},{"id":942,"depth":110,"text":942},{"id":1564,"depth":110,"text":1564},{"id":2263,"depth":104,"text":2263},"ai","2026-07-22","このチュートリアルでは、的を絞ったテスト修正から始めて品質ゲートを整備し、開発ライフサイクルのコンテキスト、テスト結果、レビューのエビデンスを踏まえながらコードを変更していく流れを解説します。","md",null,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1776457632/llddiylsgwuze0u1rjks.png",{},"/ja-jp/blog/modernize-java-with-cursor-and-gitlab",{"config":2350,"title":5,"description":2343},{"noIndex":2351},false,"modernize-java-with-cursor-and-gitlab","ja-jp/blog/modernize-java-with-cursor-and-gitlab",[2355,2356,2357],"AI","product","tutorial","BlogPost","2026-07-23","NMfHOeK1KnkvyAFjfnd4Ly-txEPFOCerC0eUre7h688",{"logo":2362,"freeTrial":2367,"sales":2372,"login":2377,"items":2382,"search":2706,"minimal":2739,"duo":2756,"switchNav":2765,"pricingDeployment":2776},{"config":2363},{"href":2364,"dataGaName":2365,"dataGaLocation":2366},"/ja-jp/","gitlab logo","header",{"text":2368,"config":2369},"無料トライアルを開始",{"href":2370,"dataGaName":2371,"dataGaLocation":2366},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/ja-jp&glm_content=default-saas-trial/","free trial",{"text":2373,"config":2374},"デモをリクエスト",{"href":2375,"dataGaName":2376,"dataGaLocation":2366},"/ja-jp/sales/?contact-topic=request-demo","sales",{"text":2378,"config":2379},"サインイン",{"href":2380,"dataGaName":2381,"dataGaLocation":2366},"https://gitlab.com/users/sign_in/","sign in",[2383,2412,2514,2519,2628,2684],{"text":2384,"config":2385,"menu":2387},"プラットフォーム",{"dataNavLevelOne":2386},"platform",{"type":2388,"columns":2389},"cards",[2390,2396,2404],{"title":2384,"description":2391,"link":2392},"DevSecOpsに特化したインテリジェントオーケストレーションプラットフォーム",{"text":2393,"config":2394},"プラットフォームの詳細はこちら",{"href":2395,"dataGaName":2386,"dataGaLocation":2366},"/ja-jp/platform/",{"title":2397,"description":2398,"link":2399},"GitLab Duo Agent Platform","ソフトウェアライフサイクル全体を支えるエージェント型AI",{"text":2400,"config":2401},"GitLab Duoのご紹介",{"href":2402,"dataGaName":2403,"dataGaLocation":2366},"/ja-jp/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":2405,"description":2406,"link":2407},"GitLabが選ばれる理由","エンタープライズがGitLabを選ぶ主な理由をご覧ください",{"text":2408,"config":2409},"詳細はこちら",{"href":2410,"dataGaName":2411,"dataGaLocation":2366},"/ja-jp/why-gitlab/","why gitlab",{"text":2413,"left":137,"config":2414,"menu":2416},"製品",{"dataNavLevelOne":2415},"solutions",{"type":2417,"link":2418,"columns":2422,"feature":2493},"lists",{"text":2419,"config":2420},"すべてのソリューションを表示",{"href":2421,"dataGaName":2415,"dataGaLocation":2366},"/ja-jp/solutions/",[2423,2448,2471],{"title":2424,"description":2425,"link":2426,"items":2431},"自動化","CI/CDと自動化でデプロイを加速",{"config":2427},{"icon":2428,"href":2429,"dataGaName":2430,"dataGaLocation":2366},"AutomatedCodeAlt","/ja-jp/solutions/delivery-automation/","automated software delivery",[2432,2436,2439,2444],{"text":2433,"config":2434},"CI/CD",{"href":2435,"dataGaLocation":2366,"dataGaName":2433},"/ja-jp/solutions/continuous-integration/",{"text":2397,"config":2437},{"href":2402,"dataGaLocation":2366,"dataGaName":2438},"gitlab duo agent platform - product menu",{"text":2440,"config":2441},"ソースコード管理",{"href":2442,"dataGaLocation":2366,"dataGaName":2443},"/ja-jp/solutions/source-code-management/","Source Code Management",{"text":2445,"config":2446},"自動化されたソフトウェアデリバリー",{"href":2429,"dataGaLocation":2366,"dataGaName":2447},"Automated software delivery",{"title":2449,"description":2450,"link":2451,"items":2456},"セキュリティ","セキュリティを犠牲にすることなくコード作成を高速化",{"config":2452},{"href":2453,"dataGaName":2454,"dataGaLocation":2366,"icon":2455},"/ja-jp/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[2457,2461,2466],{"text":2458,"config":2459},"アプリケーションセキュリティテスト",{"href":2453,"dataGaName":2460,"dataGaLocation":2366},"Application security testing",{"text":2462,"config":2463},"ソフトウェアサプライチェーンセキュリティ",{"href":2464,"dataGaLocation":2366,"dataGaName":2465},"/ja-jp/solutions/supply-chain/","Software supply chain security",{"text":2467,"config":2468},"ソフトウェアコンプライアンス",{"href":2469,"dataGaName":2470,"dataGaLocation":2366},"/ja-jp/solutions/software-compliance/","software compliance",{"title":2472,"link":2473,"items":2478},"測定",{"config":2474},{"icon":2475,"href":2476,"dataGaName":2477,"dataGaLocation":2366},"DigitalTransformation","/ja-jp/solutions/visibility-measurement/","visibility and measurement",[2479,2483,2488],{"text":2480,"config":2481},"可視性と測定",{"href":2476,"dataGaLocation":2366,"dataGaName":2482},"Visibility and Measurement",{"text":2484,"config":2485},"バリューストリーム管理",{"href":2486,"dataGaLocation":2366,"dataGaName":2487},"/ja-jp/solutions/value-stream-management/","Value Stream Management",{"text":2489,"config":2490},"分析とインサイト",{"href":2491,"dataGaLocation":2366,"dataGaName":2492},"/ja-jp/solutions/analytics-and-insights/","Analytics and insights",{"title":2494,"type":2417,"items":2495},"GitLabが活躍する場所",[2496,2502,2508],{"text":2497,"config":2498},"大企業",{"icon":2499,"href":2500,"dataGaLocation":2366,"dataGaName":2501},"Building","/ja-jp/enterprise/","enterprise",{"text":2503,"config":2504},"スモールビジネス",{"icon":2505,"href":2506,"dataGaLocation":2366,"dataGaName":2507},"Work","/ja-jp/small-business/","small business",{"text":2509,"config":2510},"公共部門",{"icon":2511,"href":2512,"dataGaLocation":2366,"dataGaName":2513},"Organization","/ja-jp/solutions/public-sector/","public sector",{"text":2515,"config":2516},"価格",{"href":2517,"dataGaName":2518,"dataGaLocation":2366,"dataNavLevelOne":2518},"/ja-jp/pricing/","pricing",{"text":2520,"config":2521,"menu":2523},"関連リソース",{"dataNavLevelOne":2522},"resources",{"type":2417,"link":2524,"columns":2528,"feature":2617},{"text":2525,"config":2526},"すべてのリソースを表示",{"href":2527,"dataGaName":2522,"dataGaLocation":2366},"/ja-jp/resources/",[2529,2562,2584],{"title":2530,"items":2531},"はじめに",[2532,2537,2542,2547,2552,2557],{"text":2533,"config":2534},"インストール",{"href":2535,"dataGaName":2536,"dataGaLocation":2366},"/ja-jp/install/","install",{"text":2538,"config":2539},"クイックスタートガイド",{"href":2540,"dataGaName":2541,"dataGaLocation":2366},"/ja-jp/get-started/","quick setup checklists",{"text":2543,"config":2544},"学ぶ",{"href":2545,"dataGaLocation":2366,"dataGaName":2546},"https://university.gitlab.com/","learn",{"text":2548,"config":2549},"製品ドキュメント",{"href":2550,"dataGaName":2551,"dataGaLocation":2366},"https://docs.gitlab.com/ja-jp/","product documentation",{"text":2553,"config":2554},"ベストプラクティスビデオ",{"href":2555,"dataGaName":2556,"dataGaLocation":2366},"/ja-jp/getting-started-videos/","best practice videos",{"text":2558,"config":2559},"インテグレーション",{"href":2560,"dataGaName":2561,"dataGaLocation":2366},"/ja-jp/integrations/","integrations",{"title":2563,"items":2564},"検索する",[2565,2570,2575,2579],{"text":2566,"config":2567},"お客様成功事例",{"href":2568,"dataGaName":2569,"dataGaLocation":2366},"/ja-jp/customers/","customer success stories",{"text":2571,"config":2572},"ブログ",{"href":2573,"dataGaName":2574,"dataGaLocation":2366},"/ja-jp/blog/","blog",{"text":2576,"config":2577},"The Source",{"href":2578,"dataGaName":2574,"dataGaLocation":2366},"/ja-jp/the-source/",{"text":2580,"config":2581},"リモート",{"href":2582,"dataGaName":2583,"dataGaLocation":2366},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":2585,"items":2586},"つなげる",[2587,2592,2597,2602,2607,2612],{"text":2588,"config":2589},"GitLabサービス",{"href":2590,"dataGaName":2591,"dataGaLocation":2366},"/ja-jp/services/","services",{"text":2593,"config":2594},"コントリビュート",{"href":2595,"dataGaName":2596,"dataGaLocation":2366},"https://contributors.gitlab.com","contribute",{"text":2598,"config":2599},"コミュニティ",{"href":2600,"dataGaName":2601,"dataGaLocation":2366},"/community/","community",{"text":2603,"config":2604},"フォーラム",{"href":2605,"dataGaName":2606,"dataGaLocation":2366},"https://forum.gitlab.com/","forum",{"text":2608,"config":2609},"イベント",{"href":2610,"dataGaName":2611,"dataGaLocation":2366},"/events/","events",{"text":2613,"config":2614},"パートナー",{"href":2615,"dataGaName":2616,"dataGaLocation":2366},"/ja-jp/partners/","partners",{"config":2618,"title":2621,"text":2622,"link":2623},{"background":2619,"textColor":2620},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","GitLabの最新情報","最新の機能と改善点に関する情報をお届けします。",{"text":2624,"config":2625},"最新情報を読む",{"href":2626,"dataGaName":2627,"dataGaLocation":2366},"/ja-jp/whats-new/","whats new",{"text":2629,"config":2630,"menu":2632},"企業情報",{"dataNavLevelOne":2631},"company",{"type":2417,"columns":2633},[2634],{"items":2635},[2636,2641,2647,2649,2654,2659,2664,2669,2674,2679],{"text":2637,"config":2638},"GitLabについて",{"href":2639,"dataGaName":2640,"dataGaLocation":2366},"/ja-jp/company/","about",{"text":2642,"config":2643,"footerGa":2646},"採用情報",{"href":2644,"dataGaName":2645,"dataGaLocation":2366},"/jobs/","jobs",{"dataGaName":2645},{"text":2608,"config":2648},{"href":2610,"dataGaName":2611,"dataGaLocation":2366},{"text":2650,"config":2651},"経営陣",{"href":2652,"dataGaName":2653,"dataGaLocation":2366},"/company/team/e-group/","leadership",{"text":2655,"config":2656},"ハンドブック",{"href":2657,"dataGaName":2658,"dataGaLocation":2366},"https://handbook.gitlab.com/","handbook",{"text":2660,"config":2661},"投資家向け情報",{"href":2662,"dataGaName":2663,"dataGaLocation":2366},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":2665,"config":2666},"トラストセンター",{"href":2667,"dataGaName":2668,"dataGaLocation":2366},"/ja-jp/security/","trust center",{"text":2670,"config":2671},"AI Transparency Center",{"href":2672,"dataGaName":2673,"dataGaLocation":2366},"/ja-jp/ai-transparency-center/","ai transparency center",{"text":2675,"config":2676},"ニュースレター",{"href":2677,"dataGaName":2678,"dataGaLocation":2366},"/company/contact/#contact-forms","newsletter",{"text":2680,"config":2681},"プレス",{"href":2682,"dataGaName":2683,"dataGaLocation":2366},"/press/","press",{"text":2685,"config":2686,"menu":2687},"お問い合わせ",{"dataNavLevelOne":2631},{"type":2417,"columns":2688},[2689],{"items":2690},[2691,2696,2701],{"text":2692,"config":2693},"お問い合わせはこちら",{"href":2694,"dataGaName":2695,"dataGaLocation":2366},"/ja-jp/sales/","talk to sales",{"text":2697,"config":2698},"サポートを受ける",{"href":2699,"dataGaName":2700,"dataGaLocation":2366},"https://support.gitlab.com/hc/en-us","support portal",{"text":2702,"config":2703},"カスタマーポータル",{"href":2704,"dataGaName":2705,"dataGaLocation":2366},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":2707,"login":2708,"suggestions":2715},"閉じる",{"text":2709,"link":2710},"リポジトリとプロジェクトを検索するには、次にログインします",{"text":2711,"config":2712},"GitLab.com",{"href":2380,"dataGaName":2713,"dataGaLocation":2714},"search login","search",{"text":2716,"default":2717},"提案",[2718,2720,2725,2727,2731,2735],{"text":2397,"config":2719},{"href":2402,"dataGaName":2397,"dataGaLocation":2714},{"text":2721,"config":2722},"コード提案（AI）",{"href":2723,"dataGaName":2724,"dataGaLocation":2714},"/ja-jp/solutions/code-suggestions/","Code Suggestions (AI)",{"text":2433,"config":2726},{"href":2435,"dataGaName":2433,"dataGaLocation":2714},{"text":2728,"config":2729},"GitLab on AWS",{"href":2730,"dataGaName":2728,"dataGaLocation":2714},"/ja-jp/partners/technology-partners/aws/",{"text":2732,"config":2733},"GitLab on Google Cloud",{"href":2734,"dataGaName":2732,"dataGaLocation":2714},"/ja-jp/partners/technology-partners/google-cloud-platform/",{"text":2736,"config":2737},"GitLabを選ぶ理由",{"href":2410,"dataGaName":2738,"dataGaLocation":2714},"Why GitLab?",{"freeTrial":2740,"mobileIcon":2744,"desktopIcon":2749,"secondaryButton":2752},{"text":2368,"config":2741},{"href":2742,"dataGaName":2371,"dataGaLocation":2743},"https://gitlab.com/-/trials/new/","nav",{"altText":2745,"config":2746},"GitLabアイコン",{"src":2747,"dataGaName":2748,"dataGaLocation":2743},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":2745,"config":2750},{"src":2751,"dataGaName":2748,"dataGaLocation":2743},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":2530,"config":2753},{"href":2754,"dataGaName":2755,"dataGaLocation":2743},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/ja-jp/get-started/","get started",{"freeTrial":2757,"mobileIcon":2761,"desktopIcon":2763},{"text":2758,"config":2759},"GitLab Duoの詳細について",{"href":2402,"dataGaName":2760,"dataGaLocation":2743},"gitlab duo",{"altText":2745,"config":2762},{"src":2747,"dataGaName":2748,"dataGaLocation":2743},{"altText":2745,"config":2764},{"src":2751,"dataGaName":2748,"dataGaLocation":2743},{"button":2766,"mobileIcon":2771,"desktopIcon":2773},{"text":2767,"config":2768},"/switch",{"href":2769,"dataGaName":2770,"dataGaLocation":2743},"#contact","switch",{"altText":2745,"config":2772},{"src":2747,"dataGaName":2748,"dataGaLocation":2743},{"altText":2745,"config":2774},{"src":2775,"dataGaName":2748,"dataGaLocation":2743},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":2777,"mobileIcon":2782,"desktopIcon":2784},{"text":2778,"config":2779},"料金ページに戻る",{"href":2517,"dataGaName":2780,"dataGaLocation":2743,"icon":2781},"back to pricing","GoBack",{"altText":2745,"config":2783},{"src":2747,"dataGaName":2748,"dataGaLocation":2743},{"altText":2745,"config":2785},{"src":2751,"dataGaName":2748,"dataGaLocation":2743},{"title":2787,"button":2788,"config":2792},"GitLab Orbitが登場: AIエージェントのためのコンテキストレイヤー",{"text":2408,"config":2789},{"href":2790,"dataGaName":2791,"dataGaLocation":2366},"/ja-jp/gitlab-orbit/","orbit",{"layout":2793,"disabled":2351},"release",{"data":2795},{"text":2796,"source":2797,"edit":2803,"contribute":2808,"config":2813,"items":2818,"minimal":3027},"GitはSoftware Freedom Conservancyの商標です。当社は「GitLab」をライセンスに基づいて使用しています",{"text":2798,"config":2799},"ページのソースを表示",{"href":2800,"dataGaName":2801,"dataGaLocation":2802},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":2804,"config":2805},"このページを編集",{"href":2806,"dataGaName":2807,"dataGaLocation":2802},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":2809,"config":2810},"ご協力をお願いします",{"href":2811,"dataGaName":2812,"dataGaLocation":2802},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":2814,"facebook":2815,"youtube":2816,"linkedin":2817},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[2819,2864,2917,2960,2994],{"title":2515,"links":2820,"subMenu":2835},[2821,2825,2830],{"text":2822,"config":2823},"プランの表示",{"href":2517,"dataGaName":2824,"dataGaLocation":2802},"view plans",{"text":2826,"config":2827},"Premiumを選ぶ理由",{"href":2828,"dataGaName":2829,"dataGaLocation":2802},"/ja-jp/pricing/premium/","why premium",{"text":2831,"config":2832},"Ultimateを選ぶ理由",{"href":2833,"dataGaName":2834,"dataGaLocation":2802},"/ja-jp/pricing/ultimate/","why ultimate",[2836],{"title":2685,"links":2837},[2838,2840,2842,2844,2849,2854,2859],{"text":2685,"config":2839},{"href":2694,"dataGaName":2376,"dataGaLocation":2802},{"text":2697,"config":2841},{"href":2699,"dataGaName":2700,"dataGaLocation":2802},{"text":2702,"config":2843},{"href":2704,"dataGaName":2705,"dataGaLocation":2802},{"text":2845,"config":2846},"ステータス",{"href":2847,"dataGaName":2848,"dataGaLocation":2802},"https://status.gitlab.com/","status",{"text":2850,"config":2851},"利用規約",{"href":2852,"dataGaName":2853,"dataGaLocation":2802},"/terms/","terms of use",{"text":2855,"config":2856},"プライバシーに関する声明",{"href":2857,"dataGaName":2858,"dataGaLocation":2802},"/ja-jp/privacy/","privacy statement",{"text":2860,"config":2861},"Cookie 優先設定",{"dataGaName":2862,"dataGaLocation":2802,"id":2863,"isOneTrustButton":137},"cookie preferences","ot-sdk-btn",{"title":2413,"links":2865,"subMenu":2874},[2866,2870],{"text":2867,"config":2868},"DevSecOpsプラットフォーム",{"href":2395,"dataGaName":2869,"dataGaLocation":2802},"devsecops platform",{"text":2871,"config":2872},"AI支援開発",{"href":2402,"dataGaName":2873,"dataGaLocation":2802},"ai-assisted development",[2875],{"title":2876,"links":2877},"トピック",[2878,2882,2887,2892,2897,2902,2907,2912],{"text":2433,"config":2879},{"href":2880,"dataGaName":2881,"dataGaLocation":2802},"/ja-jp/topics/ci-cd/","cicd",{"text":2883,"config":2884},"GitOps",{"href":2885,"dataGaName":2886,"dataGaLocation":2802},"/ja-jp/topics/gitops/","gitops",{"text":2888,"config":2889},"DevOps",{"href":2890,"dataGaName":2891,"dataGaLocation":2802},"/ja-jp/topics/devops/","devops",{"text":2893,"config":2894},"バージョン管理",{"href":2895,"dataGaName":2896,"dataGaLocation":2802},"/ja-jp/topics/version-control/","version control",{"text":2898,"config":2899},"DevSecOps",{"href":2900,"dataGaName":2901,"dataGaLocation":2802},"/ja-jp/topics/devsecops/","devsecops",{"text":2903,"config":2904},"クラウドネイティブ",{"href":2905,"dataGaName":2906,"dataGaLocation":2802},"/ja-jp/topics/cloud-native/","cloud native",{"text":2908,"config":2909},"コーディングのためのAI",{"href":2910,"dataGaName":2911,"dataGaLocation":2802},"/ja-jp/topics/devops/ai-for-coding/","ai for coding",{"text":2913,"config":2914},"エージェント型AI",{"href":2915,"dataGaName":2916,"dataGaLocation":2802},"/ja-jp/topics/agentic-ai/","agentic ai",{"title":2918,"links":2919},"ソリューション",[2920,2923,2925,2930,2934,2937,2940,2943,2945,2947,2950,2955],{"text":2458,"config":2921},{"href":2453,"dataGaName":2922,"dataGaLocation":2802},"Application Security Testing",{"text":2445,"config":2924},{"href":2429,"dataGaName":2430,"dataGaLocation":2802},{"text":2926,"config":2927},"アジャイル開発",{"href":2928,"dataGaName":2929,"dataGaLocation":2802},"/ja-jp/solutions/agile-delivery/","agile delivery",{"text":2931,"config":2932},"SCM",{"href":2442,"dataGaName":2933,"dataGaLocation":2802},"source code management",{"text":2433,"config":2935},{"href":2435,"dataGaName":2936,"dataGaLocation":2802},"continuous integration & delivery",{"text":2484,"config":2938},{"href":2486,"dataGaName":2939,"dataGaLocation":2802},"value stream management",{"text":2883,"config":2941},{"href":2942,"dataGaName":2886,"dataGaLocation":2802},"/ja-jp/solutions/gitops/",{"text":2497,"config":2944},{"href":2500,"dataGaName":2501,"dataGaLocation":2802},{"text":2503,"config":2946},{"href":2506,"dataGaName":2507,"dataGaLocation":2802},{"text":2948,"config":2949},"公共機関",{"href":2512,"dataGaName":2513,"dataGaLocation":2802},{"text":2951,"config":2952},"教育",{"href":2953,"dataGaName":2954,"dataGaLocation":2802},"/ja-jp/solutions/education/","education",{"text":2956,"config":2957},"金融サービス",{"href":2958,"dataGaName":2959,"dataGaLocation":2802},"/ja-jp/solutions/finance/","financial services",{"title":2961,"links":2962},"リソース",[2963,2965,2967,2969,2973,2975,2978,2980,2982,2984,2986,2988,2990,2992],{"text":2533,"config":2964},{"href":2535,"dataGaName":2536,"dataGaLocation":2802},{"text":2538,"config":2966},{"href":2540,"dataGaName":2541,"dataGaLocation":2802},{"text":2543,"config":2968},{"href":2545,"dataGaName":2546,"dataGaLocation":2802},{"text":2548,"config":2970},{"href":2971,"dataGaName":2972,"dataGaLocation":2802},"https://docs.gitlab.com/ja-jp","docs",{"text":2571,"config":2974},{"href":2573,"dataGaName":2574,"dataGaLocation":2802},{"text":2976,"config":2977},"最新リリース",{"href":2626,"dataGaName":2627,"dataGaLocation":2802},{"text":2566,"config":2979},{"href":2568,"dataGaName":2569,"dataGaLocation":2802},{"text":2580,"config":2981},{"href":2582,"dataGaName":2583,"dataGaLocation":2802},{"text":2588,"config":2983},{"href":2590,"dataGaName":2591,"dataGaLocation":2802},{"text":2593,"config":2985},{"href":2595,"dataGaName":2596,"dataGaLocation":2802},{"text":2598,"config":2987},{"href":2600,"dataGaName":2601,"dataGaLocation":2802},{"text":2603,"config":2989},{"href":2605,"dataGaName":2606,"dataGaLocation":2802},{"text":2608,"config":2991},{"href":2610,"dataGaName":2611,"dataGaLocation":2802},{"text":2613,"config":2993},{"href":2615,"dataGaName":2616,"dataGaLocation":2802},{"title":2995,"links":2996},"会社情報",[2997,2999,3001,3003,3005,3007,3011,3016,3018,3020,3022],{"text":2637,"config":2998},{"href":2639,"dataGaName":2631,"dataGaLocation":2802},{"text":2642,"config":3000},{"href":2644,"dataGaName":2645,"dataGaLocation":2802},{"text":2650,"config":3002},{"href":2652,"dataGaName":2653,"dataGaLocation":2802},{"text":2655,"config":3004},{"href":2657,"dataGaName":2658,"dataGaLocation":2802},{"text":2660,"config":3006},{"href":2662,"dataGaName":2663,"dataGaLocation":2802},{"text":3008,"config":3009},"Sustainability",{"href":3010,"dataGaName":3008,"dataGaLocation":2802},"/sustainability/",{"text":3012,"config":3013},"ダイバーシティ、インクルージョン、ビロンギング（DIB）",{"href":3014,"dataGaName":3015,"dataGaLocation":2802},"/ja-jp/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":2665,"config":3017},{"href":2667,"dataGaName":2668,"dataGaLocation":2802},{"text":2675,"config":3019},{"href":2677,"dataGaName":2678,"dataGaLocation":2802},{"text":2680,"config":3021},{"href":2682,"dataGaName":2683,"dataGaLocation":2802},{"text":3023,"config":3024},"現代奴隷制の透明性に関する声明",{"href":3025,"dataGaName":3026,"dataGaLocation":2802},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":3028},[3029,3031,3034],{"text":2850,"config":3030},{"href":2852,"dataGaName":2853,"dataGaLocation":2802},{"text":3032,"config":3033},"Cookieの設定",{"dataGaName":2862,"dataGaLocation":2802,"id":2863,"isOneTrustButton":137},{"text":2855,"config":3035},{"href":2857,"dataGaName":2858,"dataGaLocation":2802},[3037],{"id":3038,"title":7,"body":2345,"config":3039,"content":3041,"description":2345,"extension":3045,"meta":3046,"navigation":137,"path":3047,"seo":3048,"stem":3049,"__hash__":3050},"blogAuthors/en-us/blog/authors/michael-friedrich.yml",{"template":3040},"BlogAuthor",{"name":7,"config":3042},{"headshot":3043,"ctfId":3044},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659879/Blog/Author%20Headshots/dnsmichi-headshot.jpg","dnsmichi","yml",{},"/en-us/blog/authors/michael-friedrich",{},"en-us/blog/authors/michael-friedrich","lJ-nfRIhdG49Arfrxdn1Vv4UppwD51BB13S3HwIswt4",[3052,3060,3068],{"title":3053,"description":3054,"heroImage":3055,"category":2341,"date":3056,"authors":3057,"slug":3059,"externalUrl":2345},"1,500人が挑んだGitLab Transcendハッカソン：開発者たちがGitLab Orbitで作ったもの","1,500人を超える開発者がGitLab Orbitを使ってAIエージェントやツールを構築しました。受賞プロジェクトと、ライブコードグラフが一度のクエリで答える問いをご紹介します。\n","https://res.cloudinary.com/about-gitlab-com/image/upload/v1780996524/sd1vpl8empy26wizarqj.png","2026-07-20",[3058],"Mattias Michaux","gitlab-transcend-hackathon-orbit",{"title":3061,"description":3062,"heroImage":3063,"category":2341,"date":3064,"authors":3065,"slug":3067,"externalUrl":2345},"複数ステップのソフトウェア開発を、信頼できるエージェント型フローに","GitLab Duo Agent Platformのカスタムフローが一般提供（GA）になりました。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1783980535/t3gez0gpayfndrhncunf.png","2026-07-16",[3066],"Ozer Dondurmacioglu","multi-step-software-delivery-with-agentic-flows",{"title":3069,"description":3070,"heroImage":3063,"category":2341,"date":3064,"authors":3071,"slug":3072,"externalUrl":2345},"GitLab Duo Agent Platformがターミナルに対応","GitLab 19.2でDuo CLIが一般提供開始。コード、パイプライン、複数ステップの作業も、シェルから離れずに完結できます。",[3066],"gitlab-duo-cli-generally-available",{"promotions":3074},[3075,3088,3099,3111],{"id":3076,"categories":3077,"header":3078,"text":3079,"button":3080,"image":3085},"ai-modernization",[2341],"AIの真価、組織全体で発揮できていますか？","所要時間は5分以内です",{"text":3081,"config":3082},"AI成熟度スコアを確認する",{"href":3083,"dataGaName":3084,"dataGaLocation":2574},"/ja-jp/assessments/ai-modernization-assessment/","modernization assessment",{"config":3086},{"src":3087},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":3089,"categories":3090,"header":3091,"text":3079,"button":3092,"image":3096},"devops-modernization",[2356,2901],"単にツールを管理するだけでなく、イノベーションを提供していますか？",{"text":3093,"config":3094},"DevOps成熟度スコアを確認しましょう",{"href":3095,"dataGaName":3084,"dataGaLocation":2574},"/ja-jp/assessments/devops-modernization-assessment/",{"config":3097},{"src":3098},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":3100,"categories":3101,"header":3103,"text":3079,"button":3104,"image":3108},"security-modernization",[3102],"security","スピードのためにセキュリティを犠牲にしていませんか？",{"text":3105,"config":3106},"セキュリティ成熟度スコアを確認しましょう",{"href":3107,"dataGaName":3084,"dataGaLocation":2574},"/ja-jp/assessments/security-modernization-assessment/",{"config":3109},{"src":3110},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":3112,"paths":3113,"header":3116,"text":3117,"button":3118,"image":3123},"github-azure-migration",[3114,3115],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","チームはGitHubのAzure移行に対応できていますか？","GitHubはすでにAzureを基盤として再構築を進めています。それがあなたのチームにとって何を意味するのか、ご確認ください。",{"text":3119,"config":3120},"GitLabとGitHubの比較を見る",{"href":3121,"dataGaName":3122,"dataGaLocation":2574},"/ja-jp/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":3124},{"src":3098},{"header":3126,"blurb":3127,"button":3128,"secondaryButton":3132},"今すぐ開発をスピードアップ","DevSecOpsに特化したインテリジェントオーケストレーションプラットフォームで実現できることをご確認ください。\n",{"text":2368,"config":3129},{"href":3130,"dataGaName":2371,"dataGaLocation":3131},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/ja-jp/","feature",{"text":2685,"config":3133},{"href":2694,"dataGaName":2376,"dataGaLocation":3131},1784826390574]