Details
-
Bug
-
Resolution: Done
-
Major
-
None
-
8.29.0.Final
-
None
-
2022 Week 44-46 (from Oct 31)
-
NEW
-
NEW
-
---
-
---
Description
we are currently deploying drools (drools-engine-classic) together with our web application (spring-boot based) on a tomcat 9.0. when starting the application we are getting with version 8.29.0 the following stack trace printed out.
Caused by: java.lang.ExceptionInInitializerError at org.drools.core.base.FieldAccessorFactory.get(FieldAccessorFactory.java:34) at org.drools.core.base.ClassFieldAccessorCache$CacheEntry.getReadAccessor(ClassFieldAccessorCache.java:175) at org.drools.core.base.ClassFieldAccessorCache.getReadAccessor(ClassFieldAccessorCache.java:97) at org.drools.mvel.accessors.ClassFieldAccessorStore.wire(ClassFieldAccessorStore.java:279) at org.drools.mvel.accessors.ClassFieldAccessorStore.getReader(ClassFieldAccessorStore.java:112) at org.drools.mvel.accessors.ClassFieldAccessorStore.getReader(ClassFieldAccessorStore.java:90) at org.drools.mvel.MVELKnowledgePackageImpl.getReader(MVELKnowledgePackageImpl.java:113) at org.drools.compiler.rule.builder.PatternBuilder.getFieldReadAccessor(PatternBuilder.java:1784) at org.drools.compiler.rule.builder.PatternBuilder.getFieldReadAccessor(PatternBuilder.java:1748) at org.drools.compiler.rule.builder.PatternBuilder.buildConstraintForPattern(PatternBuilder.java:1164) at org.drools.compiler.rule.builder.PatternBuilder.buildRelationalExpression(PatternBuilder.java:1111) at org.drools.compiler.rule.builder.PatternBuilder.buildExpression(PatternBuilder.java:980) at org.drools.compiler.rule.builder.PatternBuilder.buildCcdDescr(PatternBuilder.java:952) at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:762) at org.drools.compiler.rule.builder.PatternBuilder.processConstraintsAndBinds(PatternBuilder.java:606) at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:174) at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:140) at org.drools.compiler.rule.builder.PatternBuilder.build(PatternBuilder.java:122) at org.drools.compiler.rule.builder.GroupElementBuilder.build(GroupElementBuilder.java:66) at org.drools.compiler.rule.builder.RuleBuilder.build(RuleBuilder.java:98) at org.drools.compiler.builder.impl.processors.ImmutableRuleCompilationPhase.internalAddRule(ImmutableRuleCompilationPhase.java:343) at org.drools.compiler.builder.impl.processors.ImmutableRuleCompilationPhase.addRule(ImmutableRuleCompilationPhase.java:337) at org.drools.compiler.builder.impl.processors.ImmutableRuleCompilationPhase.lambda$compileRulesLevel$3(ImmutableRuleCompilationPhase.java:278) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290) at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:754) ... 5 more Caused by: org.drools.core.common.MissingDependencyException: You're trying to compile a Drools asset without mvel. Please add the module org.drools:drools-mvel to your classpath. at org.drools.core.base.CoreComponentsBuilder.throwExceptionForMissingMvel(CoreComponentsBuilder.java:34) at org.drools.core.base.FieldAccessorFactory$Holder.getFactory(FieldAccessorFactory.java:29) at org.drools.core.base.FieldAccessorFactory$Holder.<clinit>(FieldAccessorFactory.java:25) ... 34 more
while running it directly as a spring boot application without deploying to a tomcat everything works fine.
taking a deeper look brought up an issue in here
private static FieldAccessorFactory getFactory() { FieldAccessorFactory instance = KieService.load( FieldAccessorFactory.class ); return instance != null ? instance : throwExceptionForMissingMvel(); }
when running inside the tomcat the ServiceLoader.load() used in KieService.load does not see the implementations. when running a on-the-fly debugging on the line calling the ServiceLoader.load method show this behaviour
ServiceLoader.load(FieldAccessorFactory.class).stream().count() => 0
ServiceLoader.load(FieldAccessorFactory.class, FieldAccessorFactory.class.getClassloader()).stream().count() => 1
so digging a little bit deeper shows that when it returns 0 the fork-join-thread with a different classloader is used not containing any jar files on the classpath
i was able to workaround by adding this line in the application startup part before drools is used at all
System.setProperty(ParallelRulesBuildThresholdOption.PROPERTY_NAME, "-1");