There is no need to update your kbase in the listener. The agent will apply all the changes to the provided kbase. If you already have a stateful ksession from that kbase, then the changes in the kbase should be reflected immediately.<div>

Could you please post the log output of the kagent?</div><div><br></div><div>Best Regards, <br clear="all"><br>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br><br>Esteban Aliverti<br>- Developer @ <a href="http://www.plugtree.com" target="_blank">http://www.plugtree.com </a><br>

- Blog @ <a href="http://ilesteban.wordpress.com" target="_blank">http://ilesteban.wordpress.com</a><br>
<br><br><div class="gmail_quote">On Tue, Apr 19, 2011 at 4:24 AM, Mattias Avelin <span dir="ltr">&lt;<a href="mailto:mattias.avelin@netlight.se">mattias.avelin@netlight.se</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Hi!<br>
<br>
Yes, I have already implemented a KnowledgeAgentEventListener acts on KnowledgeBaseUpdatedEvent and ResourceCompilationFailedEvent. I use this to update my knowledgebase reference in my class that wraps the KnowledgeBase and KnowledgeAgent. Below is the code for this class (&quot;DynamicDecisionService&quot;). I suspect that I have missed something vital since I&#39;m actually not getting my knowledgebase to update itself either but I &quot;do it myself&quot; in the listener when I receive a KnowledgeBaseUpdatedEvent.<br>


<br>
Here is the code that handles the KnowledgeAgent and KnowledgeBase (I have stripped out some labels and comments since this belongs to the client).<br>
<br>
Best regards<br>
<br>
Mattias Avelin<br>
<br>
package com.x.service;<br>
<br>
import java.util.ArrayList;<br>
import org.apache.log4j.Logger;<br>
import org.drools.KnowledgeBase;<br>
import org.drools.KnowledgeBaseConfiguration;<br>
import org.drools.KnowledgeBaseFactory;<br>
import org.drools.agent.KnowledgeAgent;<br>
import org.drools.agent.KnowledgeAgentConfiguration;<br>
import org.drools.agent.KnowledgeAgentFactory;<br>
import org.drools.builder.KnowledgeBuilderError;<br>
import org.drools.builder.KnowledgeBuilderErrors;<br>
import org.drools.conf.EventProcessingOption;<br>
import org.drools.event.knowledgeagent.KnowledgeBaseUpdatedEvent;<br>
import org.drools.event.knowledgeagent.ResourceCompilationFailedEvent;<br>
import org.drools.event.rule.DefaultKnowledgeAgentEventListener;<br>
import org.drools.io.ResourceChangeScannerConfiguration;<br>
import org.drools.io.ResourceFactory;<br>
<br>
/**<br>
 * {@inheritDoc}<br>
 * &lt;p&gt;<br>
 * This implementation of DecisionService updates the knowledgebase dynamically<br>
 * when the underlying rules (drl-files) are updated. Therefore each call to the<br>
 * createSession() method will return a session based on the most resent version<br>
 * of the rules (allowing for some lag due to the intervals of the<br>
 * resource scanner).<br>
 * &lt;/p&gt;<br>
 * &lt;p&gt;<br>
 * For statefull sessions the session needs to be updated &quot;manually&quot; when the<br>
 * KnowledgeBase has been updated.<br>
 * &lt;/P&gt;<br>
 * @author Mattias Avelin - <a href="mailto:mattias.avelin@netlight.se">mattias.avelin@netlight.se</a><br>
 */<br>
