This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch camel-jdk17-support in repository https://gitbox.apache.org/repos/asf/camel.git
commit 834705b03dcfa366c263e07c59f334ad4f6e81cc Author: Guillaume Nodet <[email protected]> AuthorDate: Fri Mar 13 15:00:00 2026 +0100 Lower minimum JDK requirement from 21 to 17 - Change jdk.version from 21 to 17 in root pom.xml - Create JDK 17 fallback for CamelThreadFactory using new Thread() - Move JDK 21 CamelThreadFactory (virtual threads) to MRJAR java21/ directory - Replace List.getLast() (JDK 21) with index-based access in JsonObject - Replace String.splitWithDelimiters() (JDK 21) with Pattern/Matcher in JsonObject - Add @EnabledForJreRange(min=JAVA_21) to ManagedVirtualThreadExecutorTest Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../ManagedVirtualThreadExecutorTest.java | 3 ++ .../camel/util/concurrent/CamelThreadFactory.java | 35 ++++------------------ .../camel/util/concurrent/CamelThreadFactory.java | 0 pom.xml | 2 +- .../org/apache/camel/util/json/JsonObject.java | 22 ++++++++++++-- 5 files changed, 29 insertions(+), 33 deletions(-) diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedVirtualThreadExecutorTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedVirtualThreadExecutorTest.java index e6e4d500689d..bc823a9f2adb 100644 --- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedVirtualThreadExecutorTest.java +++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedVirtualThreadExecutorTest.java @@ -26,12 +26,15 @@ import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.spi.LifecycleStrategy; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.JRE; import static org.apache.camel.management.DefaultManagementObjectNameStrategy.TYPE_THREAD_POOL; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +@EnabledForJreRange(min = JRE.JAVA_21) public class ManagedVirtualThreadExecutorTest extends ManagementTestSupport { private ExecutorService vte; diff --git a/core/camel-util/src/main/java/org/apache/camel/util/concurrent/CamelThreadFactory.java b/core/camel-util/src/main/java/org/apache/camel/util/concurrent/CamelThreadFactory.java index 4bb630479974..638fcf1b399d 100644 --- a/core/camel-util/src/main/java/org/apache/camel/util/concurrent/CamelThreadFactory.java +++ b/core/camel-util/src/main/java/org/apache/camel/util/concurrent/CamelThreadFactory.java @@ -20,8 +20,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Thread factory which creates threads supporting a naming pattern. The factory creates virtual threads in case the - * System property {@code camel.threads.virtual.enabled} set to {@code true}. + * Thread factory which creates threads supporting a naming pattern. On JDK 21+, this factory creates virtual threads + * when the System property {@code camel.threads.virtual.enabled} is set to {@code true}. On JDK 17, only platform + * threads are available. */ public final class CamelThreadFactory implements ThreadFactoryTypeAware { private static final Logger LOG = LoggerFactory.getLogger(CamelThreadFactory.class); @@ -29,25 +30,24 @@ public final class CamelThreadFactory implements ThreadFactoryTypeAware { private final String pattern; private final String name; private final boolean daemon; - private final ThreadFactoryType threadType; public CamelThreadFactory(String pattern, String name, boolean daemon) { this.pattern = pattern; this.name = name; this.daemon = daemon; - this.threadType = daemon ? ThreadFactoryType.current() : ThreadFactoryType.PLATFORM; } @Override public boolean isVirtual() { - return threadType == ThreadFactoryType.VIRTUAL; + return false; } @Override public Thread newThread(Runnable runnable) { String threadName = ThreadHelper.resolveThreadName(pattern, name); - Thread answer = threadType.newThread(threadName, daemon, runnable); + Thread answer = new Thread(runnable, threadName); + answer.setDaemon(daemon); LOG.trace("Created thread[{}] -> {}", threadName, answer); return answer; @@ -61,27 +61,4 @@ public final class CamelThreadFactory implements ThreadFactoryTypeAware { public String toString() { return "CamelThreadFactory[" + name + "]"; } - - private enum ThreadFactoryType { - PLATFORM { - Thread.Builder newThreadBuilder(String threadName, boolean daemon) { - return Thread.ofPlatform().name(threadName).daemon(daemon); - } - }, - VIRTUAL { - Thread.Builder newThreadBuilder(String threadName, boolean daemon) { - return Thread.ofVirtual().name(threadName); - } - }; - - Thread newThread(String threadName, boolean daemon, Runnable runnable) { - return newThreadBuilder(threadName, daemon).unstarted(runnable); - } - - abstract Thread.Builder newThreadBuilder(String threadName, boolean daemon); - - static ThreadFactoryType current() { - return ThreadType.current() == ThreadType.VIRTUAL ? VIRTUAL : PLATFORM; - } - } } diff --git a/core/camel-util/src/main/java/org/apache/camel/util/concurrent/CamelThreadFactory.java b/core/camel-util/src/main/java21/org/apache/camel/util/concurrent/CamelThreadFactory.java similarity index 100% copy from core/camel-util/src/main/java/org/apache/camel/util/concurrent/CamelThreadFactory.java copy to core/camel-util/src/main/java21/org/apache/camel/util/concurrent/CamelThreadFactory.java diff --git a/pom.xml b/pom.xml index 6690a991d31b..acf6827876ca 100644 --- a/pom.xml +++ b/pom.xml @@ -110,7 +110,7 @@ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <site-repo-url>scpexe://people.apache.org/www/camel.apache.org/maven/</site-repo-url> - <jdk.version>21</jdk.version> + <jdk.version>17</jdk.version> <!-- These two are here only to prevent the versions for the Apache parent pom from leaking--> <maven.compiler.source>${jdk.version}</maven.compiler.source> <maven.compiler.target>${jdk.version}</maven.compiler.target> diff --git a/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java b/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java index d361e0b05179..a6be47747d96 100644 --- a/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java +++ b/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java @@ -20,12 +20,15 @@ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * JsonObject is a common non-thread safe data format for string to data mappings. The contents of a JsonObject are only @@ -194,7 +197,7 @@ public class JsonObject extends LinkedHashMap<String, Object> implements Jsonabl if (pos != -1 && answer instanceof List<?> arr) { jo = null; if (pos == Integer.MAX_VALUE) { - answer = arr.getLast(); + answer = arr.get(arr.size() - 1); } else if (pos < arr.size()) { answer = arr.get(pos); } else { @@ -230,10 +233,23 @@ public class JsonObject extends LinkedHashMap<String, Object> implements Jsonabl return JsonObject.class.cast(o); } + private static String[] splitWithDelimiters(String input, String regex) { + List<String> parts = new ArrayList<>(); + Matcher m = Pattern.compile(regex).matcher(input); + int lastEnd = 0; + while (m.find()) { + parts.add(input.substring(lastEnd, m.start())); + parts.add(m.group()); + lastEnd = m.end(); + } + parts.add(input.substring(lastEnd)); + return parts.toArray(new String[0]); + } + private Optional<Object> doPath(final String path) { Object answer = null; - String[] split = path.splitWithDelimiters("(\\?\\.|\\.)", 0); + String[] split = splitWithDelimiters(path, "(\\?\\.|\\.)"); for (int i = 0; i < split.length; i = i + 2) { String part = split[i]; String dot = i > 0 ? split[i - 1] : null; @@ -262,7 +278,7 @@ public class JsonObject extends LinkedHashMap<String, Object> implements Jsonabl } if (pos != -1 && answer instanceof List<?> arr) { if (pos == Integer.MAX_VALUE) { - answer = arr.getLast(); + answer = arr.get(arr.size() - 1); } else if (pos < arr.size()) { answer = arr.get(pos); } else {
