[jboss-jira] [JBoss JIRA] (DROOLS-1359) Race condition in MVELDialectRuntimeData.getParserConfiguration
Matteo Mortari (JIRA)
issues at jboss.org
Wed Nov 16 05:08:00 EST 2016
[ https://issues.jboss.org/browse/DROOLS-1359?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13323492#comment-13323492 ]
Matteo Mortari commented on DROOLS-1359:
----------------------------------------
Hi [~chp-anujs], thank you for this; I've checked your reproducer but rewriting it using the public Kie API, and simulating the race condition inside {{MVELDialectRuntimeData}}, does not exhibit the problem, because at build time and during initialization of a new KieSession (either from KieContainer or KieBase) +the public Kie API+ guarantees the thread safety.
Below your test case modified to use the public Kie API (is just one possible example to use the public Kie API)
{code:java}
@Test
public void testRaceCondition() {
List<String> lines = new ArrayList<>();
lines.add("package testrules");
lines.add("import static " + Helper.class.getCanonicalName() + ".* ");
lines.add("import " + Fact.class.getCanonicalName());
lines.add("rule \"test-rule\" ");
lines.add(" when ");
lines.add(" fact : Fact( staticMethod(arg) )");
lines.add(" then ");
lines.add(" fact.setActivated(); ");
lines.add("end");
String drl = lines.stream().collect(Collectors.joining("\n"));
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();
KieFileSystem kfs = ks.newKieFileSystem();
kfs.write("src/main/resources/DROOLS-1359.drl", drl);
KieBuilder kb = ks.newKieBuilder(kfs);
System.out.println("building...");
kb.buildAll();
if (kb.getResults().hasMessages(Level.ERROR)) {
throw new RuntimeException("Build Errors:\n" + kb.getResults().toString());
}
System.out.println("building finished.");
KieContainer kContainer = ks.newKieContainer(kr.getDefaultReleaseId());
KieBase knowledgeBase = kContainer.getKieBase();
int numberOfThreads = 2;
System.out.println("Starting threads...");
ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);
Callable<Boolean> executeRulesTask = new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
// Create a knowledge session
KieSession session = knowledgeBase.newKieSession();
try {
// Insert the fact objects
session.insert(new Fact());
// Run the session
session.fireAllRules();
return true;
} catch (RuntimeException e) {
e.printStackTrace();
return false;
} finally {
session.dispose();
}
}
};
List<Future<Boolean>> executionResults = new ArrayList<>();
for (int i = 0; i < numberOfThreads; i++)
executionResults.add(executor.submit(executeRulesTask));
executor.shutdown();
boolean finalResult = true;
for (int i = 0; i < numberOfThreads; i++) {
try {
finalResult &= executionResults.get(i).get();
} catch (InterruptedException | ExecutionException e) {
finalResult = false;
}
}
assertTrue(finalResult);
}
...
public class Helper {
public static boolean staticMethod(String arg) {
return true;
}
}
...
public class Fact {
public String getArg() {
return null;
}
public void setActivated() {
}
}
{code}
and the {{MVELDialectRuntimeData}} quick modification to attempt the raise of the race-condition (Line 318):
{code:java}
this.parserConfiguration = new ParserConfiguration();
try {
System.out.println("X");
Thread.sleep(2_000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.parserConfiguration.setImports( this.imports );
this.parserConfiguration.setPackageImports( this.packageImports );
this.parserConfiguration.setClassLoader( packageClassLoader );
{code}
In conclusion: not a bug, using the public Kie API does not exhibit racing-condition issues. If you still think there are some issues with the public Kie API, kindly let us know, and thank you anyway for your report so far!
> Race condition in MVELDialectRuntimeData.getParserConfiguration
> ---------------------------------------------------------------
>
> Key: DROOLS-1359
> URL: https://issues.jboss.org/browse/DROOLS-1359
> Project: Drools
> Issue Type: Bug
> Components: core engine
> Affects Versions: 5.5.0.Final, 6.5.0.Final
> Reporter: Anuj Shah
> Assignee: Mario Fusco
>
> MVELDialectRuntimeData attempts to hold a lazy loaded ParserConfiguration. The getParserConfiguration method sets this to a new configuration object and then sets the imports on the configuration. Between these two steps another thread could retrieve the stale configuration and use it. This could result in a number of exceptions in compilation.
> A simple fix is to delay assignment of new ParserConfiguration until after the imports are set.
--
This message was sent by Atlassian JIRA
(v7.2.3#72005)
More information about the jboss-jira
mailing list