diff --git a/README.md b/README.md index 2029624..9662470 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The subprojects include: ### `java-preview-features/` -This subproject shows how to configure Gradle to build and run a project that uses Java [_Preview Features_](https://openjdk.java.net/jeps/12). +Configure Gradle to build and run a project that uses Java [_Preview Features_](https://openjdk.java.net/jeps/12). See the README in [java-preview-features/](java-preview-features/). diff --git a/java-preview-features/README.md b/java-preview-features/README.md index d57ba01..8771177 100644 --- a/java-preview-features/README.md +++ b/java-preview-features/README.md @@ -1,11 +1,12 @@ # java-preview-features -This project shows how to configure Gradle to build and run a project that uses Java [_Preview Features_](https://openjdk.java.net/jeps/12). +Configure Gradle to build and run a project that uses Java [_Preview Features_](https://openjdk.java.net/jeps/12). ---- -This repo in particular showcases the [Pattern Matching for `switch`](https://openjdk.org/jeps/433) preview language -feature in Java 20. Preview features are hidden behind the `--enable-preview` Java flag. +## Overview + +This repo in particular showcases the [Unnamed Patterns and Variables](https://openjdk.org/jeps/443) preview language +feature in Java 21. Preview features are hidden behind the `--enable-preview` Java flag. Please note: Intellij won't always support preview features! @@ -14,31 +15,27 @@ Please note: Intellij won't always support preview features! Follow these instructions to build and run the demo program. -1. Use Java 17 -2. Make sure that Java 20 is installed in a location known to Gradle -3. Build and run the program: +1. Pre-requisite: Java 21 +2. Build and run the program: * ```shell ./gradlew run ``` * It should output the following. ```text > Task :compileJava - Note: /Users/dave/repos/personal/gradle-playground/java-preview-features/src/main/java/dgroomes/App.java uses preview features of Java SE 20. + Note: /Users/dave/repos/personal/gradle-playground/java-preview-features/src/main/java/dgroomes/java_preview_features/App.java uses preview features of Java SE 21. Note: Recompile with -Xlint:preview for details. + > Task :run - It's Earth, an instance of Planet. Its atmosphere is: mostly nitrogen. - It's Earth, an instance of Planet. Its atmosphere is: mostly nitrogen. - It's Mars, an instance of Planet. Its atmosphere is: carbon dioxide - It's an instance of Star. It says: I shine bright! - It's an instance of Star. It says: I shine bright! + Found 631 time zones ``` Notice the warning: - > Note: /...omitted.../App.java uses preview features of Java SE 20. + > Note: /...omitted.../App.java uses preview features of Java SE 21. There is no way to suppress this because Java's preview features are designed to allow breaking changes in future releases, so the compile-time reminder is a welcome one. -4. Run the tests: +3. Run the tests: * ```shell ./gradlew test ``` @@ -48,7 +45,5 @@ Follow these instructions to build and run the demo program. General clean-ups, TODOs and things I wish to implement for this project: -* [ ] When Gradle officially supports running on Java 20, upgrade to Java 20 for "use this Java version" because this - subproject is not designed to showcase the "toolchains for Java" feature of Gradle. * [x] DONE (I could still use the planet types very effectively thanks to "pattern matching for switch") Upgrade to Java 20 and use a Java 20 preview feature. This will require throwing away the planet design for something else. diff --git a/java-preview-features/build.gradle.kts b/java-preview-features/build.gradle.kts index 146d67c..1693c87 100644 --- a/java-preview-features/build.gradle.kts +++ b/java-preview-features/build.gradle.kts @@ -7,19 +7,13 @@ repositories { mavenCentral() } -val junitVersion = "5.8.1" // releases: https://junit.org/junit5/docs/current/release-notes/index.html +val junitVersion = "5.10.3" // releases: https://junit.org/junit5/docs/current/release-notes/index.html dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion") } -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(20)) - } -} - /** * Configure the compiler task, test task, start script creation task, and the run task to enable Java language "Preview * Features" @@ -44,5 +38,5 @@ tasks { } application { - mainClass.set("dgroomes.App") + mainClass.set("dgroomes.java_preview_features.App") } diff --git a/java-preview-features/gradle/wrapper/gradle-wrapper.jar b/java-preview-features/gradle/wrapper/gradle-wrapper.jar index 249e583..033e24c 100644 Binary files a/java-preview-features/gradle/wrapper/gradle-wrapper.jar and b/java-preview-features/gradle/wrapper/gradle-wrapper.jar differ diff --git a/java-preview-features/gradle/wrapper/gradle-wrapper.properties b/java-preview-features/gradle/wrapper/gradle-wrapper.properties index 84a0b92..09523c0 100644 --- a/java-preview-features/gradle/wrapper/gradle-wrapper.properties +++ b/java-preview-features/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/java-preview-features/gradlew b/java-preview-features/gradlew index a69d9cb..fcb6fca 100755 --- a/java-preview-features/gradlew +++ b/java-preview-features/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +130,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,6 +197,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in diff --git a/java-preview-features/gradlew.bat b/java-preview-features/gradlew.bat index f127cfd..93e3f59 100644 --- a/java-preview-features/gradlew.bat +++ b/java-preview-features/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% diff --git a/java-preview-features/src/main/java/dgroomes/App.java b/java-preview-features/src/main/java/dgroomes/App.java deleted file mode 100644 index 9bbd3e3..0000000 --- a/java-preview-features/src/main/java/dgroomes/App.java +++ /dev/null @@ -1,31 +0,0 @@ -package dgroomes; - -import java.util.List; -import java.util.Random; - -public class App { - - public static void main(String[] args) { - var app = new App(); - - // Describe some random celestial objects. - for (int i = 0; i < 5; i++) { - var randomCelestialObject = app.randomCelestialObject(); - String msg = switch (randomCelestialObject) { - case Planet planet -> { - var name = planet.getClass().getSimpleName(); - var atmosphere = planet.atmosphere(); - yield "It's %s, an instance of Planet. Its atmosphere is: %s".formatted(name, atmosphere); - } - case Star star -> "It's an instance of Star. It says: %s".formatted(star.brightMessage()); - }; - System.out.println(msg); - } - } - - public Celestial randomCelestialObject() { - var celestialObjects = List.of(new Earth(), new Mars(), new Star()); - var idx = new Random().nextInt(celestialObjects.size()); - return celestialObjects.get(idx); - } -} diff --git a/java-preview-features/src/main/java/dgroomes/Celestial.java b/java-preview-features/src/main/java/dgroomes/Celestial.java deleted file mode 100644 index 3f176b6..0000000 --- a/java-preview-features/src/main/java/dgroomes/Celestial.java +++ /dev/null @@ -1,9 +0,0 @@ -package dgroomes; - -/** - * A toy example illustrating Java's new language feature called "Sealed classes and interfaces". Uses code examples from - * the JEP page https://openjdk.java.net/jeps/397. - */ -sealed interface Celestial - permits Planet, Star { -} diff --git a/java-preview-features/src/main/java/dgroomes/Earth.java b/java-preview-features/src/main/java/dgroomes/Earth.java deleted file mode 100644 index 8474b3d..0000000 --- a/java-preview-features/src/main/java/dgroomes/Earth.java +++ /dev/null @@ -1,9 +0,0 @@ -package dgroomes; - -public class Earth extends Planet { - - @Override - public String atmosphere() { - return "mostly nitrogen."; - } -} diff --git a/java-preview-features/src/main/java/dgroomes/Mars.java b/java-preview-features/src/main/java/dgroomes/Mars.java deleted file mode 100644 index 66426ae..0000000 --- a/java-preview-features/src/main/java/dgroomes/Mars.java +++ /dev/null @@ -1,9 +0,0 @@ -package dgroomes; - -public class Mars extends Planet { - - @Override - public String atmosphere() { - return "carbon dioxide"; - } -} diff --git a/java-preview-features/src/main/java/dgroomes/Planet.java b/java-preview-features/src/main/java/dgroomes/Planet.java deleted file mode 100644 index acab134..0000000 --- a/java-preview-features/src/main/java/dgroomes/Planet.java +++ /dev/null @@ -1,6 +0,0 @@ -package dgroomes; - -public non-sealed abstract class Planet implements Celestial { - - public abstract String atmosphere(); -} diff --git a/java-preview-features/src/main/java/dgroomes/Star.java b/java-preview-features/src/main/java/dgroomes/Star.java deleted file mode 100644 index a5e2ea7..0000000 --- a/java-preview-features/src/main/java/dgroomes/Star.java +++ /dev/null @@ -1,8 +0,0 @@ -package dgroomes; - -public final class Star implements Celestial { - - public String brightMessage() { - return "I shine bright!"; - } -} diff --git a/java-preview-features/src/main/java/dgroomes/java_preview_features/App.java b/java-preview-features/src/main/java/dgroomes/java_preview_features/App.java new file mode 100644 index 0000000..c44e822 --- /dev/null +++ b/java-preview-features/src/main/java/dgroomes/java_preview_features/App.java @@ -0,0 +1,24 @@ +package dgroomes.java_preview_features; + +import java.util.TimeZone; + +public class App { + + public static void main(String[] args) { + var count = new App().countTimezones(); + System.out.printf("Found %d time zones%n", count); + } + + public int countTimezones() { + int count = 0; + + // This contrived example shows the use of the "Unnamed patterns and variables" preview language feature. We use + // "_" in place of a variable name. This is a convenient way to not have to come up with a name, and to tell + // tooling (linters, IDEs) that we indeed did not intend to use the variable. + for (var _ : TimeZone.getAvailableIDs()) { + count++; + } + + return count; + } +} diff --git a/java-preview-features/src/test/java/dgroomes/AppTest.java b/java-preview-features/src/test/java/dgroomes/java_preview_features/AppTest.java similarity index 68% rename from java-preview-features/src/test/java/dgroomes/AppTest.java rename to java-preview-features/src/test/java/dgroomes/java_preview_features/AppTest.java index 73d687b..b770803 100644 --- a/java-preview-features/src/test/java/dgroomes/AppTest.java +++ b/java-preview-features/src/test/java/dgroomes/java_preview_features/AppTest.java @@ -1,4 +1,4 @@ -package dgroomes; +package dgroomes.java_preview_features; import org.junit.jupiter.api.Test; @@ -10,6 +10,6 @@ class AppTest { void message() { var app = new App(); - assertNotNull(app.randomCelestialObject()); + assertNotNull(app.countTimezones()); } }