Repository navigation
Migrate from Java 8 to Java 11 (LTS) #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
cf9d3db
662d142
4bd5b5f
66bf1ee
e8215b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| name: CI (JDK 11) | ||
|
|
||
| on: | ||
| push: | ||
| branches: [master] | ||
| pull_request: | ||
| branches: [master] | ||
|
|
||
| jobs: | ||
| maven: | ||
| name: Maven build (Temurin 11) | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up JDK 11 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: temurin | ||
| java-version: '11' | ||
| cache: maven | ||
|
|
||
| - name: Build and verify | ||
| run: ./mvnw -B -e clean verify | ||
|
|
||
| gradle: | ||
| name: Gradle build (Temurin 11) | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up JDK 11 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: temurin | ||
| java-version: '11' | ||
| cache: gradle | ||
|
|
||
| - name: Build | ||
| run: ./gradlew --no-daemon clean build |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,5 @@ | ||
| /.idea/ | ||
| /.idea/ | ||
| target/ | ||
| build/ | ||
| .gradle/ | ||
| *.class |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip | ||
| distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip | ||
| wrapperUrl=https://repo1.maven.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # Java 8 → Java 11 Migration Notes | ||
|
|
||
| This document summarizes the migration of `springboot-java8` from Java 8 to | ||
| **Java 11 (LTS)**. The goal was a minimal, behavior-preserving migration: upgrade | ||
| the build toolchain and CI to JDK 11, replace anything removed from the JDK, and | ||
| keep the application code unchanged. | ||
|
|
||
| ## Summary | ||
|
|
||
| | Area | Before | After | | ||
| | --- | --- | --- | | ||
| | Java language/runtime target | 8 (`java.version=1.8`) | 11 (`maven.compiler.release=11`) | | ||
| | Maven packaging | `pom` (sources never compiled) | `jar` (sources compiled + repackaged) | | ||
| | Maven wrapper | 3.3.9 | 3.9.9 | | ||
| | maven-compiler-plugin | inherited 3.7.0 | 3.11.0, `<release>11</release>`, `-Xlint:all -Werror` | | ||
| | maven-surefire-plugin | inherited 2.21.0 | 3.2.5 | | ||
| | maven-failsafe-plugin | not configured | 3.2.5 | | ||
| | maven-javadoc-plugin | not configured | 3.6.3, doclint disabled | | ||
| | maven-enforcer-plugin | not configured | 3.5.0, `requireJavaVersion [11,)` | | ||
| | Gradle wrapper | 4.6 (does not run on JDK 11) | 6.9.4 | | ||
| | Gradle Java target | `sourceCompatibility = 1.8` | toolchain `languageVersion = 11` | | ||
| | CI | none | GitHub Actions, Temurin 11, Maven + Gradle | | ||
|
|
||
| ## Baseline (Java 8) | ||
|
|
||
| A Java 8 baseline was captured before any changes: | ||
|
|
||
| - `JAVA_HOME` = Temurin/OpenJDK `1.8.0_492` | ||
| - `./mvnw -B clean package` → `BUILD SUCCESS` | ||
|
|
||
| Note: with the original `<packaging>pom</packaging>`, the Maven build never invoked | ||
| the compiler, so the "baseline" Maven build did not actually compile the `hello.*` | ||
| sources. The Gradle build was the only one that compiled code. This is called out | ||
| because it changes what "parity" means here (see below). | ||
|
|
||
| ## Build tooling changes | ||
|
|
||
| ### Maven (`pom.xml`) | ||
|
|
||
| - **`packaging` changed from `pom` to `jar`.** As a `pom` project the | ||
| `maven-compiler-plugin` and `maven-surefire-plugin` never ran, so the Java 11 | ||
| `release` flag would have had no effect. Switching to `jar` makes Maven actually | ||
| compile the sources under `--release 11` and produce a runnable Spring Boot jar | ||
| via `spring-boot-maven-plugin:repackage`. | ||
| - Replaced `<java.version>1.8</java.version>` with | ||
| `maven.compiler.release=11` plus UTF-8 source/reporting encoding. | ||
| - Added explicit, JDK-11-compatible plugin versions: | ||
| `maven-compiler-plugin` 3.11.0 (`<release>11</release>`, `-Xlint:all`, | ||
| `-Werror`), `maven-surefire-plugin` 3.2.5, `maven-failsafe-plugin` 3.2.5, | ||
| `maven-javadoc-plugin` 3.6.3, `maven-enforcer-plugin` 3.5.0 enforcing | ||
| `requireJavaVersion [11,)`. | ||
| - Added `spring-boot-starter-test` (test scope) so the project has a standard test | ||
| source set; surefire reports `No tests to run` (the project ships no tests). | ||
| - Upgraded the Maven wrapper from 3.3.9 to 3.9.9 — the older plugin-aware tooling | ||
| (surefire/enforcer 3.x) requires Maven 3.6.3+. | ||
|
|
||
| ### Gradle (`build.gradle`) | ||
|
|
||
| - Upgraded the Gradle wrapper from 4.6 to 6.9.4. Gradle 4.6 cannot run on JDK 11. | ||
| - Replaced `sourceCompatibility/targetCompatibility = 1.8` with a Java | ||
| **toolchain** pinned to `JavaLanguageVersion.of(11)`. (Gradle rejects combining a | ||
| project-level toolchain with `source/targetCompatibility`, so the latter were | ||
| removed.) | ||
| - Modernized the legacy `compile`/`testCompile` configurations to | ||
| `implementation`/`testImplementation`. | ||
| - **Parity fix:** added `spring-boot-starter-jdbc` and `com.h2database:h2`. The | ||
| original Gradle build only declared `spring-boot-starter-web`, so it failed to | ||
| compile `hello.Application` (which uses `JdbcTemplate`). These deps already | ||
| existed in `pom.xml`; adding them brings the Gradle build to parity with Maven. | ||
|
|
||
| ## Removed JDK modules (Java EE / CORBA / JavaFX) | ||
|
|
||
| A scan of the source (`javax.xml.bind`, `javax.activation`, `javax.xml.ws`, | ||
| `com.sun.*`, `sun.misc.*`, Nashorn, `javafx.*`, CORBA / `org.omg.*`) found **no | ||
| usages**. No external replacement dependencies (JAXB, JAX-WS, JavaFX, Activation) | ||
| were required. | ||
|
|
||
| ## Encapsulation / illegal reflective access | ||
|
|
||
| The application code triggers no illegal reflective access warnings when compiled | ||
| or packaged on JDK 11, so **no `--add-opens` flags were added**. The only reflective | ||
| access warning observed comes from Gradle 6.9.4's own Groovy runtime during the | ||
| build (not from application code); it disappears with a newer Gradle and is out of | ||
| scope for this behavior-preserving migration. | ||
|
|
||
| ## Security / TLS, GC, logging | ||
|
|
||
| No code or configuration depends on TLS protocol/cipher pinning, keystore type, or | ||
| GC/JVM tuning flags (the only runtime config is the optional `server.port` in | ||
| `application.properties`). Java 11 defaults (TLS 1.3, PKCS12 keystores, G1 GC, | ||
| unified logging) therefore apply with no changes needed. | ||
|
|
||
| ## Validation | ||
|
|
||
| - `./mvnw -B clean verify` on **JDK 11** → `BUILD SUCCESS` (compiles with | ||
| `-Xlint:all -Werror`, enforcer confirms Java 11, jar repackaged). | ||
| - `./gradlew --no-daemon clean build` on **JDK 11** → `BUILD SUCCESSFUL`. | ||
| - No compiler warnings under `-Xlint:all`. | ||
| - Coverage is unchanged (the project ships no tests, so coverage is 0% before and | ||
| after; CI is green on the build). | ||
|
|
||
| ## Follow-ups (out of scope) | ||
|
|
||
| - Spring Boot 2.0.2 / Spring 5.0 predate official Java 11 support. Compilation and | ||
| packaging are clean on JDK 11, but a future PR should upgrade to Spring Boot | ||
| 2.1+ (ideally 2.7.x) for fully supported Java 11 runtime behavior. | ||
| - Add an actual test suite (e.g. `@SpringBootTest`) so CI verifies runtime | ||
| behavior, not just compilation. | ||
| - Resolve Gradle deprecation warnings by moving to Gradle 7/8 (requires the Spring | ||
| Boot upgrade above, since the 2.0.2 Gradle plugin is incompatible with Gradle 7+). |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 Spring Boot 2.0.2 predates official Java 11 support The PR acknowledges this in (Refers to line 14) Was this helpful? React with 👍 or 👎 to provide feedback. Debug
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 Spring Boot 2.0.2 predates official JDK 11 support The PR migrates to Java 11 but retains Spring Boot 2.0.2.RELEASE ( (Refers to line 14) Was this helpful? React with 👍 or 👎 to provide feedback.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Acknowledged and intentional. This PR is scoped to the Java 8 → 11 toolchain/CI migration with minimal behavior change, so the framework version is deliberately held at Spring Boot 2.0.2. It compiles, packages, and boots on JDK 11 (the Spring context starts; the only startup failure is a pre-existing call to a now-dead external quotes endpoint, identical on Java 8). The Spring Boot 2.1+/2.7.x upgrade for officially-supported JDK 11 runtime is called out as a follow-up in |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚩 Gradle wrapper script lacks executable permission (pre-existing)
The
gradlewscript is tracked with git mode100644(not executable), whilemvnwis correctly100755. Running./gradlew clean buildon Linux/macOS would fail with a permission error unlesschmod +xis applied first. This is a pre-existing issue (not introduced by this PR), but the PR does modify the Gradle wrapper properties and documents./gradlew clean buildas a valid build command inREADME.md:92, making it more likely someone will hit this.Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in this branch —
gradlewis now tracked with mode100755(executable), matchingmvnw:The Gradle CI job (
./gradlew --no-daemon clean build) runs the wrapper directly without achmodstep and passes, confirming the executable bit is set.