diff --git a/.github/workflows/scripts-ios.yml b/.github/workflows/scripts-ios.yml index 618e82b6cd..a76422f668 100644 --- a/.github/workflows/scripts-ios.yml +++ b/.github/workflows/scripts-ios.yml @@ -76,6 +76,13 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + cache: maven + - name: Ensure CocoaPods tooling run: | mkdir -p ~/.codenameone diff --git a/Ports/CLDC11/src/java/lang/invoke/StringConcatFactory.java b/Ports/CLDC11/src/java/lang/invoke/StringConcatFactory.java new file mode 100644 index 0000000000..140c598ced --- /dev/null +++ b/Ports/CLDC11/src/java/lang/invoke/StringConcatFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores + * CA 94065 USA or visit www.oracle.com if you need additional information or + * have any questions. + */ +package java.lang.invoke; + +/** + * @deprecated this class is used internally for String concatenation compatibility + */ +public final class StringConcatFactory { + private StringConcatFactory() { + } + + public static CallSite makeConcat(MethodHandles.Lookup lookup, String name, + MethodType concatType) { + return null; + } + + public static CallSite makeConcatWithConstants(MethodHandles.Lookup lookup, String name, + MethodType concatType, String recipe, Object... constants) { + return null; + } +} diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java index eac92a37e9..075822145a 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CN1BuildMojo.java @@ -1075,17 +1075,41 @@ private static class PropertyConflictException extends LibraryPropertiesExceptio + + private static int parseJavaVersion(String version, int defaultValue) { + if (version == null) { + return defaultValue; + } + String normalized = version.trim(); + if (normalized.isEmpty()) { + return defaultValue; + } + if (normalized.startsWith("1.")) { + normalized = normalized.substring(2); + } + int dotPos = normalized.indexOf('.'); + if (dotPos > 0) { + normalized = normalized.substring(0, dotPos); + } + int dashPos = normalized.indexOf('-'); + if (dashPos > 0) { + normalized = normalized.substring(0, dashPos); + } + try { + return Integer.parseInt(normalized); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + private SortedProperties mergeRequiredProperties(String libraryName, Properties libProps, Properties projectProps) throws LibraryPropertiesException { String javaVersion = (String)projectProps.getProperty("codename1.arg.java.version", "8"); String javaVersionLib = (String)libProps.get("codename1.arg.java.version"); if(javaVersionLib != null){ - int v1 = 5; - if(javaVersion != null){ - v1 = Integer.parseInt(javaVersion); - } - int v2 = Integer.parseInt(javaVersionLib); + int v1 = parseJavaVersion(javaVersion, 5); + int v2 = parseJavaVersion(javaVersionLib, 5); //if the lib java version is bigger, this library cannot be used if(v1 < v2){ throw new VersionMismatchException(libraryName, "Cannot use a cn1lib with java version " diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/InstallCn1libsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/InstallCn1libsMojo.java index 0725d70201..fb84db942c 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/InstallCn1libsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/InstallCn1libsMojo.java @@ -230,6 +230,33 @@ private boolean mergeProjectAppendedProperties(Artifact artifact) throws IOExcep return changed; } + + private static int parseJavaVersion(String version, int defaultValue) { + if (version == null) { + return defaultValue; + } + String normalized = version.trim(); + if (normalized.isEmpty()) { + return defaultValue; + } + if (normalized.startsWith("1.")) { + normalized = normalized.substring(2); + } + int dotPos = normalized.indexOf('.'); + if (dotPos > 0) { + normalized = normalized.substring(0, dotPos); + } + int dashPos = normalized.indexOf('-'); + if (dashPos > 0) { + normalized = normalized.substring(0, dashPos); + } + try { + return Integer.parseInt(normalized); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + /** * Merges the lib's required properties with the project properties. Does not persist. * @param artifact @@ -244,11 +271,8 @@ private boolean mergeProjectRequiredProperties(Artifact artifact) throws IOExcep String javaVersion = (String)projectProps.getProperty("codename1.arg.java.version", "8"); String javaVersionLib = (String)libProps.get("codename1.arg.java.version"); if(javaVersionLib != null){ - int v1 = 5; - if(javaVersion != null){ - v1 = Integer.parseInt(javaVersion); - } - int v2 = Integer.parseInt(javaVersionLib); + int v1 = parseJavaVersion(javaVersion, 5); + int v2 = parseJavaVersion(javaVersionLib, 5); //if the lib java version is bigger, this library cannot be used if(v1 < v2){ throw new BuildException("Cannot use a cn1lib with java version " diff --git a/scripts/build-ios-app.sh b/scripts/build-ios-app.sh index 3a39638784..d83687ee3f 100755 --- a/scripts/build-ios-app.sh +++ b/scripts/build-ios-app.sh @@ -54,12 +54,17 @@ if ! command -v pod >/dev/null 2>&1; then exit 1 fi +ORIGINAL_JAVA_HOME="$JAVA_HOME" +export JAVA_HOME="$JAVA17_HOME" export PATH="$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH" bia_log "Using JAVA_HOME at $JAVA_HOME" +bia_log "Original JAVA_HOME was $ORIGINAL_JAVA_HOME" bia_log "Using JAVA17_HOME at $JAVA17_HOME" bia_log "Using Maven installation at $MAVEN_HOME" bia_log "Using CocoaPods version $(pod --version 2>/dev/null || echo '')" +bia_log "Java version for Maven invocations:" +"$JAVA_HOME/bin/java" -version IOS_UISCENE="${IOS_UISCENE:-false}" bia_log "Building sample app with ios.uiscene=${IOS_UISCENE}" diff --git a/scripts/hellocodenameone/README.adoc b/scripts/hellocodenameone/README.adoc index 3c48268908..95911cb422 100644 --- a/scripts/hellocodenameone/README.adoc +++ b/scripts/hellocodenameone/README.adoc @@ -8,6 +8,10 @@ This is a multi-module maven project for building a Codename One application. Co If you plan to use Java as your primary language, https://shannah.github.io/cn1-maven-archetypes/cn1app-archetype-tutorial/getting-started.html[start here]. +=== Java Version + +Use Java 17 to build and run this project (e.g. `JAVA_HOME` should point to a JDK 17 installation). + === Kotlin If you plan to use Kotlin as your primary language, https://shannah.github.io/cn1app-archetype-kotlin-template/getting-started.html[start here]. diff --git a/scripts/hellocodenameone/android/pom.xml b/scripts/hellocodenameone/android/pom.xml index b72d6f7ffd..bfb4ac0257 100644 --- a/scripts/hellocodenameone/android/pom.xml +++ b/scripts/hellocodenameone/android/pom.xml @@ -14,8 +14,8 @@ UTF-8 - 1.8 - 1.8 + 17 + 17 android android android-device diff --git a/scripts/hellocodenameone/build.bat b/scripts/hellocodenameone/build.bat index b7ccc0e212..3a6de4a84d 100644 --- a/scripts/hellocodenameone/build.bat +++ b/scripts/hellocodenameone/build.bat @@ -6,6 +6,11 @@ setlocal EnableExtensions set MVNW=mvnw.cmd +java -version 2>&1 | findstr /c:"17" >nul +if errorlevel 1 if exist "C:\Program Files\Java\jdk-17" set "JAVA_HOME=C:\Program Files\Java\jdk-17" +if errorlevel 1 if exist "C:\Program Files\Eclipse Adoptium\jdk-17" set "JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-17" +if not "%JAVA_HOME%"=="" set "PATH=%JAVA_HOME%\bin;%PATH%" + SET CMD=%1 if "%CMD%"=="" ( set CMD=jar diff --git a/scripts/hellocodenameone/build.sh b/scripts/hellocodenameone/build.sh index 8a99f56684..3501905782 100755 --- a/scripts/hellocodenameone/build.sh +++ b/scripts/hellocodenameone/build.sh @@ -2,6 +2,23 @@ set -e MVNW="./mvnw" +JAVA17_HOME="" +if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ] && "$JAVA_HOME/bin/java" -version 2>&1 | head -n 1 | grep -q "\"17"; then + JAVA17_HOME="$JAVA_HOME" +else + for candidate in /usr/lib/jvm/java-17-openjdk-amd64 /usr/lib/jvm/java-17-openjdk /usr/lib/jvm/jdk-17 /usr/lib/jvm/*17*; do + if [ -x "$candidate/bin/java" ] && "$candidate/bin/java" -version 2>&1 | head -n 1 | grep -q "\"17"; then + JAVA17_HOME="$candidate" + break + fi + done +fi + +if [ -n "$JAVA17_HOME" ]; then + export JAVA_HOME="$JAVA17_HOME" + export PATH="$JAVA_HOME/bin:$PATH" +fi + function mac_desktop { "$MVNW" "package" "-DskipTests" "-Dcodename1.platform=javase" "-Dcodename1.buildTarget=mac-os-x-desktop" "-U" "-e" @@ -96,4 +113,4 @@ CMD="$1" if [ "$CMD" == "" ]; then CMD="jar" fi -"$CMD" \ No newline at end of file +"$CMD" diff --git a/scripts/hellocodenameone/common/pom.xml b/scripts/hellocodenameone/common/pom.xml index 539f3efa0a..142ce7943d 100644 --- a/scripts/hellocodenameone/common/pom.xml +++ b/scripts/hellocodenameone/common/pom.xml @@ -303,7 +303,7 @@ javase - + @@ -311,8 +311,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 + ${maven.compiler.source} + ${maven.compiler.target} diff --git a/scripts/hellocodenameone/common/src/test/java/com/codenameone/examples/hellocodenameone/Java17LanguageFeaturesTest.java b/scripts/hellocodenameone/common/src/test/java/com/codenameone/examples/hellocodenameone/Java17LanguageFeaturesTest.java new file mode 100644 index 0000000000..0bc56d0612 --- /dev/null +++ b/scripts/hellocodenameone/common/src/test/java/com/codenameone/examples/hellocodenameone/Java17LanguageFeaturesTest.java @@ -0,0 +1,27 @@ +package com.codenameone.examples.hellocodenameone; + +import com.codename1.testing.AbstractTest; + +public class Java17LanguageFeaturesTest extends AbstractTest { + + @Override + public boolean runTest() throws Exception { + var greeting = "Hello"; + var target = "Codename One"; + + var message = switch (greeting.length()) { + case 5 -> greeting + " " + target; + default -> "unexpected"; + }; + + var textBlock = """ + Java 17 language features + should compile in tests. + """; + + assertEqual("Hello Codename One", message); + assertEqual("Java 17 language features\nshould compile in tests.\n", textBlock); + + return true; + } +} diff --git a/scripts/hellocodenameone/ios/pom.xml b/scripts/hellocodenameone/ios/pom.xml index ccbad41f9f..7e26e9a300 100644 --- a/scripts/hellocodenameone/ios/pom.xml +++ b/scripts/hellocodenameone/ios/pom.xml @@ -14,8 +14,8 @@ UTF-8 - 1.8 - 1.8 + 17 + 17 ios ios ios-device diff --git a/scripts/hellocodenameone/javascript/pom.xml b/scripts/hellocodenameone/javascript/pom.xml index b9bfdcee29..13f64ecfb7 100644 --- a/scripts/hellocodenameone/javascript/pom.xml +++ b/scripts/hellocodenameone/javascript/pom.xml @@ -14,8 +14,8 @@ UTF-8 - 1.8 - 1.8 + 17 + 17 javascript javascript javascript diff --git a/scripts/hellocodenameone/javase/pom.xml b/scripts/hellocodenameone/javase/pom.xml index 82ff468af0..99fba47492 100644 --- a/scripts/hellocodenameone/javase/pom.xml +++ b/scripts/hellocodenameone/javase/pom.xml @@ -14,8 +14,8 @@ UTF-8 - 1.8 - 1.8 + 17 + 17 javase javase diff --git a/scripts/hellocodenameone/mvnw b/scripts/hellocodenameone/mvnw index 41c0f0c23d..b2a8f18832 100755 --- a/scripts/hellocodenameone/mvnw +++ b/scripts/hellocodenameone/mvnw @@ -72,6 +72,23 @@ if [ -z "$JAVA_HOME" ] ; then fi fi +is_java17_home() { + if [ -z "$1" ] || [ ! -x "$1/bin/java" ]; then + return 1 + fi + "$1/bin/java" -version 2>&1 | head -n 1 | grep -q '"17' +} + +if ! is_java17_home "$JAVA_HOME" ; then + for candidate in /usr/lib/jvm/java-17-openjdk-amd64 /usr/lib/jvm/java-17-openjdk /usr/lib/jvm/jdk-17 /usr/lib/jvm/*17*; do + if is_java17_home "$candidate" ; then + JAVA_HOME="$candidate" + export JAVA_HOME + break + fi + done +fi + if [ -z "$M2_HOME" ] ; then ## resolve links - $0 may be a link to maven's home PRG="$0" diff --git a/scripts/hellocodenameone/mvnw.cmd b/scripts/hellocodenameone/mvnw.cmd index 86115719e5..9b2c7ad636 100644 --- a/scripts/hellocodenameone/mvnw.cmd +++ b/scripts/hellocodenameone/mvnw.cmd @@ -54,6 +54,13 @@ if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" set ERROR_CODE=0 +@REM Prefer JDK 17 when available because this project compiles with target 17. +if not "%JAVA_HOME%" == "" ( + "%JAVA_HOME%\bin\java.exe" -version 2>&1 | findstr /c:"17" >nul +) +if errorlevel 1 if exist "C:\Program Files\Java\jdk-17\bin\java.exe" set "JAVA_HOME=C:\Program Files\Java\jdk-17" +if errorlevel 1 if exist "C:\Program Files\Eclipse Adoptium\jdk-17\bin\java.exe" set "JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-17" + @REM To isolate internal variables from possible post scripts, we use another setlocal @setlocal diff --git a/scripts/hellocodenameone/pom.xml b/scripts/hellocodenameone/pom.xml index 04b3e490c5..9ce3339863 100644 --- a/scripts/hellocodenameone/pom.xml +++ b/scripts/hellocodenameone/pom.xml @@ -22,13 +22,15 @@ 8.0-SNAPSHOT 8.0-SNAPSHOT UTF-8 - 1.8 - 11 + 17 + 17 1.7.11 3.8.0 - 1.8 - 1.8 - 1.8 + 17 + 17 + 17 + 17 + 17 hellocodenameone diff --git a/scripts/hellocodenameone/run.bat b/scripts/hellocodenameone/run.bat index f8b979c32a..b13546476f 100644 --- a/scripts/hellocodenameone/run.bat +++ b/scripts/hellocodenameone/run.bat @@ -5,6 +5,11 @@ setlocal EnableExtensions set MVNW=mvnw.cmd +java -version 2>&1 | findstr /c:"17" >nul +if errorlevel 1 if exist "C:\Program Files\Java\jdk-17" set "JAVA_HOME=C:\Program Files\Java\jdk-17" +if errorlevel 1 if exist "C:\Program Files\Eclipse Adoptium\jdk-17" set "JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-17" +if not "%JAVA_HOME%"=="" set "PATH=%JAVA_HOME%\bin;%PATH%" + SET CMD=%1 if "%CMD%"=="" ( set CMD=simulator diff --git a/scripts/hellocodenameone/run.sh b/scripts/hellocodenameone/run.sh index ef0a12cbe5..1259c7558a 100755 --- a/scripts/hellocodenameone/run.sh +++ b/scripts/hellocodenameone/run.sh @@ -1,6 +1,23 @@ #!/bin/bash MVNW="./mvnw" +JAVA17_HOME="" +if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ] && "$JAVA_HOME/bin/java" -version 2>&1 | head -n 1 | grep -q "\"17"; then + JAVA17_HOME="$JAVA_HOME" +else + for candidate in /usr/lib/jvm/java-17-openjdk-amd64 /usr/lib/jvm/java-17-openjdk /usr/lib/jvm/jdk-17 /usr/lib/jvm/*17*; do + if [ -x "$candidate/bin/java" ] && "$candidate/bin/java" -version 2>&1 | head -n 1 | grep -q "\"17"; then + JAVA17_HOME="$candidate" + break + fi + done +fi + +if [ -n "$JAVA17_HOME" ]; then + export JAVA_HOME="$JAVA17_HOME" + export PATH="$JAVA_HOME/bin:$PATH" +fi + function simulator { "$MVNW" "verify" "-Psimulator" "-DskipTests" "-Dcodename1.platform=javase" "-e" @@ -34,4 +51,4 @@ CMD=$1 if [ "$CMD" == "" ]; then CMD="simulator" fi -"$CMD" \ No newline at end of file +"$CMD" diff --git a/scripts/hellocodenameone/win/pom.xml b/scripts/hellocodenameone/win/pom.xml index 81831387c2..f4776d4cee 100644 --- a/scripts/hellocodenameone/win/pom.xml +++ b/scripts/hellocodenameone/win/pom.xml @@ -14,8 +14,8 @@ UTF-8 - 1.8 - 1.8 + 17 + 17 win win windows-device diff --git a/vm/JavaAPI/src/java/lang/invoke/StringConcatFactory.java b/vm/JavaAPI/src/java/lang/invoke/StringConcatFactory.java new file mode 100644 index 0000000000..140c598ced --- /dev/null +++ b/vm/JavaAPI/src/java/lang/invoke/StringConcatFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores + * CA 94065 USA or visit www.oracle.com if you need additional information or + * have any questions. + */ +package java.lang.invoke; + +/** + * @deprecated this class is used internally for String concatenation compatibility + */ +public final class StringConcatFactory { + private StringConcatFactory() { + } + + public static CallSite makeConcat(MethodHandles.Lookup lookup, String name, + MethodType concatType) { + return null; + } + + public static CallSite makeConcatWithConstants(MethodHandles.Lookup lookup, String name, + MethodType concatType, String recipe, Object... constants) { + return null; + } +}