Search code examples
mavenjakarta-eedrools

Drools integration with Spring, issue loading DRL files in my test case


I am trying to use drools with Spring in a Maven Eclipse project. 1.My POM has the following

<properties>
<droolsVersion>5.5.0.Final</droolsVersion>
</properties>

  <dependencies>
    <dependency>
     <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>${droolsVersion}</version>
      </dependency>
     <dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>${droolsVersion}</version>
   </dependency>

      </dependencies>

    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.1.1</version>
            <executions>
                <execution>
                    <phase>test</phase>
                    <goals>
                        <goal>java</goal>
                    </goals>
                    <configuration>
                        <mainClass>com.sample.app.Test2</mainClass>

                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>jboss</id>
        <name>jboss</name>
        <url><a href="https://repository.jboss.org/nexus/content/groups/public/</url>">https://repository.jboss.org/nexus/content/groups/public/</url></a>
    </repository>
</repositories>

2.My sample class is here

      package com.services.dms.model;

        public class Account {
       private Integer balance;


    public Account() {}
    public Integer getBalance() {
        return balance;
    }
    public void setBalance(Integer balance) {
        this.balance = balance;
    }
    public Account(Integer balance) {
        super();
        this.balance = balance;
    }
    public void withdraw(int money) {
        balance -= money;
    }

}

  1. My test main class

        package com.services.dms.service;
    
       import org.drools.KnowledgeBase;
         import org.drools.builder.KnowledgeBuilder;
       import org.drools.builder.KnowledgeBuilderFactory;
      import org.drools.builder.ResourceType;
      import org.drools.io.ResourceFactory;
      import org.drools.runtime.StatelessKnowledgeSession;
    
      import com.services.dms.model.Account;
    
        public class Test2 {
        public static final void main(String[] args) {
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newClassPathResource("testrule.drl"), ResourceType.DRL);
    KnowledgeBase kbase = kbuilder.newKnowledgeBase();
    StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
    Account account = new Account(200);
    account.withdraw(150);
    ksession.execute(account);
    
        }
      }
    
  2. And my testrule.drl is

     package com.services.dms.service
    
     import com.services.model.account;
    
    rule "accountBalanceAtLeast"
    when
     $account : Account( balance < 100 )
    then
     System.out.println("Warning! money running out!");
     end
    

So when I run this project i get a file not found exception and it is not able to find the .drl file.

DRL file stored in src->resources->rules Even When I put the rule file in the same package as my test main class I get the same error.


Solution

  • A classpath resource is expected in one of the directories that are collected in it. Most likely src/resources/rules is not part of the classpath. I don't know what you mean by "put the file in the same package as my test main class", but chances are that you just change the package statement of the DRL file.

    Think how com.services.dms.model.Account is found by the JVM: the directory where com.services.dms.model.Account is rooted must be part of the classpath. So: put your DRL file there and expect it to be found. Conversely, prefix some directory levels to the filename in your Test2.main.

    Always, always, always call the KnowledgeBuilder methods hasErrors and getErrors after adding a resource, e.g.:

    if( kbuilder.hasErrors() ){
        System.err.println( "### compilation errors ###" );
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        for( KnowledgeBuilderError err: errors ){
            System.err.println( err.toString() );
        }
        throw new IllegalStateException( "compile errors" );
    }
    

    This will show you clearly where the problem in your DRL file is. (A double fault ;-) )