【问题标题】:Running Drools as a fat jar(Compile drools into jar)将 Drools 作为胖 jar 运行(将 drools 编译到 jar 中)
【发布时间】:2018-05-09 16:25:13
【问题描述】:

问题:

当我运行我的测试或从主方法运行我的应用程序时,drools 初始化正常并且一切正常。但是一旦我将我的应用程序编译成一个 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>

提前致谢。

【问题讨论】:

    标签: java drools rules


    【解决方案1】:

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

    Rob 为我指出了正确的解决方案。由于您的解决方法没有奏效,因此将其添加到 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>
    

    【讨论】:

    • package 对这项工作至关重要。感谢您的帮助
    【解决方案2】:

    对于基于 Gradle+Kotlin 的构建,

    named<ShadowJar>("shadowJar") {
        transform(AppendingTransformer::class.java) {
            resource = "META-INF/kie.conf"
        }
    }
    

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

    【讨论】:

      【解决方案3】:

      添加到 kaanchabhau 的答案中,如果这是 gradle,您将拥有:

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

      【讨论】:

        【解决方案4】:

        好的,这是一个丑陋的解决方法。问题是当你编译你的 jar 时,你会覆盖 META-INF/kie.conf 文件。所以我需要做的就是将所有的依赖ki​​e.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
        

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

        【讨论】:

        【解决方案5】:

        尝试了所有方法,唯一适合我的 maven 插件是 spring-boot-maven-plugin,即使您不使用 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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-13
          • 1970-01-01
          • 1970-01-01
          • 2014-04-04
          • 1970-01-01
          • 1970-01-01
          • 2015-08-03
          • 1970-01-01
          相关资源
          最近更新 更多