This is an automated email from the ASF dual-hosted git repository.
mariofusco 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 84eb420b30 kie-issue#1738: customize ForkJoinPool to explicitly
inherit the context ClassLoader from the parent thread (#6211)
84eb420b30 is described below
commit 84eb420b3026935c56f4c41e3d8fa9aeb41ae0cb
Author: Alex Porcelli <[email protected]>
AuthorDate: Tue Jan 7 03:12:29 2025 -0500
kie-issue#1738: customize ForkJoinPool to explicitly inherit the context
ClassLoader from the parent thread (#6211)
* kie-issue#1738: customize ForkJoinPool to explicitly inherit the context
ClassLoader from the parent thread
* kie-issue#1738: ops, forgot the header :)
---
.../builder/impl/KnowledgeBuilderImpl.java | 6 +-
.../KnowledgeBuilderImplCompilerFJPoolTest.java | 93 ++++++++++++++++++++++
2 files changed, 97 insertions(+), 2 deletions(-)
diff --git
a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java
b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java
index 8b332a20d7..7a3367ef0b 100644
---
a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java
+++
b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java
@@ -32,6 +32,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinWorkerThread;
import java.util.function.Supplier;
import org.drools.base.RuleBase;
@@ -500,10 +501,11 @@ public class KnowledgeBuilderImpl implements
InternalKnowledgeBuilder, TypeDecla
}
public static class ForkJoinPoolHolder {
- public static final ForkJoinPool COMPILER_POOL = new ForkJoinPool();
// avoid common pool
+ public static final ForkJoinPool COMPILER_POOL = new
ForkJoinPool(Math.min(32767, Runtime.getRuntime().availableProcessors()), pool
-> new ForkJoinWorkerThread(pool) {{
+
setContextClassLoader(Thread.currentThread().getContextClassLoader());
+ }}, null, false); // avoid common pool
}
-
public boolean filterAccepts(ResourceChange.Type type, String namespace,
String name) {
return assetFilter == null ||
!AssetFilter.Action.DO_NOTHING.equals(assetFilter.accept(type, namespace,
name));
}
diff --git
a/drools-compiler/src/test/java/org/drools/compiler/builder/impl/KnowledgeBuilderImplCompilerFJPoolTest.java
b/drools-compiler/src/test/java/org/drools/compiler/builder/impl/KnowledgeBuilderImplCompilerFJPoolTest.java
new file mode 100644
index 0000000000..bb00c8bc14
--- /dev/null
+++
b/drools-compiler/src/test/java/org/drools/compiler/builder/impl/KnowledgeBuilderImplCompilerFJPoolTest.java
@@ -0,0 +1,93 @@
+/**
+ * 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.compiler.builder.impl;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+public class KnowledgeBuilderImplCompilerFJPoolTest {
+
+ private ClassLoader originalClassLoader;
+ private ClassLoader customClassLoader;
+
+ @BeforeEach
+ void setUp() {
+ // Save the original classloader
+ originalClassLoader = Thread.currentThread().getContextClassLoader();
+
+ // Create a custom classloader for testing
+ customClassLoader = new
ClassLoader(ClassLoader.getSystemClassLoader()) {};
+ Thread.currentThread().setContextClassLoader(customClassLoader);
+ }
+
+ @AfterEach
+ void tearDown() {
+ // Restore original classloader
+ Thread.currentThread().setContextClassLoader(originalClassLoader);
+ }
+
+ private static class ClassLoaderCheckTask extends RecursiveAction {
+ private final List<ClassLoader> results;
+ private final int index;
+
+ public ClassLoaderCheckTask(List<ClassLoader> results, int index) {
+ this.results = results;
+ this.index = index;
+ }
+
+ @Override
+ protected void compute() {
+ results.set(index, Thread.currentThread().getContextClassLoader());
+ }
+ }
+
+ @Test
+ void testCompilerPoolClassLoader() throws Exception {
+ int numTasks = 5;
+ List<ClassLoader> results = new ArrayList<>(numTasks);
+ for (int i = 0; i < numTasks; i++) {
+ results.add(null);
+ }
+
+ // Submit tasks to the COMPILER_POOL
+ for (int i = 0; i < numTasks; i++) {
+ KnowledgeBuilderImpl.ForkJoinPoolHolder.COMPILER_POOL.submit(new
ClassLoaderCheckTask(results, i));
+ }
+
+ // Wait for completion
+
KnowledgeBuilderImpl.ForkJoinPoolHolder.COMPILER_POOL.awaitQuiescence(1,
TimeUnit.SECONDS);
+
+ // Verify all worker threads have the expected classloader
+ for (ClassLoader workerClassLoader : results) {
+ assertSame(
+ customClassLoader,
+ workerClassLoader,
+ "Worker thread should have inherited the custom
classloader"
+ );
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]