Drools DRL file on a package can't read

10,212

Solution 1

Your knowledge base is being built using "neu/als/KnowledgeLevel" as the classpath, whereas according to your directory structure, the correct path would be "com/neu/als/KnowledgeLevel".

I wouldn't expect src/main/rules to be on the project classpath, which could also impact this.

I usually keep my rules under src/main/resources so that Maven builds them into the classpath.

Solution 2

Just for help :If any one use code:

KieFileSystem kieFileSystem = kieServices.newKieFileSystem();    
Resource resource = kieResources.newClassPathResource("EvaluationDossier.drl");
String resourcepath = "src/main/resources/rules" + "/" + "RulesCompiled.drl";
kieFileSystem.write(resourcepath, resource);

and facing this exception:

Exception in thread « main » java.lang.RuntimeException: Unable to get LastModified for ClasspathResource
..........................
Caused by: java.io.FileNotFoundException: ‘EvaluationDossier.drl’ cannot be opened because it does not exist

After a few search i resolve it by adding these line in the pom.xml

<build>
        <resources>
            <resource>
                <directory>src/main/resources/rules</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
            </resource>
        </resources>
    </build>

Solution 3

You should put the rule file in resource folder (which is working for me).

enter image description here

In your code, when you add the knowledgebase, just keep the file name as Example1.drl not Example.

Share:
10,212
user2785929
Author by

user2785929

Updated on June 04, 2022

Comments

  • user2785929
    user2785929 about 2 years

    I'm new to drools, and I can't access my DRL file inside a package. That is what I thought. My hierarchy of the rules of my project is like this

    enter image description here

    I tried to access the DRL file with this code:

    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
            kbuilder.add( ResourceFactory.newClassPathResource( "neu/als/KnowledgeLevel", getClass() ), ResourceType.DRL );
            KnowledgeBuilderErrors errors = kbuilder.getErrors();
    
            if( errors.size() > 0 )
            {
                for( KnowledgeBuilderError error : errors )
                {
                    System.err.println( error );
                }
                throw new IllegalArgumentException( "Could not parse knowledge." );
            }
    
            KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
            kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
            return kbase;
    

    Which is resulting to an error:

    java.lang.RuntimeException: Unable to get LastModified for ClasspathResource
        at org.drools.io.impl.ClassPathResource.getLastModified(ClassPathResource.java:204)
        at org.drools.io.impl.ClassPathResource.getInputStream(ClassPathResource.java:141)
        at org.drools.compiler.DrlParser.parse(DrlParser.java:145)
        at org.drools.compiler.DrlParser.parse(DrlParser.java:139)
        at org.drools.compiler.PackageBuilder.drlToPackageDescr(PackageBuilder.java:477)
        at org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:466)
        at org.drools.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.java:694)
        at org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:51)
        at org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:40)
        at com.neu.als.thesis.units.InferenceEngine.readKnowledgeBase(InferenceEngine.java:52)
        at com.neu.als.thesis.web.controllers.FLTController.evaluateFLT(FLTController.java:124)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
        at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:444)
        at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:432)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:946)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:848)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:822)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
    Caused by: java.io.FileNotFoundException: 'neu/als/KnowledgeLevel.drl' cannot be opened because it does not exist
        at org.drools.io.impl.ClassPathResource.getURL(ClassPathResource.java:165)
        at org.drools.io.impl.ClassPathResource.getLastModified(ClassPathResource.java:177)
        ... 40 more
    

    What am I doing wrong?

    UPDATE:

    Here is my web.xml

    <servlet>
          <servlet-name>ThesisProject</servlet-name>
          <servlet-class>
             org.springframework.web.servlet.DispatcherServlet
          </servlet-class>
          <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
          <servlet-name>ThesisProject</servlet-name>
          <url-pattern>*.do</url-pattern>
      </servlet-mapping>
    
      <context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/ThesisProject-servlet.xml</param-value>
      </context-param>
    
      <listener>
         <listener-class>
            org.springframework.web.context.ContextLoaderListener
         </listener-class>
      </listener>
    

    and my bean config

    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans     
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
      <context:component-scan base-package="com.neu.als.thesis.web.controllers" />
    
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
      </bean>
    
    </beans>
    

    Added some configuration

  • user2785929
    user2785929 over 10 years
    Is that really the case? When I remove the com.neu.als package and put it back to the src/main/rules, I was able to read the DRL file. And by the way I can't find src/main/resources
  • Steve
    Steve over 10 years
    It rather depends on how your project is configured. Whether it will build the contents of src/main/rules into a classpath location. Note just spotted a bug so will add that to the answer.
  • user2785929
    user2785929 over 10 years
    How do I know if I'm using Maven? Or the fact that I don't know prove that I'm not using Maven? About the classpath, so you mean that I should create a new folder instead of src/main/rules, I should keep it in src/main/resources? Am I right?
  • user2785929
    user2785929 over 10 years
    I also put my configuration in web.xml and the bean configuration( if I'm not mistaken of what is it called ), see my update
  • Steve
    Steve over 10 years
    The src/main/* path is a convention that was introduced by Maven (from what I remember), and Maven is used heavily by the Drools projects. However, it is now a popular convention, so not all projects with that structure are Maven projects. :) You will be using Maven if you build your project by typing something like "mvn clean install". Although there are Maven plugins for Eclipse and other IDEs which could hide that piece of info.
  • Steve
    Steve over 10 years
    Your specific bug looks to be that you're not putting "com/" at the front of the classpath when you build the knowledge base. However, if using Maven, then the resulting Jar/War will be built with classes generated from "src/main/java" and with classpath resources (such as Spring configs and DRL) copied from "src/main/resources". If there's a pom.xml which mentions additional plugins, there may be more directories that are loaded on to the classpath, but that's not the standard config.
  • user2785929
    user2785929 over 10 years
    Could you give a sample pom.xml that suits my need? I don't exactly know what should I write on that.
  • Steve
    Steve over 10 years
    There's a pom.xml in the root of this project, which is sufficient for building a Spring web application with Drools rules services: github.com/gratiartis/sctrcd-payment-validation-web
  • user2785929
    user2785929 over 10 years
    Sir Its well documented but for a newbie like me, its a bit complicated to read the code. Please guide me a bit more. If I'm not wrong this will replace my bean configuration? And if I understand it right the the only thing I need in the build is the resources? In dependency I only need is the Spring MVC one. And nothing more?
  • Steve
    Steve over 10 years
    I must admit that it is a bit of a large application to understand with a quick look. My vague plan is to write a few tutorials around it. The pom.xml and bean definitions are separate things. The pom.xml defines the Jars that are needed by the application, for Spring, Drools, etc. The bean configuration is a definition of various objects within your application. For instance, if you look at that application, you will find bean definitions in src/main/webapp/WEB-INF/payment-web-servlet.xml
  • user2785929
    user2785929 over 10 years
    I see, I'm using Spring MVC and Drools on you POM what should I take to setup a Maven for my project?
  • Steve
    Steve over 10 years
    Maven is an application that builds your project and pulls in dependencies. See link above.
  • user2785929
    user2785929 over 10 years
    Thanks for the guidance