Drools DRL file on a package can't read
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).
In your code, when you add the knowledgebase, just keep the file name as Example1.drl
not Example
.
user2785929
Updated on June 04, 2022Comments
-
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
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 over 10 yearsIs that really the case? When I remove the
com.neu.als
package and put it back to thesrc/main/rules
, I was able to read theDRL
file. And by the way I can't findsrc/main/resources
-
Steve over 10 yearsIt 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 over 10 yearsHow 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 insrc/main/resources
? Am I right? -
user2785929 over 10 yearsI also put my configuration in
web.xml
and thebean configuration
( if I'm not mistaken of what is it called ), see my update -
Steve over 10 yearsThe 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 over 10 yearsYour 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 over 10 yearsCould you give a sample
pom.xml
that suits my need? I don't exactly know what should I write on that. -
Steve over 10 yearsThere'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 over 10 yearsSir 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 over 10 yearsI 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 over 10 yearsI see, I'm using Spring MVC and Drools on you POM what should I take to setup a Maven for my project?
-
Steve over 10 yearsMaven is an application that builds your project and pulls in dependencies. See link above.
-
user2785929 over 10 yearsThanks for the guidance