2011-08-16 2 views
0

규칙을 동적으로 다시로드하는 중 문제가 발생했습니다. 컨텍스트로 시작 : 총 10000 개의 규칙과 다양한 유형의 DRL 파일이 있습니다. 규칙을 컴파일하고 재배포하는 프로세스가 길어지기 시작 (2 분 이상)하기 때문에 수정 된 규칙 만 & 재배포를 컴파일하려고합니다.이미 선언 된 사실 유형을 사용하여 규칙을 동적으로 다시로드하는 방법은 무엇입니까?

DRL을 준수하려면 수정 된 규칙과 모든 사용 된 유형을 다시 배포하기 위해 DRL에 선언해야합니다.

우리의 문제는 새 DRL에 선언 된 유형이 이미 배포 된 유형과 병합되지 않기 때문에 해당 유형과 일치 할 때 새 규칙이 활성화되지 않는다는 것입니다.

ReteoRuleBase 개체를보고 TypeDeclaration 목록에 "Item"다음에 이름이 지정된 두 개의 클래스가 포함되어있는 것을 발견했습니다. 다시 배포 된 규칙이 올바른 개체와 일치하지 않는 이유는 분명합니다.

첫째, 배포 및 재배치 방법 노출 내 단위 테스트 : (첫 번째 배포) 원래 DRL을

@Test 
public void test_hot_deploy() throws FileNotFoundException { 
    File drl1 = new File("src/test/resources/essai-drools/hot-deploy-1.drl"); 
    Resource resource1 = ResourceFactory.newInputStreamResource(new FileInputStream(drl1)); 

    File drl2 = new File("src/test/resources/essai-drools/hot-deploy-2.drl"); 
    Resource resource2 = ResourceFactory.newInputStreamResource(new FileInputStream(drl2)); 

    KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
    builder.add(resource1, ResourceType.DRL); 
    KnowledgeBase kb = builder.newKnowledgeBase(); 
    StatefulKnowledgeSession session = kb.newStatefulKnowledgeSession(); 
    int fired = session.fireAllRules(); 
    Assert.assertEquals(2, fired); 

      System.out.println("--- redeploy ---"); 

    KnowledgeBuilder builder2 = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
    builder2.add(resource2, ResourceType.DRL); 
    kb.addKnowledgePackages(builder2.getKnowledgePackages()); 

    session = kb.newStatefulKnowledgeSession(); 
    fired = session.fireAllRules(); 
    Assert.assertEquals(2, fired); 
} 

:

package test; 
declare Item 
value : String 
end 
rule "insertion" 
when 
then 
    Item $item = new Item(); 
    $item.setValue("A"); 
    insert($item); 
    System.out.println("Object A inserted"); 
end 
rule "modification" 
when  
    $item: Item(value == "A") 
then 
    $item.setValue("B"); 
    update($item); 
    System.out.println("Object A -> B"); 
end 

재배치 DRL :

package test; 
declare Item 
    value : String 
end 
rule "modification" 
when  
    $item : Item(value == "A") 
then 
    $item.setValue("C"); 
    update($item); 
    System.out.println("Object A -> C"); 
end 

출력 :

Object A inserted 
Object A -> B 
--- redeploy --- 
Object A inserted 

누락 된 출력

Object A -> C 

우리는 병합하지 않는 이러한 유형의 처리 수있는 방법의 어떤 생각을 (당신이 보는대로 재배포 규칙이 실행되지 않았습니다)?

희망이 있으시길 바랍니다. 나는 단순한 정보를 얻기 위해 여기에 있습니다.

답변

1

버전 5.2부터 Drools는 유형 선언의 재배포를 지원하지 않습니다. 그 이유는 java에서 클래스는 classloader + 클래스로 식별되기 때문입니다. 타입 선언이 배포되면 클래스 로더가 새로 고쳐 져야 새로운 클래스 로더가 효과적으로 생성됩니다. 앞에서 언급했듯이 모든 기존 규칙은 이전 클래스 로더 + 클래스를 계속 기대하며 새 클래스 로더 + 클래스와 일치하지 않습니다.

그래서, 당신이 제안한 것은 당신이 hot-redeploy 규칙을 필요로한다면, 타입 선언을 별도의 DRL 파일에 유지하고 rules 파일 만 재배포하는 것입니다. 또는 새 규칙을 즉시 생성하거나 파일에서 변경된 규칙을 추출하여 다시 배포 만 할 수 있습니다.

+0

Edson에게 감사드립니다. 문제는 부분적으로 해결되었지만 완전히는 아닙니다. 나중에 문제가 해결 될 때 수정 된 코드를 공개하기 위해 다시 올게요. – ipingu