This is an automated email from the ASF dual-hosted git repository.
tkobayas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new fe01cf8434 [incubator-kie-drools-6561] Update supported java versions
> 19 for DRL compilation (#6569)
fe01cf8434 is described below
commit fe01cf8434d59c8feb3b2404f1a8b0eb0b595ef8
Author: Toshiya Kobayashi <[email protected]>
AuthorDate: Fri Jan 30 18:31:10 2026 +0900
[incubator-kie-drools-6561] Update supported java versions > 19 for DRL
compilation (#6569)
* [incubator-kie-drools-6561] Update supported java versions > 19
- Add java versions for DRL java compilation
- Upgrade eclipse-ecj from 3.33.0 to 3.44.0
- Java 21 syntax test
- Not support dialect "mvel" yet
- drools-mvel is deprecated
- drools-model/mvel.jj is based on Java 16 now. Enhancement would be a
separate issue/PR
- WIP
* add native compile test and ecj compile test
* refactor to remove duplicate java version definitions
* Remove java version 1.7 check because eclipse-ecj 3.44.0 supports 1.8 and
higher
* add kie-maven-plugin kjar test
* Apply copilot suggestion. Remove unnecessary test for java 1.6
* default is 17
* further refactoring to reduce duplication
* ensure language level normalization
---
build-parent/pom.xml | 2 +-
.../java/org/drools/ecj/EclipseJavaCompiler.java | 12 ++++
.../drools/ecj/EclipseJavaCompilerSettings.java | 63 ++---------------
.../java/org/drools/ecj/JavaCompilerI18NTest.java | 4 +-
.../test/java/org/drools/ecj/Jdk21SyntaxTest.java | 81 ++++++++++++++++++++++
.../codegen/execmodel/generator/DrlxParseUtil.java | 6 +-
.../codegen/execmodel/jdk/Jdk21SyntaxTest.java | 68 ++++++++++++++++++
.../compilers/NativeJavaCompilerSettingsTest.java | 8 +--
.../integrationtests/SwitchOverStringTest.java | 19 +----
.../invoker.properties | 29 ++++++++
.../kie-maven-plugin-test-kjar-16-java21/pom.xml | 71 +++++++++++++++++++
.../src/main/resources/META-INF/kmodule.xml | 27 ++++++++
.../src/main/resources/org/java21test/rules.drl | 34 +++++++++
.../maven/plugin/ittests/Java21SyntaxTestIT.java | 73 +++++++++++++++++++
.../kie/memorycompiler/JavaCompilerFactory.java | 5 +-
.../kie/memorycompiler/JavaCompilerSettings.java | 6 ++
.../org/kie/memorycompiler/JavaConfiguration.java | 48 ++++++-------
.../kie/memorycompiler/KieMemoryCompilerTest.java | 32 +++++++++
18 files changed, 477 insertions(+), 111 deletions(-)
diff --git a/build-parent/pom.xml b/build-parent/pom.xml
index f6a6f8406e..a0262d7fe5 100644
--- a/build-parent/pom.xml
+++ b/build-parent/pom.xml
@@ -94,7 +94,7 @@
<version.org.apache.poi>5.4.1</version.org.apache.poi>
<version.org.apache.tomcat.tomcat-dbcp>10.1.48</version.org.apache.tomcat.tomcat-dbcp>
<version.org.assertj>3.27.3</version.org.assertj>
- <version.org.eclipse.jdt>3.33.0</version.org.eclipse.jdt>
+ <version.org.eclipse.jdt>3.44.0</version.org.eclipse.jdt>
<version.org.freemarker>2.3.32</version.org.freemarker>
<version.org.glassfish.jaxb>4.0.6</version.org.glassfish.jaxb>
<!--This needs to be in sync with JUnit-->
diff --git a/drools-ecj/src/main/java/org/drools/ecj/EclipseJavaCompiler.java
b/drools-ecj/src/main/java/org/drools/ecj/EclipseJavaCompiler.java
index 8cc9cd652f..5fc08c86a5 100644
--- a/drools-ecj/src/main/java/org/drools/ecj/EclipseJavaCompiler.java
+++ b/drools-ecj/src/main/java/org/drools/ecj/EclipseJavaCompiler.java
@@ -45,6 +45,8 @@ import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.kie.memorycompiler.AbstractJavaCompiler;
import org.kie.memorycompiler.CompilationProblem;
@@ -156,6 +158,16 @@ public final class EclipseJavaCompiler extends
AbstractJavaCompiler {
public boolean ignoreOptionalProblems() {
return true;
}
+
+ @Override
+ public char[] getModuleName() {
+ return ModuleBinding.UNNAMED;
+ }
+
+ @Override
+ public ModuleBinding module(LookupEnvironment environment) {
+ return environment.getModule(ModuleBinding.UNNAMED);
+ }
}
diff --git
a/drools-ecj/src/main/java/org/drools/ecj/EclipseJavaCompilerSettings.java
b/drools-ecj/src/main/java/org/drools/ecj/EclipseJavaCompilerSettings.java
index d56c6b2b25..28b25b096c 100644
--- a/drools-ecj/src/main/java/org/drools/ecj/EclipseJavaCompilerSettings.java
+++ b/drools-ecj/src/main/java/org/drools/ecj/EclipseJavaCompilerSettings.java
@@ -24,30 +24,12 @@ import java.util.Map;
import org.kie.memorycompiler.JavaCompilerSettings;
/**
- * Native Eclipse compiler settings
+ * Native Eclipse compiler settings.
+ *
+ * Supported Java version strings are defined in {@link
org.kie.memorycompiler.JavaConfiguration#LANGUAGE_LEVELS}.
+ * Version strings are passed through to the Eclipse compiler as-is.
*/
public final class EclipseJavaCompilerSettings extends JavaCompilerSettings {
-
- //copied from org.eclipse.jdt.internal.compiler.impl.CompilerOptions as we
can't access it
- public static final String CompilerOptions_VERSION_1_1 = "1.1";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_1_2 = "1.2";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_1_3 = "1.3";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_1_4 = "1.4";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_JSR14 = "jsr14";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_CLDC1_1 = "cldc1.1";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_1_5 = "1.5";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_1_6 = "1.6";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_1_7 = "1.7";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_1_8 = "1.8";
//$NON-NLS-1$
- public static final String CompilerOptions_VERSION_9 = "9"; //$NON-NLS-1$
- public static final String CompilerOptions_VERSION_10 = "10"; //$NON-NLS-1$
- public static final String CompilerOptions_VERSION_11 = "11"; //$NON-NLS-1$
- public static final String CompilerOptions_VERSION_12 = "12"; //$NON-NLS-1$
- public static final String CompilerOptions_VERSION_15 = "15"; //$NON-NLS-1$
- public static final String CompilerOptions_VERSION_16 = "16"; //$NON-NLS-1$
- public static final String CompilerOptions_VERSION_17 = "17"; //$NON-NLS-1$
- public static final String CompilerOptions_VERSION_18 = "18"; //$NON-NLS-1$
- public static final String CompilerOptions_VERSION_19 = "19"; //$NON-NLS-1$
public static final String CompilerOptions_GENERATE =
"generate";//$NON-NLS-1$
public static final String CompilerOptions_DO_NOT_GENERATE = "do not
generate"; //$NON-NLS-1$
@@ -90,46 +72,15 @@ public final class EclipseJavaCompilerSettings extends
JavaCompilerSettings {
defaultEclipseSettings.putAll(pMap);
}
- private static Map nativeVersions = new HashMap() {
- private static final long serialVersionUID = 510l;
- {
- put("1.1", CompilerOptions_VERSION_1_1);
- put("1.2", CompilerOptions_VERSION_1_2);
- put("1.3", CompilerOptions_VERSION_1_3);
- put("1.4", CompilerOptions_VERSION_1_4);
- put("1.5", CompilerOptions_VERSION_1_5);
- put("1.6", CompilerOptions_VERSION_1_6);
- put("1.7", CompilerOptions_VERSION_1_7);
- put("1.8", CompilerOptions_VERSION_1_8);
- put("9", CompilerOptions_VERSION_9);
- put("10", CompilerOptions_VERSION_10);
- put("11", CompilerOptions_VERSION_11);
- put("12", CompilerOptions_VERSION_12);
- put("15", CompilerOptions_VERSION_15);
- put("16", CompilerOptions_VERSION_16);
- put("17", CompilerOptions_VERSION_17);
- put("18", CompilerOptions_VERSION_18);
- put("19", CompilerOptions_VERSION_19);
- }};
-
- private String toNativeVersion( final String pVersion ) {
- final String nativeVersion = (String) nativeVersions.get(pVersion);
-
- if (nativeVersion == null) {
- throw new RuntimeException("unknown version " + pVersion);
- }
-
- return nativeVersion;
- }
Map toNativeSettings() {
final Map map = new HashMap(defaultEclipseSettings);
map.put(CompilerOptions_OPTION_SuppressWarnings,
isWarnings()?CompilerOptions_GENERATE:CompilerOptions_DO_NOT_GENERATE);
map.put(CompilerOptions_OPTION_ReportDeprecation,
isDeprecations()?CompilerOptions_GENERATE:CompilerOptions_DO_NOT_GENERATE);
- map.put(CompilerOptions_OPTION_TargetPlatform,
toNativeVersion(getTargetVersion()));
- map.put(CompilerOptions_OPTION_Source,
toNativeVersion(getSourceVersion()));
- map.put(CompilerOptions_OPTION_Compliance,
toNativeVersion(getSourceVersion()));
+ map.put(CompilerOptions_OPTION_TargetPlatform, getTargetVersion());
+ map.put(CompilerOptions_OPTION_Source, getSourceVersion());
+ map.put(CompilerOptions_OPTION_Compliance, getSourceVersion());
map.put(CompilerOptions_OPTION_Encoding, getSourceEncoding());
return map;
diff --git a/drools-ecj/src/test/java/org/drools/ecj/JavaCompilerI18NTest.java
b/drools-ecj/src/test/java/org/drools/ecj/JavaCompilerI18NTest.java
index ab364f90ff..2262ffc681 100644
--- a/drools-ecj/src/test/java/org/drools/ecj/JavaCompilerI18NTest.java
+++ b/drools-ecj/src/test/java/org/drools/ecj/JavaCompilerI18NTest.java
@@ -43,8 +43,8 @@ public class JavaCompilerI18NTest {
reader.add(fileStr, fileContents.getBytes());
EclipseJavaCompilerSettings settings = new
EclipseJavaCompilerSettings();
- settings.setSourceVersion( "1.5" );
- settings.setTargetVersion( "1.5" );
+ settings.setSourceVersion( "17" );
+ settings.setTargetVersion( "17" );
EclipseJavaCompiler compiler = new EclipseJavaCompiler( settings, "" );
CompilationResult res = compiler.compile( classes.toArray( new
String[classes.size()] ), reader, store );
assertThat(0).isEqualTo(res.getErrors().length);
diff --git a/drools-ecj/src/test/java/org/drools/ecj/Jdk21SyntaxTest.java
b/drools-ecj/src/test/java/org/drools/ecj/Jdk21SyntaxTest.java
new file mode 100644
index 0000000000..510c446199
--- /dev/null
+++ b/drools-ecj/src/test/java/org/drools/ecj/Jdk21SyntaxTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.ecj;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledForJreRange;
+import org.junit.jupiter.api.condition.JRE;
+import org.kie.memorycompiler.CompilationResult;
+import org.kie.memorycompiler.KieMemoryCompiler;
+import org.kie.memorycompiler.resources.MemoryResourceReader;
+import org.kie.memorycompiler.resources.MemoryResourceStore;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@EnabledForJreRange(min = JRE.JAVA_21)
+class Jdk21SyntaxTest {
+
+ private static final String JDK21_TYPE_SWITCH_CLASS = """
+ package org.kie.memorycompiler;
+
+ public class ExampleClass {
+
+ public String typeSwitch(Object obj) {
+ return switch (obj) {
+ case Integer i -> "int: " + i;
+ case String s -> "string: " + s;
+ default -> "other";
+ };
+ }
+ }
+ """;
+
+ @Test
+ void jdk21typeSwitch() throws Exception {
+ String fileStr = "org/kie/memorycompiler/ExampleClass.java";
+ List<String> classes = new ArrayList<>();
+ classes.add(fileStr);
+
+ MemoryResourceReader reader = new MemoryResourceReader();
+ MemoryResourceStore store = new MemoryResourceStore();
+
+ reader.add(fileStr, JDK21_TYPE_SWITCH_CLASS.getBytes());
+
+ EclipseJavaCompilerSettings settings = new
EclipseJavaCompilerSettings();
+ settings.setSourceVersion("21");
+ settings.setTargetVersion("21");
+ EclipseJavaCompiler compiler = new EclipseJavaCompiler(settings, "");
+ CompilationResult res = compiler.compile(classes.toArray(new
String[classes.size()]), reader, store);
+ assertThat(res.getErrors()).isEmpty();
+
+ byte[] byteCode = store.getResources().values().iterator().next();
+ KieMemoryCompiler.MemoryCompilerClassLoader
kieMemoryCompilerClassLoader = new
KieMemoryCompiler.MemoryCompilerClassLoader(this.getClass().getClassLoader());
+ String className = "org.kie.memorycompiler.ExampleClass";
+ kieMemoryCompilerClassLoader.addCode(className, byteCode);
+ Class<?> exampleClazz =
kieMemoryCompilerClassLoader.loadClass(className);
+ Object instance =
exampleClazz.getDeclaredConstructors()[0].newInstance();
+ Method typeSwitchMethod = exampleClazz.getMethod("typeSwitch",
Object.class);
+ Object result = typeSwitchMethod.invoke(instance, 51);
+ assertThat(result).isEqualTo("int: 51");
+ }
+}
diff --git
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DrlxParseUtil.java
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DrlxParseUtil.java
index d06c9aa663..d29fe8f592 100644
---
a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DrlxParseUtil.java
+++
b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DrlxParseUtil.java
@@ -124,6 +124,10 @@ import static org.drools.util.MethodUtils.findMethod;
public class DrlxParseUtil {
+ // Regardless of the configured language level, always parse with the
highest level at this point,
+ // so compiler will report any incompatible syntax at the compilation
phase.
+ public static final ParserConfiguration.LanguageLevel
PARSABLE_LANGUAGE_LEVEL = ParserConfiguration.LanguageLevel.JAVA_21;
+
public static final String THIS_PLACEHOLDER = "_this";
private static final ConcurrentMap<String, Method> ACCESSOR_CACHE = new
ConcurrentHashMap<>();
@@ -497,7 +501,7 @@ public class DrlxParseUtil {
public static BlockStmt parseBlock(String ruleConsequenceAsBlock) {
ParserConfiguration parserConfiguration = new ParserConfiguration();
-
parserConfiguration.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_15);
+ parserConfiguration.setLanguageLevel(PARSABLE_LANGUAGE_LEVEL);
com.github.javaparser.JavaParser javaParser = new
com.github.javaparser.JavaParser(parserConfiguration);
ParseResult<BlockStmt> blockStmtParseResult =
javaParser.parseBlock(String.format("{%n%s%n}", ruleConsequenceAsBlock));
diff --git
a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/jdk/Jdk21SyntaxTest.java
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/jdk/Jdk21SyntaxTest.java
new file mode 100644
index 0000000000..fff0594986
--- /dev/null
+++
b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/jdk/Jdk21SyntaxTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.codegen.execmodel.jdk;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.model.codegen.execmodel.BaseModelTest;
+import org.junit.jupiter.api.condition.EnabledForJreRange;
+import org.junit.jupiter.api.condition.JRE;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.kie.api.runtime.KieSession;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test class to verify syntax features introduced in JDK 21
+ * Note: at the moment, this class tests only dialect "java" (default),
+ * because drools-mvel (non-exec-model) is deprecated,
+ * and drools-model/mvel.jj (exec-model) enhancement would be a separate task.
+ */
+@EnabledForJreRange(min = JRE.JAVA_21)
+class Jdk21SyntaxTest extends BaseModelTest {
+
+ @ParameterizedTest
+ @MethodSource("parameters")
+ void testTypeSwitch(RUN_TYPE runType) {
+ String str = """
+ global java.util.List results;
+
+ rule R1
+ when
+ $obj : Object()
+ then
+ String message = switch ($obj) {
+ case Integer i -> "int: " + i;
+ case String s -> "string: " + s;
+ default -> "other";
+ };
+ results.add(message);
+ end
+ """;
+
+ KieSession ksession = getKieSession(runType, str);
+ List<String> results = new ArrayList<>();
+ ksession.setGlobal("results", results);
+ ksession.insert(51);
+ ksession.fireAllRules();
+ assertThat(results).containsExactly("int: 51");
+ }
+}
diff --git
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/commons/jci/compilers/NativeJavaCompilerSettingsTest.java
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/commons/jci/compilers/NativeJavaCompilerSettingsTest.java
index 6f65e7ec29..c0f3ce19ba 100644
---
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/commons/jci/compilers/NativeJavaCompilerSettingsTest.java
+++
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/commons/jci/compilers/NativeJavaCompilerSettingsTest.java
@@ -47,8 +47,8 @@ public class NativeJavaCompilerSettingsTest {
settings.setWarnings(true);
settings.setDeprecations(true);
settings.setSourceEncoding("My-Custom-Encoding");
- settings.setSourceVersion("1.9");
- settings.setTargetVersion("1.9");
+ settings.setSourceVersion("9");
+ settings.setTargetVersion("9");
List<String> options = settings.toOptionsList();
assertThat(options).hasSize(9);
@@ -56,8 +56,8 @@ public class NativeJavaCompilerSettingsTest {
assertThat(options).contains("-Xlint:all");
assertThat(options).contains("-deprecation");
// check the order is correct, value of the option needs to be right
after the option name
- assertThat(options).contains("1.9",
Index.atIndex(options.indexOf("-source") + 1));
- assertThat(options).contains("1.9",
Index.atIndex(options.indexOf("-target") + 1));
+ assertThat(options).contains("9",
Index.atIndex(options.indexOf("-source") + 1));
+ assertThat(options).contains("9",
Index.atIndex(options.indexOf("-target") + 1));
assertThat(options).contains("My-Custom-Encoding",
Index.atIndex(options.indexOf("-encoding") + 1));
}
diff --git
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/SwitchOverStringTest.java
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/SwitchOverStringTest.java
index f362d2716d..fac3c2079b 100644
---
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/SwitchOverStringTest.java
+++
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/SwitchOverStringTest.java
@@ -59,9 +59,8 @@ public class SwitchOverStringTest {
@ParameterizedTest(name = "KieBase type={0}")
@MethodSource("parameters")
public void
testCompileSwitchOverStringWithLngLevel17(KieBaseTestConfiguration
kieBaseTestConfiguration) {
- double javaVersion =
Double.valueOf(System.getProperty("java.specification.version"));
- Assumptions.assumeTrue(javaVersion >= 1.7, "Test only makes sense on
Java 7+.");
- System.setProperty("drools.dialect.java.compiler.lnglevel", "1.7");
+ // Switch Over String is supported since Java 7. Set 17 here, because
17 is the minimum level supported in Drools 10
+ System.setProperty("drools.dialect.java.compiler.lnglevel", "17");
try {
KieBuilder kieBuilder =
KieUtil.getKieBuilderFromDrls(kieBaseTestConfiguration, false,
FUNCTION_WITH_SWITCH_OVER_STRING);
List<Message> errors =
kieBuilder.getResults().getMessages(Message.Level.ERROR);
@@ -70,18 +69,4 @@ public class SwitchOverStringTest {
System.clearProperty("drools.dialect.java.compiler.lnglevel");
}
}
-
- @ParameterizedTest(name = "KieBase type={0}")
- @MethodSource("parameters")
- public void
testShouldFailToCompileSwitchOverStringWithLngLevel16(KieBaseTestConfiguration
kieBaseTestConfiguration) {
- System.setProperty("drools.dialect.java.compiler.lnglevel", "1.6");
- try {
- KieBuilder kieBuilder =
KieUtil.getKieBuilderFromDrls(kieBaseTestConfiguration, false,
FUNCTION_WITH_SWITCH_OVER_STRING);
- List<Message> errors =
kieBuilder.getResults().getMessages(Message.Level.ERROR);
- assertThat(errors.isEmpty()).as("Should have an error").isFalse();
-
- } finally {
- System.clearProperty("drools.dialect.java.compiler.lnglevel");
- }
- }
}
diff --git
a/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/invoker.properties
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/invoker.properties
new file mode 100644
index 0000000000..32f00a5bc0
--- /dev/null
+++
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/invoker.properties
@@ -0,0 +1,29 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# A comma or space separated list of goals/phases to execute, may
+# specify an empty list to execute the default goal of the IT project.
+# Environment variables used by maven plugins can be added here
+invoker.goals = clean install
+
+# Require Java 21 for type switch syntax
+invoker.java.version = 21+
+
+# Uncomment the following to debug invoker. Do note that you have to connect
the remote debugger after "maven-invoker-plugin:3.2.0:run" has been print on
console
+#invoker.mavenOpts=-Xdebug -Xnoagent
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
diff --git
a/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/pom.xml
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/pom.xml
new file mode 100644
index 0000000000..2ccf87a143
--- /dev/null
+++ b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-maven-plugin-test-kjar-parent</artifactId>
+ <version>@org.kie.version@</version>
+
<relativePath>../kie-maven-plugin-test-kjar-setup/kie-maven-plugin-test-kjar-parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>kie-maven-plugin-test-kjar-16-java21</artifactId>
+
+ <packaging>kjar</packaging>
+
+ <properties>
+ <!-- Override parent's Java 11 to require Java 21 for type switch syntax
-->
+ <maven.compiler.release>21</maven.compiler.release>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-api</artifactId>
+ <version>${org.kie.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ <version>${org.kie.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ <version>${org.kie.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-mvel</artifactId>
+ <version>${org.kie.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-maven-plugin-test-kjar-common</artifactId>
+ <version>@org.kie.version@</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git
a/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/main/resources/META-INF/kmodule.xml
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/main/resources/META-INF/kmodule.xml
new file mode 100644
index 0000000000..c30e4f6d5a
--- /dev/null
+++
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/main/resources/META-INF/kmodule.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
+ <kbase name="Java21KBase" packages="org.java21test">
+ <ksession name="Java21KBase.session" type="stateful"/>
+ </kbase>
+</kmodule>
diff --git
a/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/main/resources/org/java21test/rules.drl
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/main/resources/org/java21test/rules.drl
new file mode 100644
index 0000000000..2e40b69baf
--- /dev/null
+++
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/main/resources/org/java21test/rules.drl
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.java21test
+
+global java.util.List results;
+
+rule "TypeSwitchRule"
+ when
+ $obj : Object()
+ then
+ String message = switch ($obj) {
+ case Integer i -> "int: " + i;
+ case String s -> "string: " + s;
+ default -> "other";
+ };
+ results.add(message);
+end
diff --git
a/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/test/java-filtered/org/kie/maven/plugin/ittests/Java21SyntaxTestIT.java
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/test/java-filtered/org/kie/maven/plugin/ittests/Java21SyntaxTestIT.java
new file mode 100644
index 0000000000..2aab43f332
--- /dev/null
+++
b/kie-maven-plugin/src/it/kie-maven-plugin-test-kjar-16-java21/src/test/java-filtered/org/kie/maven/plugin/ittests/Java21SyntaxTestIT.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.maven.plugin.ittests;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledForJreRange;
+import org.junit.jupiter.api.condition.JRE;
+import org.kie.api.runtime.KieSession;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test to verify Java 21 type switch syntax works in DRL rules
+ * when built with kie-maven-plugin.
+ */
+@EnabledForJreRange(min = JRE.JAVA_21)
+public class Java21SyntaxTestIT {
+
+ private static final String GAV_ARTIFACT_ID =
"kie-maven-plugin-test-kjar-16-java21";
+ private static final String GAV_VERSION = "${org.kie.version}";
+ private static final String KBASE_NAME = "Java21KBase";
+
+ @Test
+ public void testTypeSwitch() throws Exception {
+ final URL targetLocation =
Java21SyntaxTestIT.class.getProtectionDomain().getCodeSource().getLocation();
+ KieSession kSession = ITTestsUtils.getKieSession(targetLocation,
GAV_ARTIFACT_ID, GAV_VERSION, KBASE_NAME);
+
+ try {
+ List<String> results = new ArrayList<>();
+ kSession.setGlobal("results", results);
+
+ // Test with Integer - should match "case Integer i"
+ kSession.insert(51);
+ kSession.fireAllRules();
+ assertThat(results).containsExactly("int: 51");
+
+ // Test with String - should match "case String s"
+ results.clear();
+ kSession.insert("hello");
+ kSession.fireAllRules();
+ assertThat(results).contains("string: hello");
+
+ // Test with Double - should match "default"
+ results.clear();
+ kSession.insert(3.14);
+ kSession.fireAllRules();
+ assertThat(results).contains("other");
+
+ } finally {
+ kSession.dispose();
+ }
+ }
+}
diff --git
a/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaCompilerFactory.java
b/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaCompilerFactory.java
index 3c08626577..e653feef98 100644
---
a/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaCompilerFactory.java
+++
b/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaCompilerFactory.java
@@ -41,9 +41,10 @@ public class JavaCompilerFactory {
}
private static JavaCompilerSettings createSettings( JavaCompiler compiler,
String lngLevel ) {
+ String normalizedLevel = JavaConfiguration.findJavaVersion( lngLevel );
JavaCompilerSettings settings = compiler.createDefaultSettings();
- settings.setTargetVersion( lngLevel );
- settings.setSourceVersion( lngLevel );
+ settings.setTargetVersion( normalizedLevel );
+ settings.setSourceVersion( normalizedLevel );
return settings;
}
diff --git
a/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaCompilerSettings.java
b/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaCompilerSettings.java
index 2660aaa915..03dcf900e3 100644
---
a/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaCompilerSettings.java
+++
b/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaCompilerSettings.java
@@ -60,6 +60,9 @@ public class JavaCompilerSettings {
}
public void setTargetVersion( final String pTargetVersion ) {
+ if (!JavaConfiguration.isValidLanguageLevel(pTargetVersion)) {
+ throw new RuntimeException("value '" + pTargetVersion + "' is not
a valid language level");
+ }
targetVersion = pTargetVersion;
}
@@ -69,6 +72,9 @@ public class JavaCompilerSettings {
public void setSourceVersion( final String pSourceVersion ) {
+ if (!JavaConfiguration.isValidLanguageLevel(pSourceVersion)) {
+ throw new RuntimeException("value '" + pSourceVersion + "' is not
a valid language level");
+ }
sourceVersion = pSourceVersion;
}
diff --git
a/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaConfiguration.java
b/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaConfiguration.java
index d497e3eaeb..835bea0e4c 100644
---
a/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaConfiguration.java
+++
b/kie-memory-compiler/src/main/java/org/kie/memorycompiler/JavaConfiguration.java
@@ -31,16 +31,16 @@ import org.kie.memorycompiler.jdknative.NativeJavaCompiler;
* The valid values are "ECLIPSE" and "NATIVE" only.
*
* drools.dialect.java.compiler = <ECLIPSE|NATIVE>
- * drools.dialect.java.compiler.lnglevel = <1.5|1.6>
+ * drools.dialect.java.compiler.lnglevel = <1.5|...|21>
*
- * The default compiler is Eclipse and the default lngLevel is 1.5.
+ * The default compiler is Eclipse and the default lngLevel is 17.
* The lngLevel will attempt to autodiscover your system using the
* system property "java.version"
*/
public class JavaConfiguration {
// This should be in alphabetic order to search with BinarySearch
- protected static final String[] LANGUAGE_LEVELS = new String[]{"1.5",
"1.6", "1.7", "1.8", "10", "11", "12", "13", "14", "15", "16", "17", "18",
"19", "9"};
+ protected static final String[] LANGUAGE_LEVELS = new String[]{"1.5",
"1.6", "1.7", "1.8", "10", "11", "12", "13", "14", "15", "16", "17", "18",
"19", "20", "21", "9"};
public static final String JAVA_COMPILER_PROPERTY =
"drools.dialect.java.compiler";
public static final String JAVA_LANG_LEVEL_PROPERTY =
"drools.dialect.java.compiler.lnglevel";
@@ -85,32 +85,24 @@ public class JavaConfiguration {
return findJavaVersion( System.getProperty( JAVA_LANG_LEVEL_PROPERTY,
System.getProperty("java.version") ) );
}
+ public static boolean isValidLanguageLevel(String level) {
+ return Arrays.binarySearch(LANGUAGE_LEVELS, level) >= 0;
+ }
+
public static String findJavaVersion(String level) {
- if (level.startsWith("1.5")) {
- return "1.5";
- } else if (level.startsWith("1.6")) {
- return "1.6";
- } else if (level.startsWith("1.7")) {
- return "1.7";
- } else if (level.startsWith("1.8")) {
- return "1.8";
- } else if (level.startsWith("9")) {
- return "9";
- } else if (level.startsWith("10")) {
- return "10";
- } else if (level.startsWith("15")) {
- return "15";
- } else if (level.startsWith("16")) {
- return "16";
- } else if (level.startsWith("17")) {
- return "17";
- } else if (level.startsWith("18")) {
- return "18";
- } else if (level.startsWith("19")) {
- return "19";
+ String normalized = normalizeVersion(level);
+ if (isValidLanguageLevel(normalized)) {
+ return normalized;
}
+ return "17"; // default
+ }
- return "11";
+ private static String normalizeVersion(String version) {
+ String[] parts = version.split("\\.");
+ if ("1".equals(parts[0]) && parts.length > 1) {
+ return "1." + parts[1]; // Legacy format: 1.8.0_292 -> 1.8
+ }
+ return parts[0]; // Modern format: 21.0.2 -> 21
}
public String getJavaLanguageLevel() {
@@ -118,11 +110,11 @@ public class JavaConfiguration {
}
/**
- * You cannot set language level below 1.5, as we need static imports, 1.5
is now the default.
+ * You cannot set language level below 1.5, as we need static imports. 17
is now the default.
* @param languageLevel
*/
public void setJavaLanguageLevel(final String languageLevel) {
- if ( Arrays.binarySearch( LANGUAGE_LEVELS, languageLevel ) < 0 ) {
+ if (!isValidLanguageLevel(languageLevel)) {
throw new RuntimeException( "value '" + languageLevel + "' is not
a valid language level" );
}
this.languageLevel = languageLevel;
diff --git
a/kie-memory-compiler/src/test/java/org/kie/memorycompiler/KieMemoryCompilerTest.java
b/kie-memory-compiler/src/test/java/org/kie/memorycompiler/KieMemoryCompilerTest.java
index ec9dca17c3..017b5691f8 100644
---
a/kie-memory-compiler/src/test/java/org/kie/memorycompiler/KieMemoryCompilerTest.java
+++
b/kie-memory-compiler/src/test/java/org/kie/memorycompiler/KieMemoryCompilerTest.java
@@ -22,6 +22,8 @@ import java.lang.reflect.Method;
import java.util.Map;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledForJreRange;
+import org.junit.jupiter.api.condition.JRE;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
@@ -115,4 +117,34 @@ public class KieMemoryCompilerTest {
assertThat(compiled.get("org.kie.memorycompiler.ExampleClass")).isNotNull();
assertThat(compiled.get("org.kie.memorycompiler.ExampleClass$InnerClass")).isNotNull();
}
+
+ private static final String JDK21_TYPE_SWITCH_CLASS = """
+ package org.kie.memorycompiler;
+
+ public class ExampleClass {
+
+ public String typeSwitch(Object obj) {
+ return switch (obj) {
+ case Integer i -> "int: " + i;
+ case String s -> "string: " + s;
+ default -> "other";
+ };
+ }
+ }
+ """;
+
+ @EnabledForJreRange(min = JRE.JAVA_21)
+ @Test
+ void jdk21typeSwitch() throws Exception {
+ Map<String, String> source =
singletonMap("org.kie.memorycompiler.ExampleClass", JDK21_TYPE_SWITCH_CLASS);
+ Map<String, Class<?>> compiled = KieMemoryCompiler.compile(source,
this.getClass().getClassLoader());
+
+ Class<?> exampleClazz =
compiled.get("org.kie.memorycompiler.ExampleClass");
+ assertThat(exampleClazz).isNotNull();
+
+ Object instance =
exampleClazz.getDeclaredConstructors()[0].newInstance();
+ Method typeSwitchMethod = exampleClazz.getMethod("typeSwitch",
Object.class);
+ Object result = typeSwitchMethod.invoke(instance, 51);
+ assertThat(result).isEqualTo("int: 51");
+ }
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]