我目前有一些正在使用的excel决策表,这些表正通过以下库读取到骆驼路线中:
- Drools 5.6.0.最终
- 骆驼2.14.0
- 弹簧靴1.0.2
- JDK 7
我们正在将spring-boot升级到1.1.5,升级后,即使分配了2GB的permGen空间,drools决策表编译也开始崩溃。
新的春季启动版本似乎会导致某种类加载器循环,它会吃掉它能找到的所有PerGem。
若我们使用JDK8,问题"消失"了,但启动过程在编译流决策表时消耗了1.6GB的内存。
我尝试将drowls升级到6.1.0(KIE),但后来我无法再使用基于excel的决策表,因为似乎再也没有任何方法来配置Spring/Camel/drools bean了。或者至少http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html/ch.kie.spring.html#d0e12957没有提供任何关于如何实现这一目标的线索。
有人知道在JDK7下让drools 5.6.0更有效地工作的方法吗?或者如何在JDK8下使用drools/Kie 6+允许excel决策表?
JDK 7上的异常堆栈争用permGen错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'excelDTABLE_KBase': Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: PermGen space
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1554)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:687)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at my.domain.Application.main(Application.java:54)
Caused by: java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at org.drools.rule.JavaDialectRuntimeData$PackageClassLoader.fastFindClass(JavaDialectRuntimeData.java:624)
at org.drools.util.CompositeClassLoader$CachingLoader.load(CompositeClassLoader.java:254)
at org.drools.util.CompositeClassLoader$CachingLoader.load(CompositeClassLoader.java:237)
at org.drools.util.CompositeClassLoader.loadClass(CompositeClassLoader.java:88)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at org.drools.rule.JavaDialectRuntimeData.wire(JavaDialectRuntimeData.java:434)
at org.drools.rule.JavaDialectRuntimeData.wire(JavaDialectRuntimeData.java:429)
at org.drools.rule.JavaDialectRuntimeData.onBeforeExecute(JavaDialectRuntimeData.java:257)
at org.drools.rule.DialectRuntimeRegistry.onBeforeExecute(DialectRuntimeRegistry.java:139)
at org.drools.compiler.PackageBuilder.reloadAll(PackageBuilder.java:1202)
at org.drools.compiler.PackageBuilder.compileAllRules(PackageBuilder.java:951)
at org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:938)
at org.drools.compiler.PackageBuilder.addPackageFromDecisionTable(PackageBuilder.java:451)
at org.drools.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.java:715)
at org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:51)
at org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:40)
at org.drools.container.spring.beans.KnowledgeBaseBeanFactory.afterPropertiesSet(KnowledgeBaseBeanFactory.java:110)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:687)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
提供的解决方案是使用弹簧引导使用kie的drool决策表
参考流表仅供参考,注意在条件之间共享的对象必须已经合并了在这些条件下的单元格
@Configuration
public class DroolConfig {
private KieServices kieServices = KieServices.Factory.get();
private KieFileSystem getKieFileSystem() throws IOException {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
String xls[] = new String[] {"wallet.xls","offer.xls"}; // path to file
for(int i=0 ; i< xls.length; i++) {
kieFileSystem.write(ResourceFactory.newClassPathResource(xls[i]));
}
return kieFileSystem;
}
@Bean
public KieContainer getKieContainer() throws IOException {
System.out.println("Container created...");
getKieRepository();
KieBuilder kb = kieServices.newKieBuilder(getKieFileSystem());
kb.buildAll();
KieModule kieModule = kb.getKieModule();
KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId());
return kContainer;
}
private void getKieRepository() {
final KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(new KieModule() {
public ReleaseId getReleaseId() {
return kieRepository.getDefaultReleaseId();
}
});
}
@Bean
public KieSession getKieSession() throws IOException {
System.out.println("session created...");
return getKieContainer().newKieSession();
}
}
@RestController
public class MegaOfferController {
@Autowired
private KieSession session;
@PostMapping("/order")
public Order orderNow(@RequestBody Order order) {
session.insert(order);
session.fireAllRules();
return order;
}
<properties>
<drools.version>6.4.0.Final</drools.version>
</properties>
<dependencies>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-ci</artifactId>
<version>${drools.version}</version>
</dependency>
</dependencies>