Veröffentlicht am: 22. Juli 2026

18 Minuten Lesezeit

Java mit Cursor und GitLab modernisieren

Dieses Tutorial beginnt mit einem gezielten Test-Fix, führt Quality-Gates ein und setzt Codeänderungen mit Lifecycle-Kontext, Tests und Review-Belegen um.

Warum Java-Modernisierung mehr als ein Task ist

"Java 8 auf Java 21 modernisieren" klingt nach einer einzigen Aufgabe, ist es aber nicht. Es betrifft den Build, die Runtime, Abhängigkeiten, APIs, Nebenläufigkeit, Tests, Container und das Produktionsverhalten, oft alles gleichzeitig. Wer einen Agenten bittet, das alles in einem einzigen Prompt zu erledigen, bekommt einen riesigen Merge Request, den niemand sicher reviewen kann.

Cursor, ein KI-Coding-Agent, ist im fokussierten Teil dieses Problems stark. Bekommt er einen einzelnen fehlschlagenden Test oder ein abgegrenztes Issue, kann er die Implementierung untersuchen, erklären, was schiefging, einen Fix vorschlagen und die Tests ausführen, ohne aus dem Entwicklungsfluss zu reißen. Was er nicht allein entscheiden kann, ist, was "sicher" über eine mehrstufige Migration hinweg bedeutet.

Genau hier kommt GitLab ins Spiel: Die Duo Agent Platform orchestriert KI-Workflows im übrigen Software-Lebenszyklus und ist darauf ausgelegt, die Arbeit von Coding-Agenten zu zertifizieren. Die Issue-Hierarchie mit Epics macht den Plan dauerhaft und reviewbar. Der GitLab-Model-Context-Protocol-Server (MCP) bringt den Kontext aus dem Entwicklungszyklus nach Cursor. CI/CD, Security-Scanning, Code-Review, Impact-Analyse und ein serviceübergreifender Test liefern die Belege, die es braucht, bevor sich das Produktionsverhalten ändert.

Der Nutzen steht damit fest: eine Migration, der ein Team vertrauen kann. Jede Änderung ist abgegrenzt, reviewt, gegen Java 8 und Java 21 getestet und bis zu einem Work Item mit den zugehörigen Entscheidungen und Belegen zurückverfolgbar. Cursor übernimmt die Implementierung, GitLab liefert den Nachweis. Eine bestehende Java-8-Codebasis wird nicht dadurch sicherer zu modernisieren, dass ein Agent den Code schreibt, sondern dadurch, dass jede Änderung abgegrenzt, reviewt, gegen beide Java-Versionen getestet und nachvollziehbar ist.

Angesprochen sind damit Teams, die auf einer bestehenden Java-8-Codebasis sitzen und agentisches Tempo nutzen wollen, ohne Governance, Review und Nachvollziehbarkeit aufzugeben. Cursor arbeitet schnell innerhalb einer abgegrenzten Aufgabe. Code Review Flow, Developer Flow, CI/CD, Code-Owner-Freigaben und Impact-Analyse sind das, was dieses Tempo sicher macht. Sie sind keine optionalen Kontrollpunkte, sondern der Mechanismus, der jeden von einem Agenten erzeugten Merge Request an denselben Maßstab hält wie jeden anderen.

Das Folgende ist die praktische Umsetzung: drei aufeinander aufbauende Use Cases, die zeigen, wie sich das Schritt für Schritt in Cursor und GitLab durchführen lässt.

  1. Einen fehlschlagenden End-to-End-Test mit Cursor beheben
  2. Quality-Gates zur Java-21-Modernisierung vorbereiten
  3. Das HTTP-Connection-Handling mit Java 21 modernisieren

Die Reihenfolge hat einen Grund: klein anfangen, Projektkontext ergänzen, dann eine Grenze modernisieren.

Die Demo-Umgebung aus Java-Collector und Rust-Backend

Für alle drei Use Cases nutzen wir den Java HTTP Metrics Collector aus der Tanuki IoT Platform. Er prüft HTTP-Endpunkte, erfasst Metriken wie Antwortstatus und Timing und schickt die Messwerte an sein Rust-Metrics-Backend. Das gibt uns eine sichtbare Anwendungsgrenze zum Modernisieren und einen echten Backend-Vertrag zum Verifizieren. Das Rust-Backend haben wir vor einiger Zeit im Tutorial zu Codex und GitLab entwickelt, und es fügt sich nun in die Produktionsarchitektur ein:

