Skip to content

Commit a73e166

Browse files
bedaHovorkaclaude
andcommitted
Migrate from Java 11 to Java 21 LTS with dependency updates and Docker optimization
This migration upgrades the project to Java 21 LTS while maintaining backward compatibility with the jDisco library (Java 6). The primary motivation was to resolve deprecated Observable/Observer APIs that were blocking future Java version upgrades. Key changes: **API Modernization:** - Replace deprecated java.util.Observable/Observer with PropertyChangeSupport - Add ContextChangeListener interface extending PropertyChangeListener - Refactor DefaultContext, StatusBar, RailwayNetGridCanvas to use new pattern - Add 6 PropertyChangeTest unit tests (242 tests total, all passing) **Dependency Updates:** - Java: 11 → 21 LTS - JUnit: 5.10.1 → 5.11.4 - AssertJ: 3.24.2 → 3.27.6 (required for Java 21) - Mockito: 5.7.0 → 5.21.0 - SLF4J: 2.0.9 → 2.0.17 - Logback: 1.4.11 → 1.5.23 - Gradle: 8.5 → 8.12 - Shadow Plugin: 8.1.1 → 8.3.8 (plugin ID changed to com.gradleup.shadow) **Docker Optimization:** - Replace Debian Buster + manual Java install with Eclipse Temurin official images - Use eclipse-temurin:21-jdk for builder stage - Use eclipse-temurin:21-jre for runtime stage - Simplify Dockerfile, improve maintainability **CI/CD Updates:** - Rename .github/workflows/ant-java11.yml → gradle-java21.yml - Update JAVA_VERSION environment variable to '21' - Update build badges and references **Documentation:** - Update CLAUDE.md with Java 21 requirements and dependencies - Update README.md with current build system and Docker setup - Add JAVA21-MIGRATION-SUMMARY.md with comprehensive migration details All 242 tests pass with Java 21 (236 existing + 6 new PropertyChange tests). Docker build and runtime verified successfully. GUI functionality confirmed working with X11 forwarding. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent cf91c0c commit a73e166

19 files changed

Lines changed: 1050 additions & 275 deletions
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Gradle Build with Java 11
1+
name: Gradle Build with Java 21
22

33
on:
44
push:
@@ -16,7 +16,7 @@ concurrency:
1616
cancel-in-progress: true
1717

1818
env:
19-
JAVA_VERSION: '11'
19+
JAVA_VERSION: '21'
2020
MAVEN_OPTS: '-Xmx512m'
2121
GRADLE_OPTS: '-Xmx512m -XX:MaxMetaspaceSize=512m'
2222

.github/workflows/sonarqube.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ concurrency:
1717
cancel-in-progress: true
1818

1919
env:
20-
JAVA_VERSION: '11'
20+
JAVA_VERSION: '21'
2121
MAVEN_OPTS: '-Xmx512m'
2222
GRADLE_OPTS: '-Xmx512m -XX:MaxMetaspaceSize=512m'
2323

CLAUDE.md

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,26 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66

77
Railway Interlocking Simulator - A BSc thesis project (2006/2007) from Brno University of Technology that simulates railway interlocking systems with a graphical editor and discrete event simulation engine.
88

