2013-02-08 31 views
0

我在一個小Drools項目工作,我有以下問題:

- 當我通過knowledgeAgent滴料閱讀knowledgepackages它需要很長的時間來加載
((現在我知道,建設一般知識庫特別是當從裝載的Guvnor包是非常激烈))KnowledgeAgent是否可以用於自動將知識庫寫入文件以便可以在外部使用?

  • 所以我想給知識庫序列化到位於本地系統
    上的文件 - 一方面是因爲從本地加載kBase文件要快得多
    - 對於另一個,這樣我就可以將知識庫用於其他應用程序
    問題這是,當使用KnowledgeAgent第一次加載知識庫時,基地將自動更新

    但是:雖然基地更新,我的本地文件也不會更新
    所以我' m想知道如何處理/從我的KnowledgeAgent獲取changeNotification,以便我可以調用一個方法來序列化我的知識庫?


    這是不是有可能?基本上我只想更新我的本地知識庫文件,每次有人在州長編輯規則時,這樣我的本地文件總是最新的。


    如果這是不可能的,或者是一個非常糟糕的解決方案,那麼最好的解決方法是什麼?


    請忍受我的英語和問題本身,如果你真的不知道我想完成什麼,或者如果我的要求實際上不是一個好的解決方案或問題本身是多餘的,我相當新的Java和總noob當涉及流口水。

樓下是代碼:

公共類DroolsConnection {

private static KnowledgeAgent kAgent; 
private static KnowledgeBase kAgentBase; 

public DroolsConnection(){ 
    ResourceFactory.getResourceChangeNotifierService().start(); 
    ResourceFactory.getResourceChangeScannerService() .start(); 

} 

public KnowledgeBase readKnowledgeBase() throws Exception { 

    kAgent  = KnowledgeAgentFactory.newKnowledgeAgent("guvnorAgent"); 
    kAgent  .applyChangeSet(ResourceFactory.newFileResource(CHANGESET_PATH)); 
    kAgent.monitorResourceChangeEvents(true); 

    kAgentBase = kAgent.getKnowledgeBase(); 
    serializeKnowledgeBase(kAgentBase); 
    return kAgentBase; 

    } 


public List<EvaluationObject> runAgainstRules(List<EvaluationObject> objectsToEvaluate, 
               KnowledgeBase kBase) throws Exception{ 

    StatefulKnowledgeSession knowSession = kBase.newStatefulKnowledgeSession(); 
    KnowledgeRuntimeLogger knowLogger = KnowledgeRuntimeLoggerFactory.newFileLogger(knowSession, "logger"); 

    for (EvaluationObject o : objectsToEvaluate){ 
     knowSession.insert(o); 
    } 

    knowSession.fireAllRules(); 
    knowLogger .close(); 
    knowSession.dispose(); 
    return objectsToEvaluate; 
} 


public KnowledgeBase serializeKnowledgeBase(KnowledgeBase kBase) throws IOException{ 

     OutputStream outStream = new FileOutputStream(SERIALIZE_BASE_PATH); 
     ObjectOutputStream oos = new ObjectOutputStream(outStream); 
     oos.writeObject  (kBase); 
     oos.close(); 
     return kBase; 
} 


public KnowledgeBase loadFromSerializedKnowledgeBase() throws Exception { 

     KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase(); 
     InputStream is  = new FileInputStream(SERIALIZE_BASE_PATH); 
     ObjectInputStream ois = new ObjectInputStream(is); 
     kBase     = (KnowledgeBase) ois.readObject(); 
     ois.close(); 
     return kBase; 
} 

}


感謝您的幫助提前!
最好的問候,
Marenko

回答

0

爲了保持當地kbase更新,你可以使用一個KnowledgeAgentEventListener知道什麼時候它的內部kbase得到更新:

kagent.addEventListener(new KnowledgeAgentEventListener() { 

     public void beforeChangeSetApplied(BeforeChangeSetAppliedEvent event) { 
     } 

     public synchronized void afterChangeSetApplied(AfterChangeSetAppliedEvent event) { 
     } 

     public void beforeChangeSetProcessed(BeforeChangeSetProcessedEvent event) { 
     } 

     public void afterChangeSetProcessed(AfterChangeSetProcessedEvent event) { 
     } 

     public void beforeResourceProcessed(BeforeResourceProcessedEvent event) { 
     } 

     public void afterResourceProcessed(AfterResourceProcessedEvent event) { 
     } 

     public void knowledgeBaseUpdated(KnowledgeBaseUpdatedEvent event) { 
      //THIS IS THE EVENT YOU ARE INTERESTED IN 
     } 

     public void resourceCompilationFailed(ResourceCompilationFailedEvent event) {    
     } 
    }); 

你仍然需要處理您同時訪問本地kbase雖然。

順便說一下,由於您沒有使用'newInstance'配置選項,因此每次應用更改集時,代理將創建一個kbase的新實例。所以,請確保您序列化kagent的內部kbase(kagent.getKnowledgeBase()),而不是您在應用中的引用。

希望它能幫助,

+0

非常感謝您的回答,我希望這就是我一直在尋找,太。當我遇到一個問題,生病回到你身邊,非常感謝回覆:) – Marenko

+0

當我嘗試序列化event.getKnowledgeBase int konwledgeBaseUpdated函數,我得到一個io。EOFException當試圖從序列化知識庫讀取(「在java.io.ObjectInputStream.something(Unknown Source)」。當我刪除eventlistener它工作得很好,你有什麼想法嗎? – Marenko

+0

你有完整的stacktrace ? –

相關問題