flowchart LR
  subgraph sources["HTTP metric sources"]
    direction TB
    health["Health endpoint"]
    maintenance["Maintenance endpoint"]
  end

  java["Java HTTP metrics collector"]
  rust[("Rust metrics-store backend")]

  java -->|"GET"| health
  java -->|"GET"| maintenance
  java -->|"POST /api/metrics"| rust
  rust -->|"HTTP response"| java

  classDef source fill:#f8fafc,stroke:#64748b,stroke-width:2px,color:#0f172a
  classDef focus fill:#dcfce7,stroke:#16a34a,stroke-width:3px,color:#0f172a
  classDef backend fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0f172a

  class health,maintenance source
  class java focus
  class rust backend

Voraussetzungen

  1. Cursor installiert und konfiguriert. In diesem Tutorial nutzen wir die Cursor-IDE.
  2. Ein GitLab-Projekt mit dem Quellcode des Java-Collectors, Issues und Modernisierungs-Work-Items. Nutzen lässt sich der Java HTTP Metrics Collector der Tanuki IoT Platform.
  3. Java 8 für den ersten Use Case und Java 21 für die Modernisierungsarbeit
  4. Maven, Docker und Docker Compose für lokale Builds und funktionale Tests
  5. Der GitLab-MCP-Server, aktiviert auf der GitLab-Instanz oder der Top-Level-Gruppe
  6. GitLab Duo Code Review Flow, Developer Flow und ein Custom Flow für die Impact-Analyse bei Breaking Changes (siehe Abschnitt "Tipps für Cursor und GitLab"), aktiviert für das Java-Collector-Projekt. Diese Flows wenden die Projekt-Guardrails auf jeden Merge Request an, den der Agent erstellt.

Das GitLab-Projekt vorbereiten

Um den Workflow in der eigenen Umgebung nachzuvollziehen, zunächst das Projekt importieren, klonen und in Cursor öffnen:

  1. Den Java HTTP Metrics Collector der Tanuki IoT Platform in die eigene GitLab-Umgebung importieren, samt aller offenen Issues.
  2. Das Projekt in die lokale Umgebung klonen und hineinwechseln.
  3. Das Projekt in Cursor öffnen.
      git clone https://gitlab.com/gitlab-da/demo-environments/tanuki-iot-platform/sensors/java-http-metrics-collector.git
cd java-http-metrics-collector

cursor .

    

Das Projekt enthält eine AGENTS.md-Datei mit Repository-Anweisungen und Maven-Befehlen. Cursor kann diese lokalen Anweisungen nutzen, um zu verstehen, wie das Projekt organisiert ist und wie Änderungen getestet werden sollen.

Der Java HTTP Metrics Collector in Cursor geöffnet, mit AGENTS.md-Anweisungen

Einen fehlschlagenden End-to-End-Test mit Cursor beheben

Der Collector erlaubt es, den von einem Endpunkt erwarteten HTTP-Statuscode zu konfigurieren. Die Implementierung behandelt jedoch jede 2xx-Antwort als erfolgreich, und 503-Fehler schlugen immer fehl, selbst wenn sie als erwartet konfiguriert waren.

Der End-to-End-Test legt diese Diskrepanz bereits offen, aber der CI/CD-Job darf fehlschlagen. Das hat aus einem nützlichen Signal hingenommenes Hintergrundrauschen gemacht.

Der fehlschlagende End-to-End-Test und sein auf "allowed to fail" gesetzter CI/CD-Job

Mit Cursor reproduzieren und beheben

Das Problem lässt sich lokal reproduzieren. Die Cursor-IDE mit einem neuen Chat öffnen und damit beginnen, das beobachtbare Problem direkt im Prompt zu beschreiben:

      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.

    

Cursor beginnt damit, die Endpunkt-Konfiguration in den HttpCollector und den fehlschlagenden End-to-End-Test zurückzuverfolgen, und identifiziert die Ursache.

Cursor analysiert das Problem und die Ursache

Nachdem die fokussierten Tests und die vollständige Maven-Testsuite durchlaufen, einen Branch und Merge Request erstellen. Der zuvor auf "allowed to fail" gesetzte End-to-End-Job kann verpflichtend werden, sobald er deterministisch und grün ist.

      Can you create a git branch and merge request?

    