public class DynamicDecisionService implements DecisionService<br>
{<br>
    private static Logger LOG = Logger.getLogger(DynamicDecisionService.class);<br>
<br>
    // Repository of all the application&#39;s knowledge definitions<br>
    private KnowledgeBase kBase;<br>
    // The agent that monitores the rule files (resources) for changes<br>
    private KnowledgeAgent kAgent;<br>
    // Decision service type<br>
    private DecisionSessionType type;<br>
    // When the current knowledgebase was created<br>
    private long kbaseLastUpdated;<br>
<br>
    /**<br>
     * Create a DynamicDecisionService using a ChangeSet.<br>
     *<br>
     * @param changeSet - The ChangeSet referencing the rule-files to use<br>
     *                    for this service. Expects a classpath reference<br>
     *<br>
     * @throws IllegalArgumentException if changeSet is not a valid ChangeSet.<br>
     */<br>
    public DynamicDecisionService(<br>
            String changeSet,<br>
            DecisionSessionType type)<br>
    {<br>
        this.kBase = createKnowledgeBase(type);<br>
        // the method could reference kBase itself but I thought it<br>
        // more more &quot;clear&quot; if I actually supply it in the method invocation<br>
        this.kAgent = createKnowledgeAgent(changeSet, this.kBase);<br>
        // This should not be neccesary according to all sources I&#39;ve found<br>
        // but without re-assigning the reference it doesn&#39;t work!?!?<br>
        this.kBase = kAgent.getKnowledgeBase();<br>
        this.kbaseLastUpdated = System.currentTimeMillis();<br>
    }<br>
<br>
<br>
    /**<br>
     * {@inheritDoc}<br>
     */<br>
    public DecisionSession createSession ()<br>
    {<br>
        return new DecisionSession(kBase.newStatefulKnowledgeSession());<br>
    }<br>
<br>
<br>
    /**<br>
     * {@inheritDoc}<br>
     */<br>
    public DecisionSession updateSession (DecisionSession oldSession)<br>
    {<br>
        // Create a new session from the current KnowledgeBase<br>
        DecisionSession newSession =<br>
                new DecisionSession(kBase.newStatefulKnowledgeSession());<br>
<br>
        if(oldSession != null)<br>
        {<br>
            // &quot;Clean&quot; the old session of all stateless facts before update<br>
            oldSession.removeAllStatelessKnowledge();<br>
            // Copy all remaining facts to the new session<br>
            newSession.uploadKnowledge(new ArrayList(oldSession.getAllFacts()));<br>
        }<br>
        return newSession;<br>
    }<br>
<br>
<br>
    /**<br>
     * {@inheritDoc}<br>
     */<br>
    public boolean isSessionStale(DecisionSession decisionSession)<br>
    {<br>
        if(decisionSession.getCreationTime() &lt; this.kbaseLastUpdated)<br>
        {<br>
            return true;<br>
        }<br>
        else<br>
        {<br>
            return false;<br>
        }<br>
    }<br>
<br>
<br>
    /**<br>
     * Create a KnowledgeBuilder from a ChangeSet.<br>
     *<br>
     * @param changeSet - The ChangeSet<br>
     * @return A KnowledgeBuilder<br>
     * @throws IllegalArgumentException if changeSet is not a valid ChangeSet.<br>
     */<br>
    private KnowledgeAgent createKnowledgeAgent(<br>
            String changeSet,<br>
            KnowledgeBase kbase)<br>
    {<br>
        // Configure KnowledgeAgentFactory<br>
        configureAgentFactory();<br>
        // Create the knowledge agent<br>
        KnowledgeAgent agent = KnowledgeAgentFactory.newKnowledgeAgent(<br>
                &quot;classificationAgent&quot;,<br>
                kbase);<br>
        agent.applyChangeSet(ResourceFactory.newClassPathResource(changeSet));<br>
        // Add actionListener for detecting rule updates<br>
        agent.addEventListener(new xKnowledgeAgentEventListener());<br>
        // Start the monitoring...<br>
        ResourceFactory.getResourceChangeNotifierService().start();<br>
        ResourceFactory.getResourceChangeScannerService().start();<br>
        return agent;<br>
    }<br>
<br>
<br>
    /**<br>
     * Configure the agentFactory.<br>
     */<br>
    private void configureAgentFactory()<br>
    {<br>
        // Enable incremental knowledge base build - false means that the<br>
        // old knowledge base is &quot;reused&quot; and updated when there are<br>
        // updated rules. True means that the old base is discarded and a new<br>
        // one is created<br>
        KnowledgeAgentConfiguration kagentConf =<br>
        KnowledgeAgentFactory.newKnowledgeAgentConfiguration();<br>
        kagentConf.setProperty(&quot;drools.agent.newInstance&quot;, &quot;false&quot;);<br>
<br>
        // Configure the scanning interval - default is 60 sec.<br>
        // (Scanning resources for changes...)<br>
        ResourceChangeScannerConfiguration sconf =<br>
        ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();<br>
        sconf.setProperty(&quot;drools.resource.scanner.interval&quot;, &quot;30&quot;);<br>
        ResourceFactory.getResourceChangeScannerService().configure(sconf);<br>
    }<br>
<br>
<br>
    /**<br>
     * Create a KnowledgeBase. For CEP (Drools Fusion) decision service<br>
     * use type = STATE_FULL otherwise use STATE_LESS.<br>
     *<br>
     * @param type - The type KnowledgeBase, state full or state less<br>
     *<br>
     * @return A KnowledgeBase<br>
     */<br>
    private KnowledgeBase createKnowledgeBase(DecisionSessionType type)<br>
    {<br>
        KnowledgeBase kbase;<br>
        if(type.equals(DecisionSessionType.STATE_FULL)){<br>
            KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();<br>
            config.setOption( EventProcessingOption.STREAM );<br>
            kbase = KnowledgeBaseFactory.newKnowledgeBase( config );<br>
        }<br>
        else<br>
        {<br>
            kbase = KnowledgeBaseFactory.newKnowledgeBase();<br>
        }<br>
        return kbase;<br>
    }<br>
<br>
<br>
    /**<br>
     * Get the ServiceType of this Service.<br>
     *<br>
     * @return The ServiceType of this service (STATE_FULL or STATE_LESS)<br>
     */<br>
    public DecisionSessionType getType ()<br>
    {<br>
        return type;<br>
    }<br>
<br>
<br>
    /**<br>
     * When was the KnowledgeBase last updated.<br>
     *<br>
     * @return The timestamp (ms) for last update of KnowledgeBase<br>
     */<br>
    public long getLastUpdated()<br>
    {<br>
        return this.kbaseLastUpdated;<br>
    }<br>
<br>
<br>
    /**<br>
     * Custom event listener for acting on events such as rule updates and<br>
     * rule loading errors.<br>
     */<br>
    private class xKnowledgeAgentEventListener<br>
            extends DefaultKnowledgeAgentEventListener<br>
    {<br>
<br>
        /**<br>
         * Update the working copy of the  KnowledgeBase when detecting<br>
         * a updated one.<br>
         *<br>
         * @param event - The event signalling that the rule base has been updated<br>
         */<br>
        @Override<br>
        public void knowledgeBaseUpdated (<br>
                KnowledgeBaseUpdatedEvent event)<br>
        {<br>
            LOG.info(&quot;Detected updated rules! Rebuilding knowledgeBase!&quot;);<br>
            long startTime = System.currentTimeMillis();<br>
            kBase = kAgent.getKnowledgeBase();<br>
            long endTime = System.currentTimeMillis();<br>
            // Update the timestamp for when the knowledgeBase was updated<br>
            kbaseLastUpdated = endTime;<br>
            LOG.info(&quot;Rebuilding knowledgebase took &quot; +<br>
                    (endTime - startTime) + &quot;ms...&quot;);<br>
        }<br>
<br>
<br>
        /**<br>
         * Log errors when problems updating the knowledge base.<br>
         *<br>
         * @param event - the Event signalling failure to load updated rules<br>
         */<br>
        @Override<br>
        public void resourceCompilationFailed (<br>
                ResourceCompilationFailedEvent event)<br>
        {<br>
            KnowledgeBuilderErrors errors =<br>
                    event.getKnowledgeBuilder().getErrors();<br>
<br>
            if (errors.size() &gt; 0)<br>
            {<br>
                LOG.error(&quot;Errors loading knowledge.&quot;);<br>
                for (KnowledgeBuilderError error : errors)<br>
                {<br>
                    LOG.error(error);<br>
                }<br>
            }<br>
        }<br>
    }<br>
}<br>
<br>
<br>
<br>
<br>
<br>
________________________________________<br>
<div class="im">From: <a href="mailto:rules-users-bounces@lists.jboss.org">rules-users-bounces@lists.jboss.org</a> [<a href="mailto:rules-users-bounces@lists.jboss.org">rules-users-bounces@lists.jboss.org</a>] On Behalf Of Esteban Aliverti [<a href="mailto:esteban.aliverti@gmail.com">esteban.aliverti@gmail.com</a>]<br>


