Hi Geoffrey,
thanks for sharing your opinion!
When drools-spring creates the resource from the configuration file, it
creates it passing the class' class loader:
new ClassPathResource(path, ClassPathResource.class.getClassLoader() );
Internally, ClassPathResource is doing:
this.classLoader = ClassLoaderUtil.getClassLoader( new ClassLoader[] {
classLoader },null, false );
So, a classloader is indeed supplied. AFAIK, the problem is that the
provided classloader is tomcat's classloader.
I know it is dangerous to store native URLs instead of the classpath, but
after all, after you deploy drools-server, each of the resources will have
an URL.
If this is a problem, you can always use classpath resources. That is why I
thought in a new Resource type and not in modify ClassPathResource class.
I have created an issue for this:
https://issues.jboss.org/browse/JBRULES-2960
Thanks again for your time!
Best Regards,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Esteban Aliverti
- Developer @
http://www.plugtree.com
- Blog @
http://ilesteban.wordpress.com
On Fri, Apr 15, 2011 at 9:38 AM, Geoffrey De Smet
<ge0ffrey.spam(a)gmail.com>wrote:
The kbuilder uses the second method of ClassPathResource
(getInputStream()) to get the content of the resource.
Shouldn't that also supply a ClassLoader or a Class (of which
Class.getClassLoader() is used)?
This resource type will let you define your resources present in your
classpath as usually but it will translate them to URL Resource internally.
It's probably dangerous to store the native URL the concept of a classpath
is designed to have a map of files "that are just there" and you don't
need
to worry what's the OS-specific underlying details.
Instead, I believe, the classpath key (for example "simpler.drl") and the
ClassLoader (for example MyApp.class.getClassLoader()) should be stored.
Op 15-04-11 13:52, Esteban Aliverti schreef:
Hi Guys,
I want to discuss a problem I have found when using the combination of
knowledge agent + classpathResources.
I will try to describe what am I doing first to give you some context.
I'm deploying drools-camel-server in a Tomcat 7 container. Inside the
WEB-INF/classes directory I have some DRL files that I want to use.
My knowledge-services.xml file declares the following kagent:
<drools:kagent id="kagent1" kbase="kbase1"
new-instance="false">
<drools:resources>
<drools:resource type="DRL"
source="*classpath*:simple.drl"/>
...
</drools:resources>
</drools:kagent>
When spring parses this configuration file it creates a KnowledgeAgent
instance with a ChangeSet containing all the listed resources.
The next step is to start ResourceChangeNotifierService
and ResourceChangeScannerService.
So far so good.
The problem:
The problem I'm having is not directly related to drools, but I think it is
quite easy to provide a solution for the people that is in my same
situation.
ClassPathResource is the class that represents a resource defined as "*
classpath:"*
This class has 2 important methods:
public long getLastModified(){
return this.classLoader.getResource( this.path
).openConnection().getLastModified();
}
public InputStream getInputStream(){
return this.classLoader.getResourceAsStream( this.path );
}
The first method is used by ResourceChangeScannerService to check whether
the resource has changed or not. It works fine. When the resource in the
filesystem changes, the scanner detects the change without any problem.
The scanner ends up notifying the kagent about the change, and the kagent
passes the Resource to an instance of KnowledgeBuilder.
An here is when things fail.
The kbuilder uses the second method of ClassPathResource (getInputStream())
to get the content of the resource. In the case of Tomcat (and probably some
other environments), it seems that the classloader (Tomcat's classloader) is
using a cache. So the InputStream returned doesn't reflect the current state
of the resource.
Long story short: the agent is notified about a change in the resource, but
the change is never applied to the kbase because the kbuilder is unable to
get it :P
Solutions:
The first solution is not to use classpath resources :). You can use just
url resources like http:// or file:/. But honestly, when you have your
rules inside your webapp, it is much more comfortable and even manageable to
avoid the use of real paths.
What I was thinking about (I already have a working prototype) is to
create a new Resource type for these cases. This resource type will let you
define your resources present in your classpath as usually but it will
translate them to URL Resource internally.
So, in the example above:
<drools:resource type="DRL"
source="*URLClasspath*:simple.drl"/>
is going to be translated (internally and in a transparent way) to
something like:
file:/usr/local/apache-tomcat-7/webapps/MyWebapp/WEB-INF/simple.drl.
Opinions?
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Esteban Aliverti
- Developer @
http://www.plugtree.com
- Blog @
http://ilesteban.wordpress.com
_______________________________________________
rules-dev mailing
listrules-dev@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-dev
--
With kind regards,
Geoffrey De Smet
_______________________________________________
rules-dev mailing list
rules-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-dev