-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Migrate from Java 9 to Java 11 #2
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
37f0082
cb82721
e4ff4a5
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,27 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ master, main ] | ||
| pull_request: | ||
| branches: [ master, main ] | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up JDK 11 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| java-version: '11' | ||
| distribution: 'temurin' | ||
| cache: maven | ||
|
|
||
| - name: Compile | ||
| run: mvn -B clean compile | ||
|
|
||
| - name: Test | ||
| run: mvn -B test |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # Migration Notes: Java 9 → Java 11 | ||
|
|
||
| ## Java Version Change | ||
|
|
||
| - **From**: Java 9 (source/target 1.9) | ||
| - **To**: Java 11 (using `<release>11</release>`) | ||
| - The `<release>` flag replaces the legacy `<source>`/`<target>` configuration and provides stronger cross-compilation guarantees. | ||
|
|
||
| ## Plugin Upgrades | ||
|
|
||
| | Plugin | Old Version | New Version | Notes | | ||
| |--------|-------------|-------------|-------| | ||
| | maven-compiler-plugin | 3.1 | 3.11.0 | Switched from source/target to release flag | | ||
| | maven-surefire-plugin | (none) | 3.2.5 | Added for test execution | | ||
| | maven-failsafe-plugin | (none) | 3.2.5 | Added for integration test support | | ||
| | maven-enforcer-plugin | (none) | 3.5.0 | Added to enforce Java 11+ at build time | | ||
| | maven-javadoc-plugin | (none) | 3.6.3 | Added with `<doclint>none</doclint>` (Java 11 doclint is stricter) | | ||
| | maven-shade-plugin | (unversioned) | 3.6.2 | Pinned explicit version (was unversioned, which Maven warns is unstable) | | ||
|
|
||
| Build encoding is pinned to UTF-8 for both source (`project.build.sourceEncoding`) and reporting (`project.reporting.outputEncoding`). | ||
|
|
||
| ## Dependency Upgrades | ||
|
|
||
| | Dependency | Old Version | New Version | Notes | | ||
| |------------|-------------|-------------|-------| | ||
| | JUnit | 4.11 | 4.13.2 | Latest JUnit 4.x; added `<scope>test</scope>` | | ||
| | JMH (jmh-core) | 1.17.4 | 1.37 | Java 11 compatible | | ||
| | JMH (jmh-generator-annprocess) | 1.17.4 | 1.37 | Java 11 compatible | | ||
|
|
||
| ## Code Fixes Required | ||
|
|
||
| Minimal changes were needed: | ||
|
|
||
| - **Moved `ReadPositiveIntParam.java`** from `src/main/java` to `src/test/java` — this file contained JUnit `@Test` annotations but was incorrectly placed in the main source tree. With JUnit correctly scoped to `test`, it must reside under `src/test/java`. | ||
| - No Nashorn JavaScript engine references found | ||
| - No internal `sun.*` or `com.sun.*` API usage | ||
| - No Java EE modules (removed in Java 11) were used | ||
| - Deprecation warning in `Util.java` (deprecated API usage) — informational only, no breaking change | ||
|
|
||
| ## New Test Coverage | ||
|
|
||
| Added integration tests covering core chapters: | ||
|
|
||
| | Test File | Chapter | Coverage | | ||
| |-----------|---------|----------| | ||
| | `FilteringApplesTest.java` | Chapter 1 | Lambda expressions, method references, Predicate-based filtering | | ||
| | `StreamBasicsTest.java` | Chapter 4 | Stream creation, filtering, sorting, Java 7 vs Java 8 comparison | | ||
| | `StreamProcessingTest.java` | Chapter 5 | Trader/Transaction queries, reduce, distinct, anyMatch | | ||
| | `OptionalTest.java` | Chapter 10 | Optional creation, map, flatMap, orElse, filter, stream() | | ||
| | `CompletableFutureTest.java` | Chapter 11 | supplyAsync, thenApply, thenCombine, thenCompose, exceptionally | | ||
| | `DateTimeTest.java` | Chapter 12 | LocalDate, LocalTime, LocalDateTime, Duration, TemporalAdjusters, DateTimeFormatter | | ||
|
|
||
| ## CI Workflow Added | ||
|
|
||
| - GitHub Actions workflow (`.github/workflows/ci.yml`) | ||
| - Triggers on push/PR to master/main branches | ||
| - Uses Temurin JDK 11 with Maven caching | ||
| - Runs `mvn -B clean compile` and `mvn -B test` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,23 +10,26 @@ | |
|
|
||
| <properties> | ||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | ||
| <maven.compiler.release>11</maven.compiler.release> | ||
| </properties> | ||
|
|
||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.openjdk.jmh</groupId> | ||
| <artifactId>jmh-core</artifactId> | ||
| <version>1.17.4</version> | ||
| <version>1.37</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.openjdk.jmh</groupId> | ||
| <artifactId>jmh-generator-annprocess</artifactId> | ||
| <version>1.17.4</version> | ||
| <version>1.37</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>junit</groupId> | ||
| <artifactId>junit</artifactId> | ||
| <version>4.11</version> | ||
| <version>4.13.2</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
|
|
||
|
|
@@ -35,15 +38,54 @@ | |
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-compiler-plugin</artifactId> | ||
| <version>3.1</version> | ||
| <version>3.11.0</version> | ||
| <configuration> | ||
| <source>1.9</source> | ||
| <target>1.9</target> | ||
| <release>11</release> | ||
| </configuration> | ||
| </plugin> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-surefire-plugin</artifactId> | ||
| <version>3.2.5</version> | ||
| </plugin> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-failsafe-plugin</artifactId> | ||
| <version>3.2.5</version> | ||
| </plugin> | ||
|
Comment on lines
+51
to
+55
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. 🚩 Added failsafe plugin does not run integration tests by itself The new Failsafe plugin is declared but has no executions bound to Was this helpful? React with 👍 or 👎 to provide feedback. Debug |
||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-enforcer-plugin</artifactId> | ||
| <version>3.5.0</version> | ||
| <executions> | ||
| <execution> | ||
| <id>enforce-java</id> | ||
| <goals> | ||
| <goal>enforce</goal> | ||
| </goals> | ||
| <configuration> | ||
| <rules> | ||
| <requireJavaVersion> | ||
| <version>[11,)</version> | ||
| <message>Java 11 or higher is required to build this project.</message> | ||
| </requireJavaVersion> | ||
| </rules> | ||
| </configuration> | ||
| </execution> | ||
| </executions> | ||
| </plugin> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-javadoc-plugin</artifactId> | ||
| <version>3.6.3</version> | ||
| <configuration> | ||
| <doclint>none</doclint> | ||
| </configuration> | ||
| </plugin> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-shade-plugin</artifactId> | ||
| <version>3.6.2</version> | ||
| <executions> | ||
| <execution> | ||
| <phase>package</phase> | ||
|
|
@@ -63,4 +105,4 @@ | |
| </plugin> | ||
| </plugins> | ||
| </build> | ||
| </project> | ||
| </project> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| package lambdasinaction.chap1; | ||
|
|
||
| import lambdasinaction.chap1.FilteringApples.Apple; | ||
| import org.junit.Test; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| import static org.junit.Assert.*; | ||
|
|
||
| public class FilteringApplesTest { | ||
|
|
||
| private final List<Apple> inventory = Arrays.asList( | ||
| new Apple(80, "green"), | ||
| new Apple(155, "green"), | ||
| new Apple(120, "red")); | ||
|
|
||
| @Test | ||
| public void filterGreenApples() { | ||
| List<Apple> result = FilteringApples.filterGreenApples(inventory); | ||
| assertEquals(2, result.size()); | ||
| assertTrue(result.stream().allMatch(a -> "green".equals(a.getColor()))); | ||
| } | ||
|
|
||
| @Test | ||
| public void filterHeavyApples() { | ||
| List<Apple> result = FilteringApples.filterHeavyApples(inventory); | ||
| assertEquals(1, result.size()); | ||
| assertTrue(result.get(0).getWeight() > 150); | ||
| } | ||
|
|
||
| @Test | ||
| public void filterWithMethodReference() { | ||
| List<Apple> greens = FilteringApples.filterApples(inventory, FilteringApples::isGreenApple); | ||
| assertEquals(2, greens.size()); | ||
|
|
||
| List<Apple> heavies = FilteringApples.filterApples(inventory, FilteringApples::isHeavyApple); | ||
| assertEquals(1, heavies.size()); | ||
| } | ||
|
|
||
| @Test | ||
| public void filterWithLambda() { | ||
| List<Apple> greens = FilteringApples.filterApples(inventory, a -> "green".equals(a.getColor())); | ||
| assertEquals(2, greens.size()); | ||
|
|
||
| List<Apple> heavies = FilteringApples.filterApples(inventory, a -> a.getWeight() > 150); | ||
| assertEquals(1, heavies.size()); | ||
| } | ||
|
|
||
| @Test | ||
| public void filterWithComplexPredicate() { | ||
| List<Apple> result = FilteringApples.filterApples(inventory, | ||
| a -> a.getWeight() < 80 || "brown".equals(a.getColor())); | ||
| assertTrue(result.isEmpty()); | ||
| } | ||
|
|
||
| @Test | ||
| public void appleToString() { | ||
| Apple apple = new Apple(80, "green"); | ||
| String str = apple.toString(); | ||
| assertTrue(str.contains("green")); | ||
| assertTrue(str.contains("80")); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| package lambdasinaction.chap10; | ||
|
|
||
| import org.junit.Test; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.Optional; | ||
| import java.util.Set; | ||
|
|
||
| import static org.junit.Assert.*; | ||
|
|
||
| public class OptionalTest { | ||
|
|
||
| @Test | ||
| public void getCarInsuranceNameWithEmptyPerson() { | ||
| OptionalMain main = new OptionalMain(); | ||
| String result = main.getCarInsuranceName(Optional.empty()); | ||
| assertEquals("Unknown", result); | ||
| } | ||
|
|
||
| @Test | ||
| public void optionalOfNullable() { | ||
| Optional<String> opt = Optional.ofNullable(null); | ||
| assertFalse(opt.isPresent()); | ||
|
|
||
| Optional<String> present = Optional.ofNullable("hello"); | ||
| assertTrue(present.isPresent()); | ||
| assertEquals("hello", present.get()); | ||
| } | ||
|
|
||
| @Test | ||
| public void optionalMap() { | ||
| Optional<String> name = Optional.of("Java"); | ||
| Optional<Integer> len = name.map(String::length); | ||
| assertEquals(Integer.valueOf(4), len.get()); | ||
| } | ||
|
|
||
| @Test | ||
| public void optionalFlatMap() { | ||
| Optional<Optional<String>> nested = Optional.of(Optional.of("nested")); | ||
| Optional<String> flat = nested.flatMap(x -> x); | ||
| assertEquals("nested", flat.get()); | ||
| } | ||
|
|
||
| @Test | ||
| public void optionalOrElse() { | ||
| Optional<String> empty = Optional.empty(); | ||
| assertEquals("default", empty.orElse("default")); | ||
|
|
||
| Optional<String> present = Optional.of("value"); | ||
| assertEquals("value", present.orElse("default")); | ||
| } | ||
|
|
||
| @Test | ||
| public void optionalFilter() { | ||
| Optional<String> opt = Optional.of("hello"); | ||
| assertTrue(opt.filter(s -> s.startsWith("h")).isPresent()); | ||
| assertFalse(opt.filter(s -> s.startsWith("z")).isPresent()); | ||
| } | ||
|
|
||
| @Test | ||
| public void optionalIfPresent() { | ||
| Optional<String> opt = Optional.of("test"); | ||
| StringBuilder sb = new StringBuilder(); | ||
| opt.ifPresent(sb::append); | ||
| assertEquals("test", sb.toString()); | ||
| } | ||
|
|
||
| @Test | ||
| public void optionalStream() { | ||
| Optional<String> present = Optional.of("value"); | ||
| long count = present.stream().count(); | ||
| assertEquals(1, count); | ||
|
|
||
| Optional<String> empty = Optional.empty(); | ||
| long emptyCount = empty.stream().count(); | ||
| assertEquals(0, emptyCount); | ||
| } | ||
|
|
||
| @Test | ||
| public void insuranceNameAccess() { | ||
| Insurance insurance = new Insurance(); | ||
| assertNull(insurance.getName()); | ||
| } | ||
| } |
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.
🟡 Surefire skips the moved JUnit class because its name does not match test includes
The PR moves
ReadPositiveIntParamundersrc/test/java, but the class still keeps the nameReadPositiveIntParamand its JUnit method is atsrc/test/java/lambdasinaction/chap10/ReadPositiveIntParam.java:10-13. Surefire’s default includes only run classes matching patterns such asTest*,*Test,*Tests, or*TestCase; the newly added Surefire configuration does not add an include for this class, somvn test/CI will silently skip the migrated test even though the migration notes say it was moved because it contains JUnit tests.Prompt for agents
Was this helpful? React with 👍 or 👎 to provide feedback.
Debug
Playground