</div>Sent: Monday, April 18, 2011 19:18<br>
<div class="im">To: Rules Users List<br>
Subject: Re: [rules-users] Dynamic updates of stateful sessions<br>
<br>
</div><div class="im">Maybe the new rules fail to compile. You can add an KnowledgeAgentEventListener to the agent to check for compilation errors.<br>
Could you post some code snippet showing how are you creating the kagent, the kbase, etc.<br>
<br>
You can take a look at some tests using newInstence=false here:<br>
<a href="https://github.com/droolsjbpm/drools/blob/master/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentIncrementalChangeSetTest.java" target="_blank">https://github.com/droolsjbpm/drools/blob/master/drools-compiler/src/test/java/org/drools/agent/KnowledgeAgentIncrementalChangeSetTest.java</a><br>


<br>
Best Regards,<br>
<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
<br>
Esteban Aliverti<br>
- Developer @ <a href="http://www.plugtree.com" target="_blank">http://www.plugtree.com</a><br>
- Blog @ <a href="http://ilesteban.wordpress.com" target="_blank">http://ilesteban.wordpress.com</a><br>
<br>
<br>
</div><div class="im">On Mon, Apr 18, 2011 at 1:31 PM, Mattias Avelin &lt;<a href="mailto:mattias.avelin@netlight.se">mattias.avelin@netlight.se</a>&lt;mailto:<a href="mailto:mattias.avelin@netlight.se">mattias.avelin@netlight.se</a>&gt;&gt; wrote:<br>


