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 <a...@porcelli.me> 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: commits-unsubscr...@kie.apache.org For additional commands, e-mail: commits-h...@kie.apache.org