From 8f8ee51b27c95f0736803386bd5a23e554bc8d3b Mon Sep 17 00:00:00 2001
From: Shai Almog <67850168+shai-almog@users.noreply.github.com>
Date: Mon, 9 Mar 2026 16:36:51 +0200
Subject: [PATCH 1/3] Add experimental Java 17 option to Initializr
---
.../com/codename1/initializr/Initializr.java | 33 ++++++++++++-
.../initializr/model/GeneratorModel.java | 21 +++++++++
.../initializr/model/ProjectOptions.java | 23 ++++++++-
.../model/GeneratorModelMatrixTest.java | 47 +++++++++++++++++--
4 files changed, 116 insertions(+), 8 deletions(-)
diff --git a/scripts/initializr/common/src/main/java/com/codename1/initializr/Initializr.java b/scripts/initializr/common/src/main/java/com/codename1/initializr/Initializr.java
index 8092772f86..87133bcc8a 100644
--- a/scripts/initializr/common/src/main/java/com/codename1/initializr/Initializr.java
+++ b/scripts/initializr/common/src/main/java/com/codename1/initializr/Initializr.java
@@ -50,6 +50,7 @@ public void runApp() {
final boolean[] roundedButtons = new boolean[]{true};
final boolean[] includeLocalizationBundles = new boolean[]{true};
final ProjectOptions.PreviewLanguage[] previewLanguage = new ProjectOptions.PreviewLanguage[]{ProjectOptions.PreviewLanguage.ENGLISH};
+ final ProjectOptions.JavaVersion[] javaVersion = new ProjectOptions.JavaVersion[]{ProjectOptions.JavaVersion.JAVA_8};
final RadioButton[] templateButtons = new RadioButton[Template.values().length];
final SpanLabel summaryLabel = new SpanLabel();
final TemplatePreviewPanel previewPanel = new TemplatePreviewPanel(selectedTemplate[0]);
@@ -69,7 +70,7 @@ public void runApp() {
public void run() {
ProjectOptions options = new ProjectOptions(
selectedThemeMode[0], selectedAccent[0], roundedButtons[0],
- includeLocalizationBundles[0], previewLanguage[0]
+ includeLocalizationBundles[0], previewLanguage[0], javaVersion[0]
);
previewPanel.setTemplate(selectedTemplate[0]);
previewPanel.setOptions(options);
@@ -99,6 +100,7 @@ public void run() {
final Container idePanel = createIdeSelectorPanel(selectedIde, refresh);
final Container themePanel = createThemeOptionsPanel(selectedThemeMode, selectedAccent, roundedButtons, refresh);
final Container localizationPanel = createLocalizationPanel(includeLocalizationBundles, previewLanguage, refresh, previewPanel);
+ final Container javaPanel = createJavaOptionsPanel(javaVersion, refresh);
themePanelRef[0] = themePanel;
final Container settingsPanel = BoxLayout.encloseY(summaryLabel);
@@ -106,6 +108,7 @@ public void run() {
advancedAccordion.addContent("IDE", idePanel);
advancedAccordion.addContent("Theme Customization", themePanel);
advancedAccordion.addContent("Localization", localizationPanel);
+ advancedAccordion.addContent("Java Version", javaPanel);
advancedAccordion.addContent("Current Settings", settingsPanel);
advancedAccordion.setAutoClose(false);
advancedAccordion.setScrollable(false);
@@ -133,7 +136,7 @@ public void run() {
String packageName = packageField.getText() == null ? "" : packageField.getText().trim();
ProjectOptions options = new ProjectOptions(
selectedThemeMode[0], selectedAccent[0], roundedButtons[0],
- includeLocalizationBundles[0], previewLanguage[0]
+ includeLocalizationBundles[0], previewLanguage[0], javaVersion[0]
);
GeneratorModel.create(selectedIde[0], selectedTemplate[0], appName, packageName, options).generate();
});
@@ -314,6 +317,31 @@ private Container createThemeOptionsPanel(ProjectOptions.ThemeMode[] selectedThe
);
}
+
+ private Container createJavaOptionsPanel(ProjectOptions.JavaVersion[] javaVersion, Runnable onSelectionChanged) {
+ Container selector = new Container(new GridLayout(2, 1));
+ selector.setUIID("InitializrChoicesGrid");
+ ButtonGroup group = new ButtonGroup();
+
+ for (ProjectOptions.JavaVersion version : ProjectOptions.JavaVersion.values()) {
+ RadioButton button = new RadioButton(version.label);
+ button.setToggle(true);
+ button.setUIID("InitializrChoice");
+ group.add(button);
+ selector.add(button);
+ if (version == javaVersion[0]) {
+ button.setSelected(true);
+ }
+ button.addActionListener(evt -> {
+ if (button.isSelected()) {
+ javaVersion[0] = version;
+ onSelectionChanged.run();
+ }
+ });
+ }
+ return selector;
+ }
+
private Container createTemplateSelector(Template[] selectedTemplate, RadioButton[] templateButtons, Runnable onSelectionChanged) {
Container selector = new Container(new GridLayout(2, 2));
selector.setUIID("InitializrChoicesGrid");
@@ -509,6 +537,7 @@ private String createSummary(String appName, String packageName, Template templa
+ "Rounded Buttons: " + (options.roundedButtons ? "Yes" : "No") + "\n"
+ "Localization Bundles: " + (options.includeLocalizationBundles ? "Yes" : "No") + "\n"
+ "Preview Language: " + options.previewLanguage.label + "\n"
+ + "Java: " + options.javaVersion.label + "\n"
+ "Kotlin: " + (template.IS_KOTLIN ? "Yes" : "No");
}
diff --git a/scripts/initializr/common/src/main/java/com/codename1/initializr/model/GeneratorModel.java b/scripts/initializr/common/src/main/java/com/codename1/initializr/model/GeneratorModel.java
index e555b41095..e0cf3fa54d 100644
--- a/scripts/initializr/common/src/main/java/com/codename1/initializr/model/GeneratorModel.java
+++ b/scripts/initializr/common/src/main/java/com/codename1/initializr/model/GeneratorModel.java
@@ -179,6 +179,7 @@ private byte[] applyDataReplacements(String targetPath, byte[] sourceData) throw
content = StringUtil.replaceAll(content, "myappname", appName.toLowerCase());
if ("common/codenameone_settings.properties".equals(targetPath)) {
content = replaceProperty(content, "codename1.kotlin", String.valueOf(template.IS_KOTLIN));
+ content = applyJavaVersionSettings(content);
}
if (options.includeLocalizationBundles && isBareTemplate()) {
content = injectLocalizationBootstrap(targetPath, content);
@@ -186,6 +187,9 @@ private byte[] applyDataReplacements(String targetPath, byte[] sourceData) throw
if (isBareTemplate() && "common/src/main/css/theme.css".equals(targetPath)) {
content += buildThemeOverrides();
}
+ if ("common/pom.xml".equals(targetPath)) {
+ content = applyJavaVersionToPom(content);
+ }
if ("pom.xml".equals(targetPath)) {
content = replaceTagValue(content, "cn1.plugin.version", CN1_PLUGIN_VERSION);
}
@@ -196,6 +200,23 @@ private byte[] applyDataReplacements(String targetPath, byte[] sourceData) throw
}
+
+ private String applyJavaVersionSettings(String content) {
+ if (options.javaVersion == ProjectOptions.JavaVersion.JAVA_17_EXPERIMENTAL) {
+ content = replaceProperty(content, "codename1.arg.java.version", "17");
+ }
+ return content;
+ }
+
+ private String applyJavaVersionToPom(String content) {
+ if (options.javaVersion != ProjectOptions.JavaVersion.JAVA_17_EXPERIMENTAL) {
+ return content;
+ }
+ content = StringUtil.replaceAll(content, "1.8", "17");
+ content = StringUtil.replaceAll(content, "1.8", "17");
+ return content;
+ }
+
private String injectLocalizationBootstrap(String targetPath, String content) {
String javaMainPath = "common/src/main/java/" + packageName.replace('.', '/') + "/" + appName + ".java";
String kotlinMainPath = "common/src/main/kotlin/" + packageName.replace('.', '/') + "/" + appName + ".kt";
diff --git a/scripts/initializr/common/src/main/java/com/codename1/initializr/model/ProjectOptions.java b/scripts/initializr/common/src/main/java/com/codename1/initializr/model/ProjectOptions.java
index 7595fa1fc3..d33361ec9d 100644
--- a/scripts/initializr/common/src/main/java/com/codename1/initializr/model/ProjectOptions.java
+++ b/scripts/initializr/common/src/main/java/com/codename1/initializr/model/ProjectOptions.java
@@ -43,22 +43,41 @@ public enum Accent {
ORANGE
}
+ public enum JavaVersion {
+ JAVA_8("Java 8"),
+ JAVA_17_EXPERIMENTAL("Java 17 (Experimental)");
+
+ public final String label;
+
+ JavaVersion(String label) {
+ this.label = label;
+ }
+
+ @Override
+ public String toString() {
+ return label;
+ }
+ }
+
public final ThemeMode themeMode;
public final Accent accent;
public final boolean roundedButtons;
public final boolean includeLocalizationBundles;
public final PreviewLanguage previewLanguage;
+ public final JavaVersion javaVersion;
public ProjectOptions(ThemeMode themeMode, Accent accent, boolean roundedButtons,
- boolean includeLocalizationBundles, PreviewLanguage previewLanguage) {
+ boolean includeLocalizationBundles, PreviewLanguage previewLanguage,
+ JavaVersion javaVersion) {
this.themeMode = themeMode;
this.accent = accent;
this.roundedButtons = roundedButtons;
this.includeLocalizationBundles = includeLocalizationBundles;
this.previewLanguage = previewLanguage == null ? PreviewLanguage.ENGLISH : previewLanguage;
+ this.javaVersion = javaVersion == null ? JavaVersion.JAVA_8 : javaVersion;
}
public static ProjectOptions defaults() {
- return new ProjectOptions(ThemeMode.LIGHT, Accent.DEFAULT, true, true, PreviewLanguage.ENGLISH);
+ return new ProjectOptions(ThemeMode.LIGHT, Accent.DEFAULT, true, true, PreviewLanguage.ENGLISH, JavaVersion.JAVA_8);
}
}
diff --git a/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelMatrixTest.java b/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelMatrixTest.java
index df6d831423..fe4c56d105 100644
--- a/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelMatrixTest.java
+++ b/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelMatrixTest.java
@@ -21,9 +21,30 @@ public boolean runTest() throws Exception {
validateCombination(template, ide);
}
}
+ validateExperimentalJava17Generation();
return true;
}
+
+ private void validateExperimentalJava17Generation() throws Exception {
+ String mainClassName = "DemoExperimentalJava17";
+ String packageName = "com.acme.experimental.java17";
+ ProjectOptions options = new ProjectOptions(
+ ProjectOptions.ThemeMode.LIGHT,
+ ProjectOptions.Accent.DEFAULT,
+ true,
+ true,
+ ProjectOptions.PreviewLanguage.ENGLISH,
+ ProjectOptions.JavaVersion.JAVA_17_EXPERIMENTAL
+ );
+
+ byte[] zipData = createProjectZip(IDE.INTELLIJ, Template.BAREBONES, mainClassName, packageName, options);
+ Map entries = readZipEntries(zipData);
+
+ assertCommonPom(entries, Template.BAREBONES, packageName, mainClassName, true);
+ assertSettings(entries, Template.BAREBONES, packageName, mainClassName, true);
+ }
+
private void validateCombination(Template template, IDE ide) throws Exception {
String mainClassName = "Demo" + template.ordinal() + ide.ordinal() + "App";
String packageName = "com.acme.t" + template.ordinal() + ".i" + ide.ordinal();
@@ -34,8 +55,8 @@ private void validateCombination(Template template, IDE ide) throws Exception {
assertIdeFiles(ide, entries, mainClassName);
assertGitIgnore(entries);
assertRootPom(entries, packageName, mainClassName);
- assertCommonPom(entries, template, packageName, mainClassName);
- assertSettings(entries, template, packageName, mainClassName);
+ assertCommonPom(entries, template, packageName, mainClassName, false);
+ assertSettings(entries, template, packageName, mainClassName, false);
assertMainSourceFile(entries, template, packageName, mainClassName);
assertLocalizationBundles(entries, template);
assertNoTemplatePlaceholders(entries, template);
@@ -47,6 +68,12 @@ private static byte[] createProjectZip(IDE ide, Template template, String appNam
return output.toByteArray();
}
+ private static byte[] createProjectZip(IDE ide, Template template, String appName, String packageName, ProjectOptions options) throws IOException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ GeneratorModel.create(ide, template, appName, packageName, options).writeProjectZip(output);
+ return output.toByteArray();
+ }
+
private static Map readZipEntries(byte[] zipData) throws IOException {
Map entries = new HashMap();
ByteArrayInputStream input = new ByteArrayInputStream(zipData);
@@ -97,13 +124,20 @@ private void assertRootPom(Map entries, String packageName, Stri
assertFalse(pom.indexOf("myappname") >= 0, "Root pom still contains placeholder app name");
}
- private void assertCommonPom(Map entries, Template template, String packageName, String mainClassName) {
+ private void assertCommonPom(Map entries, Template template, String packageName, String mainClassName, boolean expectJava17) {
String pom = getText(entries, "common/pom.xml");
assertContains(pom, packageName, "Common pom should include package");
assertContains(pom, mainClassName.toLowerCase(), "Common pom should include app artifact");
assertContains(pom, "codenameone-javase", "Common pom should include codenameone-javase test dependency");
assertContains(pom, "serializer", "Common pom should include xalan serializer for CN1 generate-gui-sources");
assertContains(pom, "2.7.3", "Common pom should pin serializer version expected by CN1 plugin classpath");
+ if (expectJava17) {
+ assertContains(pom, "17", "Common pom should use Java 17 source when selected");
+ assertContains(pom, "17", "Common pom should use Java 17 target when selected");
+ } else {
+ assertContains(pom, "1.8", "Common pom should default to Java 8 source");
+ assertContains(pom, "1.8", "Common pom should default to Java 8 target");
+ }
if (template == Template.GRUB) {
assertContains(pom, "" + mainClassName.toLowerCase() + "-CodeRAD", "Grub common pom should include local CodeRAD cn1lib dependency");
assertContains(pom, "1.0-SNAPSHOT", "Grub common pom should use local snapshot CodeRAD cn1lib");
@@ -117,12 +151,17 @@ private void assertCommonPom(Map entries, Template template, Str
assertFalse(pom.indexOf("myappname") >= 0, "Common pom still contains placeholder app name");
}
- private void assertSettings(Map entries, Template template, String packageName, String mainClassName) {
+ private void assertSettings(Map entries, Template template, String packageName, String mainClassName, boolean expectJava17) {
String settings = getText(entries, "common/codenameone_settings.properties");
assertContains(settings, "codename1.packageName=" + packageName, "Settings should include requested package");
assertContains(settings, "codename1.mainName=" + mainClassName, "Settings should include requested main class");
assertContains(settings, "codename1.displayName=" + mainClassName, "Settings should include requested display name");
assertContains(settings, "codename1.kotlin=" + String.valueOf(template.IS_KOTLIN), "Settings should include template kotlin flag");
+ if (expectJava17) {
+ assertContains(settings, "codename1.arg.java.version=17", "Settings should include Java 17 version when selected");
+ } else {
+ assertFalse(settings.indexOf("codename1.arg.java.version=17") >= 0, "Settings should not force Java 17 by default");
+ }
}
private void assertMainSourceFile(Map entries, Template template, String packageName, String mainClassName) {
From 633f95074faabe533f908cf97650adc6165f4b5c Mon Sep 17 00:00:00 2001
From: Shai Almog <67850168+shai-almog@users.noreply.github.com>
Date: Mon, 9 Mar 2026 16:54:48 +0200
Subject: [PATCH 2/3] Add integration build test for Java 8/11 and Java 17
generation
---
.../GeneratorModelIntegrationBuildTest.java | 233 ++++++++++++++++++
1 file changed, 233 insertions(+)
create mode 100644 scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelIntegrationBuildTest.java
diff --git a/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelIntegrationBuildTest.java b/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelIntegrationBuildTest.java
new file mode 100644
index 0000000000..3c30b0a7e6
--- /dev/null
+++ b/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelIntegrationBuildTest.java
@@ -0,0 +1,233 @@
+package com.codename1.initializr.model;
+
+import com.codename1.io.Util;
+import com.codename1.testing.AbstractTest;
+import net.sf.zipme.ZipEntry;
+import net.sf.zipme.ZipInputStream;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Integration-oriented test that generates real projects and attempts a Maven compile
+ * using selected JDK homes.
+ */
+public class GeneratorModelIntegrationBuildTest extends AbstractTest {
+ @Override
+ public boolean runTest() throws Exception {
+ Path java8Or11 = findJava8Or11Home();
+ Path java17 = findJavaHomeForMajor(17);
+
+ if (java8Or11 == null) {
+ System.out.println("[WARN] Skipping Java 8/11 integration build check. No JDK 8 or 11 found.");
+ } else {
+ buildGeneratedProject(ProjectOptions.JavaVersion.JAVA_8, java8Or11, "java8-or-11");
+ }
+
+ if (java17 == null) {
+ System.out.println("[WARN] Skipping Java 17 integration build check. No JDK 17 found.");
+ } else {
+ buildGeneratedProject(ProjectOptions.JavaVersion.JAVA_17_EXPERIMENTAL, java17, "java17");
+ }
+
+ return true;
+ }
+
+ private void buildGeneratedProject(ProjectOptions.JavaVersion version, Path javaHome, String suffix) throws Exception {
+ String appName = "Integration" + suffix.replace("-", "") + "App";
+ String packageName = "com.acme.initializr." + suffix.replace("-", "");
+
+ ProjectOptions options = new ProjectOptions(
+ ProjectOptions.ThemeMode.LIGHT,
+ ProjectOptions.Accent.DEFAULT,
+ true,
+ true,
+ ProjectOptions.PreviewLanguage.ENGLISH,
+ version
+ );
+
+ byte[] zip = createProjectZip(options, appName, packageName);
+ Path projectDir = Files.createTempDirectory("initializr-integration-" + suffix + "-");
+ Path homeDir = Files.createTempDirectory("initializr-home-" + suffix + "-");
+ ensureCodenameOneHome(homeDir);
+ unzipProject(zip, projectDir);
+
+ int exitCode = runMavenCompile(projectDir, homeDir, javaHome);
+ assertEquals(0, exitCode, "Generated project should compile with selected JDK. Version=" + version.label);
+ }
+
+ private byte[] createProjectZip(ProjectOptions options, String appName, String packageName) throws IOException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ GeneratorModel.create(IDE.INTELLIJ, Template.BAREBONES, appName, packageName, options).writeProjectZip(output);
+ return output.toByteArray();
+ }
+
+ private int runMavenCompile(Path projectDir, Path homeDir, Path javaHome) throws Exception {
+ ProcessBuilder pb = new ProcessBuilder(
+ "mvn",
+ "-f", "common/pom.xml",
+ "-DskipTests=true",
+ "-Dcodename1.platform=javase",
+ "-Duser.home=" + homeDir.toString(),
+ "compile"
+ );
+ pb.directory(projectDir.toFile());
+ pb.redirectErrorStream(true);
+
+ Map env = pb.environment();
+ env.put("JAVA_HOME", javaHome.toString());
+ env.put("PATH", javaHome.resolve("bin") + File.pathSeparator + env.get("PATH"));
+
+ List output = new ArrayList();
+ Process process = pb.start();
+ try (InputStream in = process.getInputStream()) {
+ java.io.BufferedReader r = new java.io.BufferedReader(new java.io.InputStreamReader(in));
+ String line;
+ while ((line = r.readLine()) != null) {
+ output.add(line);
+ }
+ }
+ int exit = process.waitFor();
+ if (exit != 0) {
+ StringBuilder sb = new StringBuilder();
+ for (String line : output) {
+ if (sb.length() > 12000) {
+ sb.append("\n...[truncated]");
+ break;
+ }
+ sb.append(line).append('\n');
+ }
+ System.out.println(sb.toString());
+ }
+ return exit;
+ }
+
+ private void ensureCodenameOneHome(Path homeDir) throws IOException {
+ Path cn1Dir = homeDir.resolve(".codenameone");
+ Files.createDirectories(cn1Dir);
+ Files.write(cn1Dir.resolve("guibuilder.jar"), new byte[0]);
+ Files.write(homeDir.resolve("CodeNameOneBuildClient.jar"), new byte[0]);
+ }
+
+ private void unzipProject(byte[] zipData, Path destination) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(zipData);
+ ZipInputStream zis = new ZipInputStream(input);
+ try {
+ ZipEntry entry = zis.getNextEntry();
+ while (entry != null) {
+ if (!entry.isDirectory()) {
+ Path target = destination.resolve(entry.getName());
+ Path parent = target.getParent();
+ if (parent != null) {
+ Files.createDirectories(parent);
+ }
+ FileOutputStream fos = new FileOutputStream(target.toFile());
+ try {
+ Util.copyNoClose(zis, fos, 8192);
+ } finally {
+ fos.close();
+ }
+ }
+ zis.closeEntry();
+ entry = zis.getNextEntry();
+ }
+ } finally {
+ zis.close();
+ input.close();
+ }
+ }
+
+ private Path findJava8Or11Home() throws Exception {
+ Path java11 = findJavaHomeForMajor(11);
+ if (java11 != null) {
+ return java11;
+ }
+ return findJavaHomeForMajor(8);
+ }
+
+ private Path findJavaHomeForMajor(int major) throws Exception {
+ String envName = "INITIALIZR_JDK" + major + "_HOME";
+ String envValue = System.getenv(envName);
+ if (envValue != null && envValue.length() > 0) {
+ Path candidate = Paths.get(envValue);
+ if (looksLikeJdkHome(candidate) && javaMajor(candidate) == major) {
+ return candidate;
+ }
+ }
+
+ List candidates = new ArrayList();
+ String currentJavaHome = System.getProperty("java.home");
+ if (currentJavaHome != null) {
+ candidates.add(Paths.get(currentJavaHome).getParent());
+ candidates.add(Paths.get(currentJavaHome));
+ }
+ collectJvmCandidates(candidates, "/usr/lib/jvm");
+ collectJvmCandidates(candidates, "/Library/Java/JavaVirtualMachines");
+ collectJvmCandidates(candidates, "C:\\Program Files\\Java");
+
+ for (Path candidate : candidates) {
+ if (!looksLikeJdkHome(candidate)) {
+ continue;
+ }
+ if (javaMajor(candidate) == major) {
+ return candidate;
+ }
+ Path nestedHome = candidate.resolve("Contents/Home");
+ if (looksLikeJdkHome(nestedHome) && javaMajor(nestedHome) == major) {
+ return nestedHome;
+ }
+ }
+
+ return null;
+ }
+
+ private void collectJvmCandidates(List out, String directory) throws IOException {
+ Path root = Paths.get(directory);
+ if (!Files.isDirectory(root)) {
+ return;
+ }
+ out.add(root);
+ try (java.util.stream.Stream stream = Files.list(root)) {
+ stream.forEach(out::add);
+ }
+ }
+
+ private boolean looksLikeJdkHome(Path candidate) {
+ return candidate != null && Files.isRegularFile(candidate.resolve("bin").resolve("java"));
+ }
+
+ private int javaMajor(Path javaHome) throws Exception {
+ ProcessBuilder pb = new ProcessBuilder(javaHome.resolve("bin").resolve("java").toString(), "-version");
+ pb.redirectErrorStream(true);
+ Process process = pb.start();
+ StringBuilder out = new StringBuilder();
+ try (InputStream in = process.getInputStream()) {
+ int b;
+ while ((b = in.read()) != -1) {
+ out.append((char) b);
+ }
+ }
+ process.waitFor();
+
+ String text = out.toString().toLowerCase(Locale.ROOT);
+ if (text.indexOf(" version \"1.8") >= 0) {
+ return 8;
+ }
+ java.util.regex.Matcher m = java.util.regex.Pattern.compile("version \\\"([0-9]+)").matcher(text);
+ if (m.find()) {
+ return Integer.parseInt(m.group(1));
+ }
+ return -1;
+ }
+}
From 25ba55b46da914e3d791282b7e5c8a57f6776706 Mon Sep 17 00:00:00 2001
From: Shai Almog <67850168+shai-almog@users.noreply.github.com>
Date: Mon, 9 Mar 2026 17:07:58 +0200
Subject: [PATCH 3/3] Fix integration test assertion to use AbstractTest API
---
.../initializr/model/GeneratorModelIntegrationBuildTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelIntegrationBuildTest.java b/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelIntegrationBuildTest.java
index 3c30b0a7e6..5779d205f6 100644
--- a/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelIntegrationBuildTest.java
+++ b/scripts/initializr/common/src/test/java/com/codename1/initializr/model/GeneratorModelIntegrationBuildTest.java
@@ -64,7 +64,7 @@ private void buildGeneratedProject(ProjectOptions.JavaVersion version, Path java
unzipProject(zip, projectDir);
int exitCode = runMavenCompile(projectDir, homeDir, javaHome);
- assertEquals(0, exitCode, "Generated project should compile with selected JDK. Version=" + version.label);
+ assertTrue(exitCode == 0, "Generated project should compile with selected JDK. Version=" + version.label + " | exitCode=" + exitCode);
}
private byte[] createProjectZip(ProjectOptions options, String appName, String packageName) throws IOException {