Thanks for the swift reply!<br>
<br>
I have configured my Knowledge Agent to reuse the same KnowledgeBase (set drools.agent.newInstance property to &quot;false&quot; in my KnowledgeAgentConfiguration) as described in the Expert documentation. But my stateful session keeps using the old rules event though I can see from the log output that the Knowledgebase has been updated.<br>


<br>
/Mattias<br>
________<br>
</div>From: <a href="mailto:rules-users-bounces@lists.jboss.org">rules-users-bounces@lists.jboss.org</a>&lt;mailto:<a href="mailto:rules-users-bounces@lists.jboss.org">rules-users-bounces@lists.jboss.org</a>&gt; [<a href="mailto:rules-users-bounces@lists.jboss.org">rules-users-bounces@lists.jboss.org</a>&lt;mailto:<a href="mailto:rules-users-bounces@lists.jboss.org">rules-users-bounces@lists.jboss.org</a>&gt;] On Behalf Of Esteban Aliverti [<a href="mailto:esteban.aliverti@gmail.com">esteban.aliverti@gmail.com</a>&lt;mailto:<a href="mailto:esteban.aliverti@gmail.com">esteban.aliverti@gmail.com</a>&gt;]<br>


<div class="im">Sent: Monday, April 18, 2011 16:49<br>
To: Rules Users List<br>
Subject: Re: [rules-users] Dynamic updates of stateful sessions<br>
<br>
By default, the Knowledge Agent creates a new kbase when changes in the monitored resources are detected. So the stateful sessions you had are not going to &quot;see&quot; the changes because they belong to a different kbase.<br>


