[
https://jira.jboss.org/jira/browse/JBRULES-2377?page=com.atlassian.jira.p...
]
Macon Pegram commented on JBRULES-2377:
---------------------------------------
I have done further investigation in to this issue. I've traced the code in both
5.0.1 and 5.1M1 (where the issue is still present).
There's two factors at play which conspire to make DSL not work well with change sets.
Problem 1: DSL and the DSLR must be in the same folder. One of the primary values of the
KnowledgeAgent and Change-sets is hot deployment of rules. I can add or modify rules
without needing to bring down my system. To do this it's desirable to define the
change set as a set of directories as follows:
<resource source="classpath:com/dsl/" type="DSL" />
<resource source="classpath:com/dsl/" type="DSLR" />
Unfortunately only one of those Resource types gets applied to the files retrieved from
that directory, so the framework doesn't understand the contents of the DSL (or the
DSLR depending on your which resource type happens to win.. see next issue). It is
suggested in the documentation that type inference is planned, but not present.
Here's the comment from the Drools docs:
"It is also possible to specify a directory, to add the contents of that directory.
It is expected that all the files are of the specified type, since type is not yet
inferred from the file name extensions."
You can ALMOST (again see problem 2 below) solve the problem by explicitly listing
individual files to be loaded but then in you lose the advantage of being able to hot
deploy new rules.
Problem 2: org.drools.agent.impl.KnowledgeAgentImpl.rebuildResources() pulls resources to
be compiled into a new KnowledgeBuilder from a HashMap (Resources) via a loop over
resource.keySet(). Since it's a HashMap the ordering is indeterminate. What happens
in the attached test case is that the DSLR is placed into the KnowledgeBuilder before the
DSL and the Agent can't properly deal with the DSLR. It's sheer dumb luck whether
or not your DSL is loaded before you DSLR. This is the real crux of the issue which
necessitated this ticket.
Recommendation 1: Provide resource type detection based off file extension conventions.
The documentation suggests this is the desired direction, but frankly without it DSL is
not viable with changesets.
Recommendation 2: The current scheme for building KnowledgeBases within the KnowledgeAgent
places no priorities on files or file types. Any member of the changeset could be added
to the KnowledgeBase at pretty much any time. There should be higher and lower priority
processing of various resource types within the KnowledgeAgent processing to insure proper
compilation of the KnowledgeBase. This problem extends beyond just DSL. It is also not
possible to use the ".package" convention for the same reasons. I believe there
should be a hierarchy of importance that matches up with the needs of compilation of the
ruleset. This should probably place ".package" resources at the top, followed
by ".dsl" and then pretty much any other resource type could follow (there may
be some other hierarchical needs like .rf before .drl/dslr that I'm not as familiar
with). The KnowledgeAgent's "rebuildResources()" method should respect
this hierarchy and add resources to the KnowledgeBase in that order.
Problems with DSL / DSLR files when used with a KnowledgeAgent /
Change Sets
----------------------------------------------------------------------------
Key: JBRULES-2377
URL:
https://jira.jboss.org/jira/browse/JBRULES-2377
Project: Drools
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: drools-compiler, drools-compiler (expert), drools-compiler-DSL
Affects Versions: 5.0.1.FINAL
Environment: Windows XP, Mac OS X, JDK 1.5.0_12
Reporter: Macon Pegram
Assignee: Mark Proctor
Attachments: dsl-demo-cleaner.zip, dsl-demo.zip
I tried to address this on the Drools Mailing list but did not receive an answer. See:
Mailing list message threads: "[rules-users] DSL, DSLR and Changesets...",
"[rules-users] Can DSL / DSLR be loaded in a changeset?"
----
Are DSL and DSLR files supported by the KnowledgeAgent / Changeset code. Here's the
details of my test case:
I have a Changeset file I'm trying to load which looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<change-set
xmlns='http://drools.org/drools-5.0/change-set'
xmlns:xs='http://www.w3.org/2001/XMLSchema-instance' >
<add>
<resource source="classpath:com/test/general/" type="DSL"
/>
<resource source="classpath:com/test/general/" type="DSLR"
/>
</add>
</change-set>
There's a single DSL and a single DSLR file in this folder. I'm loading the
change set as follows:
KnowledgeAgent ka = KnowledgeAgentFactory.newKnowledgeAgent(agentName);
ka.applyChangeSet(ResourceFactory.newClassPathResource(agentName +
"-changeset.xml", getClass()));
When I run this code, the logger suggests the DSL and DSLR are being loaded and
compiled:
[2009:10:299 16:10:52:info] KnowledgAgent created, with configuration:
monitorChangeSetEvents=true scanResources=true scanDirectories=true
++ Constructing and applying changeSet: dsl-test
[2009:10:299 16:10:52:info] KnowledegAgent has started listening for ChangeSet
notifications
(null: 3, 68): cvc-elt.1: Cannot find the declaration of element 'change-set'.
[2009:10:299 16:10:317:info] KnowledgAgent applying ChangeSet
[2009:10:299 16:10:317:debug] KnowledgeAgent subscribing to directory=[ClassPathResource
path='com/test/general/']
[2009:10:299 16:10:317:debug] ResourceChangeNotification subscribing
listener=org.drools.agent.impl.KnowledgeAgentImpl@b9b618 to resource=[ClassPathResource
path='com/test/general/']
[2009:10:299 16:10:317:debug] ResourceChangeScanner subcribing
notifier=org.drools.io.impl.ResourceChangeNotifierImpl@61ec49 to
resource=[ClassPathResource path='com/test/general/']
[2009:10:299 16:10:317:debug] KnowledgeAgent subscribing to directory content
resource=[FileResource
file='C:\bea\user_projects\workspaces\alerts\rules-kb\test-kb\target\test-classes\com\test\general\test.dsl']
[2009:10:299 16:10:317:debug] ResourceChangeNotification subscribing
listener=org.drools.agent.impl.KnowledgeAgentImpl@b9b618 to resource=[FileResource
file='C:\bea\user_projects\workspaces\alerts\rules-kb\test-kb\target\test-classes\com\test\general\test.dsl']
[2009:10:299 16:10:317:debug] ResourceChangeScanner subcribing
notifier=org.drools.io.impl.ResourceChangeNotifierImpl@61ec49 to resource=[FileResource
file='C:\bea\user_projects\workspaces\alerts\rules-kb\test-kb\target\test-classes\com\test\general\test.dsl']
[2009:10:299 16:10:317:debug] KnowledgeAgent subscribing to directory content
resource=[FileResource
file='C:\bea\user_projects\workspaces\alerts\rules-kb\test-kb\target\test-classes\com\test\general\test-dsl.dslr']
[2009:10:299 16:10:317:debug] ResourceChangeNotification subscribing
listener=org.drools.agent.impl.KnowledgeAgentImpl@b9b618 to resource=[FileResource
file='C:\bea\user_projects\workspaces\alerts\rules-kb\test-kb\target\test-classes\com\test\general\test-dsl.dslr']
[2009:10:299 16:10:317:debug] ResourceChangeScanner subcribing
notifier=org.drools.io.impl.ResourceChangeNotifierImpl@61ec49 to resource=[FileResource
file='C:\bea\user_projects\workspaces\alerts\rules-kb\test-kb\target\test-classes\com\test\general\test-dsl.dslr']
[2009:10:299 16:10:317:debug] KnowledgeAgent subscribing to directory=[ClassPathResource
path='com/hmc/test/general/']
[2009:10:299 16:10:317:debug] ResourceChangeNotification subscribing
listener=org.drools.agent.impl.KnowledgeAgentImpl@b9b618 to resource=[ClassPathResource
path='com/hmc/test/general/']
[2009:10:299 16:10:317:debug] KnowledgeAgent ChangeSet requires KnowledgeBuilder
[2009:10:299 16:10:317:debug] KnowledgeAgent rebuilding KnowledgeBase using ChangeSet
[2009:10:299 16:10:317:debug] KnowledgeAgent building resource=[FileResource
file='C:\bea\user_projects\workspaces\alerts\rules-kb\test-kb\target\test-classes\com\test\general\test.dsl']
[2009:10:299 16:10:333:debug] KnowledgeAgent building resource=[FileResource
file='C:\bea\user_projects\workspaces\alerts\rules-kb\test-kb\target\test-classes\com\test\general\test-dsl.dslr']
[2009:10:299 16:10:333:info] KnowledgeAgent new KnowledgeBase now built and in use
However after load is completed I try to run the following code:
System.out.println("KB Info");
Collection<KnowledgePackage> pkgs =
ka.getKnowledgeBase().getKnowledgePackages();
for (KnowledgePackage kp : pkgs) {
for (Rule rule : kp.getRules()) {
System.out.println("Rule: " + rule.getName() + ", "
+ ule.getPackageName());
for (String attribs : rule.listMetaAttributes())
System.out.println("---- " + attribs);
}
}
}
I get NO output (except of course "KB Info").
If I initialize the knowledgebase like this:
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
.newKnowledgeBuilder();
kbuilder.add(ResourceFactory
.newClassPathResource("com/test/general/test.dsl"),
ResourceType.DSL);
kbuilder.add(ResourceFactory
.newClassPathResource("com/test/general/test-dsl.dslr"),
ResourceType.DSLR);
if (kbuilder.hasErrors()) {
throw new Exception(kbuilder.getErrors().toString());
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
}
... and run the same output code I get a list of the rules that were loaded.
Any clues why the different behavior?
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira