Kie 使用 substring 来提取其模块名称。但是叫错了吗?

Kie uses substring to extract its module name. But calls it wrongly?

所以我正在做一个项目,涉及 Java 实施 Drools 客户端 运行 与 Drools-WorkBench.

的 KIE 服务

我已经开始构建最终项目,尽管我 运行 遇到了一些麻烦,因为 KIE jar 路径的 URL 似乎有一些问题。

因此,在 ServiceDiscoveryImpl 的核心部分,应用程序会尝试获取其模块名称。 它使用以下命令执行此操作:

    private static String getModuleName(URL url) {
        String s = url.toString();
        int moduleStart = s.indexOf("META-INF/kie") + "META-INF/kie".length() + 1;
        return s.substring(moduleStart, s.length() - ("kie.conf".length() + 1));
    }

现在在我的例子中 s 的值是 jar:file:/C:/SLP/Drools/target/war.jar!/META-INF/kie.conf。 导致 moduleStart 的值为 53

因此我们使用值 (53, 48) 调用 String.substring。引发异常 java.lang.StringIndexOutOfBoundsException: begin 53, end 48, length 57

堆栈跟踪:

java.lang.StringIndexOutOfBoundsException: begin 53, end 48, length 57
    java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
    java.base/java.lang.String.substring(String.java:1874)
    org.kie.api.internal.utils.ServiceDiscoveryImpl.getModuleName(ServiceDiscoveryImpl.java:346)
    java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:195)
    java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
    java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
    java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
    org.kie.api.internal.utils.ServiceDiscoveryImpl.findKieConfUrls(ServiceDiscoveryImpl.java:290)
    org.kie.api.internal.utils.ServiceDiscoveryImpl.loadKieConfs(ServiceDiscoveryImpl.java:212)
    java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:195)
    java.base/java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
    java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
    java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
    java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
    java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
    java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543)
    org.kie.api.internal.utils.ServiceDiscoveryImpl.getKieConfs(ServiceDiscoveryImpl.java:204)
    org.kie.api.internal.utils.ServiceDiscoveryImpl.getServices(ServiceDiscoveryImpl.java:103)
    org.kie.api.internal.utils.ServiceRegistry$Impl.<init>(ServiceRegistry.java:62)
    org.drools.dynamic.DynamicServiceRegistrySupplier$LazyHolder.<clinit>(DynamicServiceRegistrySupplier.java:27)
    org.drools.dynamic.DynamicServiceRegistrySupplier.get(DynamicServiceRegistrySupplier.java:32)
    org.drools.dynamic.DynamicServiceRegistrySupplier.get(DynamicServiceRegistrySupplier.java:23)
    org.kie.api.internal.utils.ServiceRegistry$Impl.getServiceRegistry(ServiceRegistry.java:90)
    org.kie.api.internal.utils.ServiceRegistry$ServiceRegistryHolder.<clinit>(ServiceRegistry.java:49)
    org.kie.api.internal.utils.ServiceRegistry.getInstance(ServiceRegistry.java:41)
    org.kie.api.internal.utils.ServiceRegistry.getService(ServiceRegistry.java:37)
    org.kie.api.KieServices$Factory$LazyHolder.<clinit>(KieServices.java:358)
    org.kie.api.KieServices$Factory.get(KieServices.java:365)
    utils.KieServerAccessor.validate(KieServerAccessor.java:73) // I call it here
    module.RabbitMQConsumer.handleDrools(RabbitMQConsumer.java:112)
    module.RabbitMQConsumer.access[=11=]0(RabbitMQConsumer.java:18)
    module.RabbitMQConsumer.lambda$handleDelivery[=11=](RabbitMQConsumer.java:79)
    java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
    java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
    java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    java.base/java.lang.Thread.run(Thread.java:829)
    

这似乎是 KIE 团队的疏忽,如果不是因为此异常仅在 运行 构建后的 .jar 文件时发生,我会将其作为问题提交。

我不知道 ide 关于 IDEA 如何编译/运行 java 应用程序,但每当我使用该功能时,都不会发生此异常。所以我有点困惑这到底是 KIE java 客户端中的错误,还是只是我对我的建筑做错了什么。

我希望你们中的一些人能够帮助解释为什么 KIE 会做他们所做的事情,以及我如何错误地构建 jar 导致了异常。

我的 pom.xml 文件很糟糕,但在这里;

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>dk.slp</groupId>
  <artifactId>DroolsWrapper</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Drools :: Wrapper</name>
  <description>
    The Wrapper Program which handel validations on received objects from RabbitMQ, and send the result to the output queue.
  </description>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>5.8.2</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <properties>
    <runtime.version>7.59.0.Final</runtime.version>
    <java.version>8</java.version>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>

  </properties>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.2</version>
        <configuration>
          <skipTests>true</skipTests>
        </configuration>
      </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-assembly-plugin</artifactId>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
          <configuration>
            <finalName>war</finalName>
            <archive>
              <manifest>
                <mainClass>
                  SLPDrools
                </mainClass>
              </manifest>
            </archive>
            <descriptorRefs>
              <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <appendAssemblyId>false</appendAssemblyId>
          </configuration>
        </execution>
      </executions>
    </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>jboss-public-repository-group</id>
      <name>JBoss Public Repository Group</name>
      <url>http://repository.jboss.org/nexus/content/groups/public/</url>
      <releases>
        <enabled>true</enabled>
        <updatePolicy>never</updatePolicy>
      </releases>
      <snapshots>
        <enabled>true</enabled>
        <updatePolicy>daily</updatePolicy>
      </snapshots>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-core</artifactId>
      <version>${runtime.version}</version>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-decisiontables</artifactId>
      <version>${runtime.version}</version>
    </dependency>
    <dependency>
      <groupId>org.jbpm</groupId>
      <artifactId>jbpm-test</artifactId>
      <version>${runtime.version}</version>
    </dependency>
    <dependency>
      <groupId>org.kie.server</groupId>
      <artifactId>kie-server-client</artifactId>
      <version>${runtime.version}</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.10</version>
    </dependency>
    <dependency>
      <groupId>com.rabbitmq</groupId>
      <artifactId>amqp-client</artifactId>
      <version>5.13.1</version>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.10.19</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.droolsassert</groupId>
      <artifactId>droolsassert</artifactId>
      <version>3.0.8</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>failureaccess</artifactId>
      <version>1.0.1</version>
    </dependency>
  </dependencies>

</project>


编辑:

所以我通过尝试使用 gradle 而不是使用此过程

来构建,进一步缩小了问题范围
jar {
    manifest {
        attributes "Main-Class": "$mainClassName"
    }

    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

并显示此错误消息;

Caused by: org.gradle.api.GradleException: Could not expand ZIP 'C:\Users\asger.weirsoe\.m2\repository\org\kie\kie-ci.59.0.Final\kie-ci-7.59.0.Final.jar'.

现在我不是专家,并且对 JAVA 构建机制感到有点沮丧。但我认为这可能是我的问题,我需要的一些在后台获取的库没有烘焙到 .jar 文件中。导致我的问题。

我用谷歌搜索并在 the documentation for KIE. 中找到了这个,但说实话,这让我更加困惑而不是给了我答案。

问题在于 KIE 如何管理其依赖项。

解决方案是不要将所有内容都构建到同一个 jar 中,因为 KIE 打包了一些名称相同但功能不同的依赖项,这些依赖项会相互覆盖。