If you want the agent to apply the changes to the current kbase, you need to set drools.agent.newInstance property to &quot;false&quot; in knowledge agent configuration.<br>
You can read about this here: <a href="http://ilesteban.wordpress.com/2010/03/25/knowledge-agent-incremental-change-set-processing-and-binary-diff/" target="_blank">http://ilesteban.wordpress.com/2010/03/25/knowledge-agent-incremental-change-set-processing-and-binary-diff/</a><br>


<br>
If you are defining the kagent using spring, you can use the &quot;newInstence&quot; attribute of &lt;kagent&gt; bean.<br>
<br>
Best Regards,<br>
<br>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
<br>
Esteban Aliverti<br>
- Developer @ <a href="http://www.plugtree.com" target="_blank">http://www.plugtree.com</a><br>
- Blog @ <a href="http://ilesteban.wordpress.com" target="_blank">http://ilesteban.wordpress.com</a><br>
<br>
<br>
</div><div class="im">On Mon, Apr 18, 2011 at 11:41 AM, Mattias Avelin &lt;<a href="mailto:mattias.avelin@netlight.se">mattias.avelin@netlight.se</a>&lt;mailto:<a href="mailto:mattias.avelin@netlight.se">mattias.avelin@netlight.se</a>&gt;&lt;mailto:<a href="mailto:mattias.avelin@netlight.se">mattias.avelin@netlight.se</a>&lt;mailto:<a href="mailto:mattias.avelin@netlight.se">mattias.avelin@netlight.se</a>&gt;&gt;&gt; wrote:<br>


We have a application in which we have both stateless &amp; stateful sessions<br>
running. We&#39;re using the KnowledgeAgent and ChangeSets to automatically<br>
update our knowledge bases when the rules are changed.<br>
This works fine for our stateless sessions for which we are creating a new<br>
session for each request and if the rules have been updated this is<br>
reflected in next session we create.<br>
<br>
But for stateful sessions I&#39;m not quite as sure on how to get it working. I<br>
can see in the logs that the KnowledgeBase is re-built when the<br>
KnowledgeAgent detects the updated rule files. But my &quot;long running&quot; session<br>
is does not reflect these changes (which it shouldn&#39;t right?). But how do we<br>
apply these changes to the stateful session without loosing all the facts I<br>
accumulated?<br>
<br>
The way I&#39;ve solved it now is to keep a &quot;last updated&quot; timestamp for the<br>
knowledgeBase and a &quot;created&quot; timestamp for the session and then compare<br>
these before using the session. If the knowledgeBase&#39;s &quot;update timestamp&quot; is<br>
later that the sessions &quot;creation timestamp&quot; I create a new Session and then<br>
&quot;manually&quot; copy all facts from the former to the latter.<br>
<br>
Is this the way you would do this or is there a better way?<br>
<br>
Best Regards<br>
<br>
Mattias Avelin<br>
<br>
<br>
_______________________________________________<br>
rules-users mailing list<br>
</div><a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>&lt;mailto:<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>&gt;&lt;mailto:<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>&lt;mailto:<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>&gt;&gt;<br>


<div><div></div><div class="h5"><a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
<br>
<br>
______________________________________________________________________<br>
This email has been scanned by the MessageLabs Email Security System.<br>
For more information please visit <a href="http://www.messagelabs.com/email" target="_blank">http://www.messagelabs.com/email</a><br>
______________________________________________________________________<br>
<br>
<br>
<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>&lt;mailto:<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a>&gt;<br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
<br>
<br>
______________________________________________________________________<br>
This email has been scanned by the MessageLabs Email Security System.<br>
For more information please visit <a href="http://www.messagelabs.com/email" target="_blank">http://www.messagelabs.com/email</a><br>
______________________________________________________________________<br>
<br>
<br>
<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</div></div></blockquote></div><br></div>