Java 将Drools作为胖jar运行(将Drools编译到jar中)

Java 将Drools作为胖jar运行(将Drools编译到jar中),java,drools,rules,Java,Drools,Rules,问题: 当我运行我的测试或从主方法运行我的应用程序时,会很好地初始化,并且一切正常。但一旦我将应用程序编译成jar文件(作为胖jar),这段代码就会抛出一个NullPointerException KieServices ks = KieServices.Factory.get(); kieContainer = ks.getKieClasspathContainer(); // ks is null 我还注意到,当从ide运行它时,ServiceDiscovery会发现更多的kie.conf

问题:

当我运行我的测试或从主方法运行我的应用程序时,会很好地初始化,并且一切正常。但一旦我将应用程序编译成jar文件(作为胖jar),这段代码就会抛出一个
NullPointerException

KieServices ks = KieServices.Factory.get();
kieContainer = ks.getKieClasspathContainer(); // ks is null
我还注意到,当从ide运行它时,ServiceDiscovery会发现更多的kie.conf文件

从IDE运行它

2018-05-09 18:18:12,219 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Loading kie.conf from  
2018-05-09 18:18:12,221 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Discovered kie.conf url=jar:file:/C:/Users/alece/.m2/repository/org/drools/drools-decisiontables/7.6.0.Final/drools-decisiontables-7.6.0.Final.jar!/META-INF/kie.conf 
2018-05-09 18:18:12,307 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.drools.decisiontable.DecisionTableProviderImpl

2018-05-09 18:18:12,307 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Loading kie.conf from  
2018-05-09 18:18:12,308 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Discovered kie.conf url=jar:file:/C:/Users/alece/.m2/repository/org/kie/kie-internal/7.6.0.Final/kie-internal-7.6.0.Final.jar!/META-INF/kie.conf 
2018-05-09 18:18:12,311 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.kie.internal.services.KieWeaversImpl

2018-05-09 18:18:12,313 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.kie.internal.services.KieBeliefsImpl

2018-05-09 18:18:12,314 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.kie.internal.services.KieAssemblersImpl

2018-05-09 18:18:12,315 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.kie.internal.services.KieRuntimesImpl

2018-05-09 18:18:12,316 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Loading kie.conf from  
2018-05-09 18:18:12,316 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Discovered kie.conf url=jar:file:/C:/Users/alece/.m2/repository/org/drools/drools-core/7.6.0.Final/drools-core-7.6.0.Final.jar!/META-INF/kie.conf 
2018-05-09 18:18:12,319 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.drools.core.io.impl.ResourceFactoryServiceImpl

2018-05-09 18:18:12,323 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.drools.core.marshalling.impl.MarshallerProviderImpl

2018-05-09 18:18:12,335 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.drools.core.concurrent.ExecutorProviderImpl

2018-05-09 18:18:12,335 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Loading kie.conf from  
2018-05-09 18:18:12,336 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Discovered kie.conf url=jar:file:/C:/Users/alece/.m2/repository/org/drools/drools-compiler/7.6.0.Final/drools-compiler-7.6.0.Final.jar!/META-INF/kie.conf 
2018-05-09 18:18:12,348 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.drools.compiler.kie.builder.impl.KieServicesImpl

2018-05-09 18:18:12,357 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.drools.compiler.builder.impl.KnowledgeBuilderFactoryServiceImpl
运行编译的jar

2018-05-09 18:14:02,771 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Loading kie.conf from
2018-05-09 18:14:02,772 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Discovered kie.conf url=jar:file:/C:/Users/alece/git-idea/directpay-monthend/target/monthend-1.0.0.jar!/META-INF/kie.conf
2018-05-09 18:14:02,773 [monthEnd] INFO  org.kie.api.internal.utils.ServiceDiscoveryImpl - Adding Service org.drools.decisiontable.DecisionTableProviderImpl
我的pom文件

<properties>
      <drools.version>7.6.0.Final</drools.version>
</properties>
        <!-- Drools -->
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-api</artifactId>
            <version>${drools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-decisiontables</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>

7.6.0.1最终版本
org.kie
基亚皮
${drools.version}
org.drools
drools决策表
${drools.version}
org.drools
流涎核
${drools.version}
org.drools
drools编译器
${drools.version}

提前谢谢。

好的,这是一个难看的工作。问题是,当您编译jar时,您正在覆盖META-INF/kie.conf文件。所以我需要做的是将所有依赖项kie.conf文件合并到一个conf中

这就是最终的结果

org.drools.compiler.compiler.DecisionTableProvider = org.drools.decisiontable.DecisionTableProviderImpl
org.kie.api.KieServices = org.drools.compiler.kie.builder.impl.KieServicesImpl
org.kie.internal.builder.KnowledgeBuilderFactoryService = org.drools.compiler.builder.impl.KnowledgeBuilderFactoryServiceImpl
org.kie.api.internal.assembler.KieAssemblers = org.kie.internal.services.KieAssemblersImpl
org.kie.api.internal.runtime.KieRuntimes = org.kie.internal.services.KieRuntimesImpl
org.kie.api.internal.weaver.KieWeavers = org.kie.internal.services.KieWeaversImpl
org.kie.api.internal.runtime.beliefs.KieBeliefs = org.kie.internal.services.KieBeliefsImpl
org.kie.api.io.KieResources = org.drools.core.io.impl.ResourceFactoryServiceImpl
org.kie.api.marshalling.KieMarshallers = org.drools.core.marshalling.impl.MarshallerProviderImpl
org.kie.api.concurrent.KieExecutors = org.drools.core.concurrent.ExecutorProviderImpl

如果有人知道更好的方法,请在这里发布。

问题是,当您编译jar时,您正在覆盖
META-INF/kie.conf
文件

罗布给我指出了正确的解决办法。由于您的解决方案不起作用,将此添加到
pom.xml
解决了我的问题:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.0</version>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/kie.conf</resource>
            </transformer>
          </transformers>
        </configuration>
      </execution>
    </executions>
  </plugin>

org.apache.maven.plugins
maven阴影插件
3.2.0
包裹
阴凉处
META-INF/kie.conf

对于基于Gradle+Kotlin的构建

named<ShadowJar>("shadowJar") {
    transform(AppendingTransformer::class.java) {
        resource = "META-INF/kie.conf"
    }
}
命名(“shadowJar”){
转换(附加Transformer::class.java){
resource=“META-INF/kie.conf”
}
}

上面的代码应该可以工作。

加上kaanchabhau的答案,如果这是gradle,您将有:

shadowJar {
    append 'META-INF/kie.conf'
    manifest {
        attributes 'Main-Class': mainClassName
    }
}

尝试了所有方法,唯一对我有效的maven插件是spring boot maven插件,即使您不使用spring boot:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.3.3.RELEASE</version>
    <configuration>
        <mainClass>${main.class}</mainClass>
        <layout>ZIP</layout>
    </configuration>
</plugin>

org.springframework.boot
springbootmaven插件
2.3.3.2发布
${main.class}
拉链

我使用maven shade插件在制作胖jar的同时将资源文件合并到jar中。有关更多详细信息,请参阅。软件包对此工作至关重要。谢谢你的帮助