Reviewen und mergen

Der Merge Request stößt automatisch CI/CD-Build und -Tests sowie Security-Scanning an.

Merge Request mit behobenen End-to-End-Tests

GitLab Duo Code Review reviewt die fokussierte Änderung anschließend anhand der Java-spezifischen Review-Anweisungen des Projekts.

Code-Review-Feedback

Wenn das Review ein konkretes Problem findet, adressieren wir es über den Developer Flow, bevor wir mergen. Das ist der Punkt: Der Code Review Flow stellt sicher, dass jeder von einem Agenten erzeugte Merge Request denselben Maßstab erfüllt wie jeder andere, unabhängig davon, wie schnell Cursor ihn erzeugt hat. Der Merge Request bleibt die Fläche für Zusammenarbeit und Entscheidung.

Developer Flow adressiert das Review-Feedback

Der Fix gibt uns eine Verhaltens-Baseline. Wir haben einen echten Bug korrigiert, ohne ihn mit einer Runtime-Migration zu vermischen, und die Tests schützen jetzt den Vertrag über den erwarteten Status während der folgenden Modernisierungsarbeit.

In diesem Video wird gezeigt, wie Cursor die erwarteten End-to-End-Tests untersucht und behebt:

Quality-Gates zur Java-21-Modernisierung vorbereiten

Der erste Fix kam allein mit Repository-Kontext aus. Die nächste Anforderung ist deutlich größer: den Collector von Java 8 auf Java 21 modernisieren.

Diese Arbeit hat bereits Planungskontext im Epic zur Java-Modernisierung: untergeordnete Work Items, Team-Diskussionen, Recherche mit Merge Requests, Pipeline-Historie, Abhängigkeiten und Security-Findings. Diese Details liegen nicht im lokalen Checkout. Statt sie alle in einen riesigen Prompt zu kopieren, lässt sich der GitLab-Kontext mit MCP nach Cursor bringen.

Den GitLab-MCP-Server in Cursor konfigurieren

Zunächst sicherstellen, dass der GitLab-MCP-Server auf der Instanz oder der Top-Level-Gruppe aktiviert ist. Cursor nutzt HTTP-Transport, um sich ohne zusätzliche Abhängigkeiten direkt zu verbinden.

Um Cursor mit dem GitLab-MCP-Server zu verbinden:

  1. In Cursor zu Settings > Cursor Settings > Tools & MCP gehen.
  2. Unter Installed MCP Servers die Option New MCP Server wählen.
  3. Die folgende Definition zum mcpServers-Schlüssel in der geöffneten mcp.json-Datei hinzufügen. Für GitLab.com <gitlab.example.com> durch gitlab.com ersetzen. Für GitLab Self-Managed oder Dedicated die eigene Instanz-URL verwenden.
      {
  "mcpServers": {
    "GitLab": {
      "type": "http",
      "url": "https://<gitlab.example.com>/api/v4/mcp"
    }
  }
}

    
  1. Die Datei speichern und warten, bis sich die OAuth-Autorisierungsseite im Browser öffnet. Öffnet sie sich nicht, Cursor schließen und neu starten.
  2. Die Autorisierungsanfrage im Browser prüfen und bestätigen.
  3. Zurück in Cursor die aufgelisteten Tools inspizieren.

Der GitLab-MCP-Server nach der OAuth-Autorisierung in Cursor verbunden

Jetzt lässt sich ein neuer Chat starten und eine Frage auf Basis der verfügbaren GitLab-MCP-Tools stellen.

Wenn Cursor sich bei GitLab MCP authentifiziert, handelt es mit der bestehenden GitLab-Identität. Es kann nur auf Projekte und Ressourcen zugreifen, auf die man ohnehin schon Zugriff hat. MCP bringt freigegebenen Kontext in die IDE. Es umgeht keine GitLab-Berechtigungen.

Die Umgebung für die Java-21-Modernisierung vorbereiten

Das Epic zur Modernisierung von Java 8 auf 21 bricht den nötigen Plan in kleinere Iterationen herunter, wobei jedes Artefakt und jede Änderung für sich testbar ist.

GitLab-Epic mit untergeordneten Issues

