[rules-dev] Classpath Resources and Classloaders using cache

Esteban Aliverti esteban.aliverti at gmail.com
Fri Apr 15 17:38:33 EDT 2011


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 at 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 at lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-dev
>
>
> --
> With kind regards,
> Geoffrey De Smet
>
>
> _______________________________________________
> rules-dev mailing list
> rules-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-dev/attachments/20110415/6107270d/attachment.html 


More information about the rules-dev mailing list