9-
[![Gradle Build with Java 11](https://github.com/bedavs/interlockSim/actions/workflows/ant-java11.yml/badge.svg)](https://github.com/bedavs/interlockSim/actions/workflows/ant-java11.yml)
9+
[![Gradle Build with Java 21](https://github.com/bedavs/interlockSim/actions/workflows/gradle-java21.yml/badge.svg)](https://github.com/bedavs/interlockSim/actions/workflows/gradle-java21.yml)
1010
[![SonarQube Analysis](https://github.com/bedavs/interlockSim/actions/workflows/sonarqube.yml/badge.svg)](https://github.com/bedavs/interlockSim/actions/workflows/sonarqube.yml)
1111

1212
## Build System
1313

14-
This project uses Gradle with Kotlin DSL for building. Java 11 bytecode compatibility is maintained (can be built with Java 11+). The jDisco library module remains at Java 6 for compatibility and uses Maven.
14+
This project uses Gradle with Kotlin DSL for building. Java 21 LTS is the minimum required version. The jDisco library module remains at Java 6 for compatibility and uses Maven.
1515

16-
**Migration Note**: Migrated from Apache Ant + Ivy to Gradle in January 2026. Gradle can be launched locally for development and builds. The previous Ant build system has been completely removed.
16+
**Migration Notes**:
17+
- Migrated from Apache Ant + Ivy to Gradle in January 2026
18+
- Migrated from Java 11 to Java 21 LTS in January 2026
19+
- Refactored deprecated Observable/Observer to PropertyChangeSupport
1720

1821
### Dependency Management
1922

2023
Dependencies are managed via Gradle:
2124
- **jDisco 1.2.0** - Discrete event simulation library (from Maven local repository, Java 6)
22-
- **JUnit 5.10.1** - Testing framework (JUnit Jupiter API and Engine)
23-
- **AssertJ 3.24.2** - Fluent assertion library for better test readability
24-
- **Mockito 5.7.0** - Mocking framework
25+
- **JUnit 5.11.4** - Testing framework (JUnit Jupiter API and Engine)
26+
- **AssertJ 3.27.6** - Fluent assertion library for better test readability
27+
- **Mockito 5.21.0** - Mocking framework
28+
- **SLF4J 2.0.17** + **Logback 1.5.23** - Logging framework
2529

2630
Gradle automatically downloads dependencies during the build. Configuration files:
2731
- `build.gradle.kts` - Build configuration and dependency declarations
@@ -131,7 +135,7 @@ java -ea -jar build/libs/interlockSim.jar example
131135

132136
**Dockerization: 2025** - Complete containerized build and runtime environment with no host dependencies.
133137

134-
The project includes Docker support for both the Java application and LaTeX thesis compilation. This eliminates the need to install Java 11, Ant, or LaTeX tools on the host machine.
138+
The project includes Docker support for both the Java application and LaTeX thesis compilation. This eliminates the need to install Java 21, Gradle, or LaTeX tools on the host machine.
135139

136140
### Prerequisites
137141

@@ -191,13 +195,13 @@ docker compose build app
191195
### Docker Architecture
192196

193197
**Root Dockerfile (multi-stage build):**
194-
1. **Builder stage** - Uses Debian Buster with OpenJDK 11, Maven, and Ant
198+
1. **Builder stage** - Uses Eclipse Temurin 21 JDK
195199
- Builds jDisco dependency (Maven install, Java 6 compatibility)
196-
- Resolves dependencies via Apache Ivy (automatic download)
197-
- Compiles Java sources (Java 11 target)
200+
- Resolves dependencies via Gradle (automatic download)
201+
- Compiles Java sources (Java 21 target)
198202
- Runs all tests with JUnit 5 (build fails if tests fail)
199203
- Creates uber JAR with all dependencies
200-
2. **Runner stage** - Debian Buster with OpenJDK 11 JRE and X11 libraries
204+
2. **Runner stage** - Eclipse Temurin 21 JRE and X11 libraries
201205
- Minimal runtime environment
202206
- X11 forwarding for GUI support
203207
- No build tools in final image
@@ -350,19 +354,19 @@ Follows `.editorconfig` configuration:
350354
1. **Do not touch Java code unless explicitly requested** - Do not refactor, optimize, or "improve" code that is working
351355
2. **Tests must exist before modifications** - Any Java source file being modified MUST be covered by tests first. If tests don't exist, they must be written before making any changes
352356
3. **Minimal changes only** - Make only the specific changes requested, nothing more
353-
4. **No unsolicited modernization** - While the project now uses Java 11, do not update Java idioms to modern features, do not add new language features, do not restructure working code
357+
4. **No unsolicited modernization** - While the project now uses Java 21, do not update Java idioms to modern features, do not add new language features, do not restructure working code
354358
5. **jDisco preservation** - The jDisco module must remain at Java 6 compatibility and should never be modified
355359

356360
This is a working historical codebase from 2007. Stability and preservation are more important than modernization.
357361

358362
## Testing
359363

360-
Comprehensive JUnit 5.10.1 test suite with AssertJ assertions located in `src/test/java/cz/vutbr/fit/interlockSim/`. All dependencies are managed via Apache Ivy.
364+
Comprehensive JUnit 5.11.4 test suite with AssertJ assertions located in `src/test/java/cz/vutbr/fit/interlockSim/`. All dependencies are managed via Gradle.
361365

362366
**Test framework:**
363367
- JUnit 5 (Jupiter API and Engine)
364368
- JUnit Platform for test execution
365-
- AssertJ 3.24.2 for fluent assertions
369+
- AssertJ 3.27.6 for fluent assertions
366370

367371
**Test organization:**
368372
- **Unit tests** - Fast tests that run by default with `./gradlew test` (excludes integration tests)
@@ -554,16 +558,16 @@ See `.github/workflows/sonarqube.yml` for automated SonarQube analysis on every
554558

555559
The project uses GitHub Actions for automated build, test, and deployment workflows.
556560

557-
**Workflow:** `.github/workflows/ant-java11.yml`
561+
**Workflow:** `.github/workflows/gradle-java21.yml`
558562

559563
**Features:**
560564
- Builds jDisco library with Java 6 compatibility
561-
- Compiles main project with Java 11
565+
- Compiles main project with Java 21
562566
- Runs all tests with JUnit 5
563567
- Packages application JAR
564568
- Uploads JAR as artifact (90-day retention)
565569
- Smoke test execution
566-
- Dependency caching (Maven and Ivy) for faster builds
570+
- Dependency caching (Maven and Gradle) for faster builds
567571

568572
**Triggers:**
569573
- Push to `main`, `develop`, `feature/**`, `fix/**` branches
@@ -572,7 +576,7 @@ The project uses GitHub Actions for automated build, test, and deployment workfl
572576

573577
**Build environment:**
574578
- Ubuntu latest
575-
- Java 11 (Temurin distribution)
579+
- Java 21 (Temurin distribution)
576580
- 15-minute timeout
577581
- Concurrency control (cancels outdated builds)
578582

Dockerfile

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
# Railway Interlocking Simulator
88
#
99
# Dockerization: 2025
10-
# Optimized: 2026-01 (BuildKit cache mounts, layer optimization)
10+
# Gradle migration: 2026-01
11+
# Java 21 migration: 2026-01 (Eclipse Temurin + Debian Bookworm)
1112
#
1213
# Multi-stage build for interlockSim with GUI support
1314
# Dependency management: Gradle with Kotlin DSL
14-
# Migrated from Ant/Ivy: 2026
15+
# Build system: Java 21 LTS with Eclipse Temurin
1516
#
1617

1718
# syntax=docker/dockerfile:1.4
@@ -26,20 +27,7 @@ FROM jdisco:latest AS jdisco-builder
2627
# ============================================
2728
# Stage 2: Build interlockSim with Gradle
2829
# ============================================
29-
FROM debian:buster-slim AS builder
30-
31-
# Debian Buster is archived - update sources
32-
RUN sed -i 's|http://deb.debian.org|http://archive.debian.org|g' /etc/apt/sources.list && \
33-
sed -i 's|http://security.debian.org|http://archive.debian.org|g' /etc/apt/sources.list && \
34-
sed -i '/buster-updates/d' /etc/apt/sources.list
35-
36-
# Install Java 11 JDK (Gradle wrapper handles Gradle itself)
37-
RUN apt-get update && apt-get install -y \
38-
openjdk-11-jdk \
39-
&& rm -rf /var/lib/apt/lists/*
40-
41-
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
42-
ENV PATH=$JAVA_HOME/bin:$PATH
30+
FROM eclipse-temurin:21-jdk AS builder
4331

4432
WORKDIR /build/interlockSim
4533

@@ -82,34 +70,21 @@ RUN ls -lh /build/interlockSim/build/libs/interlockSim.jar && \
8270
# ============================================
8371
# Stage 3: Runtime with JRE and X11 support
8472
# ============================================
85-
FROM debian:buster-slim AS runner
86-
87-
# Debian Buster is archived - update sources to use archive.debian.org
88-
RUN sed -i 's|http://deb.debian.org|http://archive.debian.org|g' /etc/apt/sources.list && \
89-
sed -i 's|http://security.debian.org|http://archive.debian.org|g' /etc/apt/sources.list && \
90-
sed -i '/buster-updates/d' /etc/apt/sources.list
73+
FROM eclipse-temurin:21-jre AS runner
9174

92-
# Install OpenJDK 11 JRE and X11 libraries for GUI support
75+
# Install X11 libraries for GUI support
76+
# Eclipse Temurin already includes Java 21 JRE
9377
RUN apt-get update && apt-get install -y \
94-
openjdk-11-jre \
9578
libxext6 \
9679
libxrender1 \
9780
libxtst6 \
9881
libxi6 \
9982
libxrandr2 \
10083
libxcursor1 \
10184
libxinerama1 \
102-
libxfixes3 \
103-
libxdamage1 \
104-
libxcomposite1 \
105-
libfreetype6 \
106-
libfontconfig1 \
85+
fontconfig \
10786
&& rm -rf /var/lib/apt/lists/*
10887

109-
# Set Java 11 JRE as default
110-
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
111-
ENV PATH=$JAVA_HOME/bin:$PATH
112-
11388
WORKDIR /app
11489

11590
# Copy compiled uber JAR from builder stage (Gradle output)

0 commit comments

Comments
 (0)