Der erste Schritt ist sicherzustellen, dass die CI/CD-Infrastruktur sowohl Java 8 als auch 21 parallel testet. Auch die Testabdeckung von Beginn an in jede Modernisierungsaufgabe hinein zu erhöhen, ist verpflichtend.

Die Cursor-IDE öffnen und den folgenden Prompt nutzen, um den Planungskontext abzurufen:

      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.

    

Nach dem Abschluss der Arbeit am Issue zur Sichtbarkeit des CI-Builds kann Cursor mit dem MCP-Tool create_workitem_note zusätzlich einen zusammenfassenden Kommentar in das Issue einfügen.

Cursor-Zusammenfassung mit Tool-Aufruf des GitLab-MCP-Servers

Der neue Merge Request stößt CI/CD-Pipelines an sowie den Code Review Flow, der Kommentare zum Development-Style-Guide hinterlässt, in denen Dokumentation eingefordert wird.

Code-Review-Feedback im Merge Request

Das Feedback lässt sich unmittelbar in der GitLab-Oberfläche adressieren, indem man den Service-Account des Developer Flow erwähnt.

      @duo-developer-<group-name> Can you help address the review feedback?

    

Dieser Prompt startet eine neue Hintergrund-Session, und wir können uns währenddessen auf andere Aufgaben konzentrieren. Alternativ lässt sich zurück in die Cursor-IDE wechseln und deren Chat bitten, das Review-Feedback im Merge Request zu adressieren.

Cursor-IDE-Prompt "There is review feedback in the MR - please help me fix it"

Cursor setzt die Änderungen um und fügt mit dem MCP-Tool create_merge_request_note Kommentare in die Merge-Request-Threads ein.

GitLab-Merge-Request mit adressierten Code-Review-Kommentaren

Die Änderung behält die temporäre Java-8-Baseline und ergänzt eine eigene Java-21-Build- und -Testvalidierung. Damit wird die Kompatibilität in der Pipeline sichtbar, bevor der Quellcode beginnt, Java-21-only-APIs zu nutzen. Sobald diese Quality-Gates existieren, ist jede weitere agentengetriebene Änderung reviewt, getestet und nachvollziehbar. Das ist derselbe Maßstab, den wir auf jeden anderen Merge Request anwenden, und er ist es, der es sicher macht, Cursor schnell arbeiten zu lassen.

In diesem Video wird gezeigt, wie Cursor GitLab MCP nutzt, um Quality-Gates vorzubereiten und Code-Review-Feedback zu adressieren:

Das HTTP-Connection-Handling mit Java 21 modernisieren

Der Java HTTP Metrics Collector nutzt derzeit die veraltete HttpURLConnection-API aus Java 8. Java 21 hat die HTTP-Bibliothek mit java.net.http.HttpClient modernisiert, aber das ist nicht bloß ein mechanisches Umbenennen. Redirects, eingeschränkte Header, Timeout-Geltungsbereich, Response-Bodies, Unterbrechung und Verbindungswiederverwendung können sich alle unterschiedlich verhalten. Deshalb liegt die Umsetzung in einem einzigen abgegrenzten Work Item: Replace HttpURLConnection with java.net.http.HttpClient. Setzen wir das in die Praxis um.

Die Cursor-IDE mit einem neuen Chat öffnen und um die Umsetzung der Änderungen bitten.

Hinweis: Für diesen Use Case wollen wir ein lokales Docker-Compose-Setup nutzen, um die Änderungen zu verifizieren. Wer das Verhalten nachvollziehen möchte, installiert Docker und Docker Compose, andernfalls den zweiten Prompt weglassen.

      We want to continue modernizing the app to Java 21 - use the same maint-java-21 branch, and start implementing issue 16.

Verify the changes locally using the docker compose setup, after making the changes.

    

Der GitLab-MCP-Server liefert den Issue-Kontext, die Akzeptanzkriterien, Abhängigkeiten und zugehörigen Diskussionen. Das erste Code-Modernisierungs-Issue bleibt bewusst synchron und begrenzt. Es ersetzt HttpURLConnection durch einen einzigen wiederverwendbaren HttpClient und fügt keine Virtual Threads hinzu, ändert nicht das Zeitmodell und behebt keine unabhängigen Abhängigkeiten. Das sind wertvolle Folgeschritte, aber sie zu kombinieren würde es erschweren, Verhaltensänderungen zu isolieren, zu reviewen und zurückzurollen.

Lokal umsetzen und verifizieren

Fokussierte lokale HTTP-Server-Tests decken Methoden, Header, erwartete und unerwartete Statuscodes, Redirects, Timeouts, Response-Metadaten, Verbindungsfehler und Unterbrechung ab.

Cursor führt lokale Maven-Tests aus

Der funktionale Test mit Docker Compose belegt anschließend, dass authentifizierte Messwerte weiterhin im rust-metrics-store-Backend ankommen.

Cursor führt lokal Docker Compose mit dem Rust-Backend aus

Falls die CI/CD-Pipelines nach den Änderungen fehlschlagen, lassen sich die GitLab-MCP-Server-Tools nutzen, um direkt in der Cursor-IDE zu inspizieren und zu beheben, ohne den Kontext zu wechseln.

Cursor-IDE mit Tool-Aufruf des GitLab-MCP-Servers zum Abrufen von CI/CD-Job-Logs

In der GitLab-Oberfläche lässt sich der Fix CI/CD Pipeline Flow nutzen oder der CI Expert Agent um Hilfe bitten.

CI/CD- und Review-Belege

GitLab CI/CD, GitLab Duo Code Review, Security-Scanning und KI-gestützte Impact-Analyse liefern die abschließenden Belege im Merge Request. Menschliches Review zählt an den subtilen Grenzen weiterhin am meisten: Jeder beabsichtigte Verhaltensunterschied sollte im Merge Request explizit sein, nicht erst nach dem Deployment entdeckt werden.

Developer Flow mit Impact-Analyse

In diesem Video wird gezeigt, wie Cursor und GitLab die HTTP-Bibliothek des Collectors auf Java 21 modernisieren:

Tipps für Cursor und GitLab

Hier einige Tipps, um Cursor und GitLab zusammen zu nutzen.

Impact-Analyse für Breaking Changes bei der Modernisierung automatisieren

Der dritte Use Case zeigt den Developer Flow bei einer Impact-Analyse für Breaking Changes. Dieser Workflow lässt sich in einen automatisierten Custom Flow überführen, der ausgelöst wird, sobald ein Merge Request bereit ist oder die Pipeline in Ordnung ist. Zusätzlicher Kontext lässt sich aus GitLab Orbit abrufen, das einen Kontextgraphen über Code, Work Items, Merge Requests, Schwachstellen und mehr bereitstellt.

Der Beispiel-Flow lässt sich im AI Catalog inspizieren: MR Impact analysis (Orbit). Dank an meine Kollegin Fatima Sarah Kalid für die Inspiration. Custom Flows sind allgemein verfügbar in GitLab 19.2.

Custom Flow im AI Catalog

Merge-Request-Impact-Analyse mit einem Custom Flow in der GitLab Duo Agent Platform und Orbit

Richtlinien und Grenzen für Agenten dokumentieren

AGENTS.md für Java

Eine AGENTS.md-Datei hilft Cursor und anderen Coding-Agenten, die Projektarchitektur, Befehle, den Code-Stil, Testerwartungen und Grenzen zu verstehen. Diese Anweisungen nah am Code halten und konkret genug, um sie zu verifizieren.

Beispiel aus der AGENTS.md im Java-HTTP-Metrics-Collector-Projekt.

      # Java HTTP Metrics Collector - Agent Instructions

## Overview

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.

## Code Style and Standards

### Java 8 Compatibility

- Do not modernize Java 8 code to Java 11+ features unless there is a GitLab issue or task specifically requesting modernization
- Target Java 8 for source and compilation: `maven.compiler.source=1.8` and `maven.compiler.target=1.8`
- Use Java 8 compatible patterns (e.g., anonymous inner classes instead of lambdas where appropriate)

### Documentation

- All public classes must have Javadoc describing purpose and usage
- All public methods must have Javadoc with `@param` and `@return` tags
- Include code examples in main class Javadoc

### Class Organization

- **Main entry point**: `HttpMetricsCollector` - orchestrates configuration loading, metric collection, and export
- **Collector**: `HttpCollector` - performs HTTP requests and collects metrics
- **Exporter**: `PrometheusExporter` - exports metrics in Prometheus text format
- **Models**: `CollectorConfig`, `EndpointConfig`, `HttpMetric` - data transfer objects

### Dependency Management

- Always use Maven for dependency management
- Use property-based version management for dependencies (e.g., `${jackson.version}`)
- Keep dependencies up-to-date in `pom.xml`

### Error Handling

- Use try-catch blocks with proper resource management (try-with-resources where applicable)
- Log errors using SLF4J Logger
- Gracefully handle configuration loading failures
- Implement proper shutdown hooks for resource cleanup

### Concurrency

- Use `ExecutorService` for concurrent HTTP requests
- Thread pool size is limited to the minimum of endpoint count and 10
- Properly shutdown executor service with timeout handling
- Use `Future` objects to collect results from concurrent tasks

    

Code-Review-Anweisungen für Java

Der GitLab Duo Code Review Flow hilft, Style-Guides und Grenzen einzuhalten. Er erwartet spezifische Anweisungen in der Datei .gitlab/duo/mr-review-instructions.yaml, zum Beispiel für Java:

      # Custom instructions for GitLab Duo Code Review

instructions:
  # General guidelines

  - name: Code Review
    instructions: |
      1. Focus on correctness and performance
      2. Ensure code comments and documentation are clear and concise
      3. Be respectful and constructive in comments

  - name: CI/CD Configuration
    fileFilters:
      - ".gitlab-ci.yml"
    instructions: |
      1. Do not use YAML anchors
      2. Always use rules in jobs, avoid using `only`

  # Java style guide

  - name: Java Style Guide
    fileFilters:
      - "**/*.java"
    instructions: |
      1. Do not modernize Java 8 code to Java 11+ features, unless there is a GitLab issue or task specifically requesting modernization
      2. All public classes must have Javadoc describing purpose and usage
      3. All public methods must have Javadoc with @param and @return tags
      4. Include code examples in main class Javadoc
      5. All public methods must have at least one test case
      6. Use httpbun.com for test endpoints (status codes, delays, JSON responses)

    

Im Zuge der Code-Modernisierung wird die erste Richtlinie mit der Java-8-Durchsetzung aktualisiert werden müssen.

Einen bewährten Workflow in eine agentische Skill überführen

Wenn ein spezialisierter Workflow wiederholbar wird, lässt er sich in einer agentischen Skill festhalten. Skills werden bei Bedarf geladen und belegen das Kontextfenster nicht standardmäßig.

Mit funktionierendem CI/CD, Tests und reviewten Entscheidungen beginnen, damit die agentische Skill bewährte Praxis widerspiegelt und keinen ungetesteten Plan. Issue 24 im Modernisierungs-Epic hält den Ansatz in einer fokussierten agentischen Skill für die Java-21+-Modernisierung fest. Das schafft Mehrwert über den aktuellen Merge Request hinaus: Künftige Agenten-Sessions können dieselben Sicherheitsgrenzen wiederverwenden, statt sie aus früheren Diskussionen zu rekonstruieren.

Diese Beispiel-Implementierung einer Skill lässt sich ausprobieren, inspiriert von der bestehenden Java-8-Maven-Maintenance-Skill:

      ---
name: java21-modernization
description: >-
  Guide incremental Java 8 to Java 21+ modernization for the HTTP metrics
  collector. Use when a GitLab work item asks for Java 21 CI visibility,
  runtime/image upgrades, HttpClient migration, dependency or source API
  modernization, or review of maint-java-21 style merge requests. Do not use
  for routine Java 8 maintenance; prefer java8-maven-maintenance instead.
compatibility: Requires Maven, Docker Compose, and access to the owning GitLab work item.
---

# Java 21 Modernization

## Overview

Modernize in small, reviewable steps. The owning work item is authoritative.
Preserve collector → Rust metrics-store behavior unless the issue says otherwise.

Companion skill: `skills/java8-maven-maintenance/` for the Java 8 default path.

## Before editing

1. Read the owning issue/epic, `AGENTS.md`, `.gitlab-ci.yml`, `pom.xml`,
   `Dockerfile`, and affected tests.
2. Record the current baseline:
   - `maven.compiler.source` / `target`
   - default CI image vs any `*:java-21` jobs
   - container base image
   - observable CLI/Compose behavior
3. Classify the change into **one** lane:
   - CI visibility only
   - runtime / image switch
   - source / API modernization
   - dependency upgrade
   - tests / contract checks

Do not combine lanes in one MR unless the work item explicitly requires it.

## Workflow

Copy and track:

```text
Modernization progress:
- [ ] Baseline recorded
- [ ] Scoped to owning work item
- [ ] Target-JDK CI evidence available before JDK-only APIs
- [ ] Java 8 lane preserved until exit criteria say otherwise
- [ ] Unit / IT / Compose checks run
- [ ] MR documents risks, rollback, human decisions
```

## Guardrails

- Do not remove Java 8 compatibility unless the work item authorizes it.
- Do not introduce Java 21-only APIs before target-JDK CI evidence exists.
- Do not mix runtime upgrades with unrelated refactors.
- Do not claim performance wins without measurements.
- Preserve the Java → Rust API and authentication contract.
- Stop for a human decision when support policy, rollback, data format, or downstream compatibility is unclear.

## Validation

```bash
mvn -Dmaven.repo.local=.m2/repository test
mvn -Dmaven.repo.local=.m2/repository clean package
```

If Compose or container files change:

```bash
docker compose config --quiet
TANUKI_INGESTION_TOKEN=replace-me docker compose up -d --build
# confirm metric_sample logs and authenticated ingest still work
docker compose down -v
```

## Completion report

In the MR description, include:

1. Baseline before the change
2. Lane changed (CI / runtime / source / deps / tests)
3. Evidence run (commands + CI jobs)
4. Remaining risks and rollback
5. Human decisions still open

## Out of scope

- Broad "modernize everything to Java 21" prompts
- HTTP endpoint semantics unrelated to the JDK migration
  (use `skills/http-endpoint-collector-behavior/`)
- Security triage unrelated to the migration slice
  (use `skills/security-triage-java-sensor/`)

    

Fazit

Die drei Use Cases in diesem Tutorial bauen aufeinander auf. Cursor hat allein mit Repository-Kontext einen hingenommenen End-to-End-Testfehler behoben. Dann brachte der GitLab-MCP-Server den Modernisierungsplan herein, sodass Cursor Quality-Gates einziehen und die Schleife beim Duo-Review-Feedback direkt aus der IDE schließen konnte. Schließlich nahm Cursor eine einzige abgegrenzte Java-21-Änderung vor und ersetzte HttpURLConnection durch einen wiederverwendbaren HttpClient, abgesichert durch fokussierte Tests, serviceübergreifende Ingestion-Läufe, Pipeline, Security-Scans, eine Software Bill of Materials, Review-Belege und Impact-Analyse.

Eine Legacy-Java-8-Codebasis wird nicht dadurch sicherer zu modernisieren, dass ein Agent den Code schreibt. Sie wird sicherer, weil jede Änderung abgegrenzt, reviewt, gegen Java 8 und Java 21 getestet und bis zu einem Work Item mit den Entscheidungen und Belegen dahinter nachvollziehbar ist. Cursor übernimmt die Implementierung. GitLab liefert den Nachweis. Zusammen machen sie die Migration zu etwas, dem ein Team vertrauen kann.

Wer diesen Workflow ausprobieren möchte, beginnt mit einem Test, der einen hingenommenen Fehler in einer Legacy-Anwendung offenlegt. Diesen Test verlässlich machen, den größeren Modernisierungsplan in GitLab festhalten und eine Grenze wählen, die sich unabhängig ändern und belegen lässt. Das gibt dem Agenten eine fokussierte Aufgabe und dem Team Belege, die es reviewen kann.

Wer die GitLab Duo Agent Platform heute noch nicht nutzt, kann mit einer kostenlosen Testversion beginnen.

Wer GitLab bereits im Free-Tier nutzt, kann sich für die GitLab Duo Agent Platform anmelden, indem er einigen wenigen Schritten folgt.

Und wer bereits GitLab Premium oder Ultimate abonniert hat, kann direkt loslegen, indem er die Duo Agent Platform aktiviert und die enthaltenen GitLab Credits aus dem Abonnement nutzt.

Feedback erwünscht

Hat dir dieser Blogbeitrag gefallen? Hast du Fragen oder Feedback? Erstelle ein neues Diskussionsthema im GitLab-Community-Forum und lass andere an deinen Eindrücken teilhaben.

Feedback teilen

Beginne noch heute, schneller zu entwickeln

Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.