I am doing something similar, and other than a memory leak (which I
have managed to track down and submit a patch for) it works pretty
well...
Try this... (Note that it would possibly be better to build a new
ReleaseId every time, but more complicated)
It has some code to clean up in case of errors, which seemed to be necessary.
private static final String DRL_PATH_PREFIX = "src/main/resources";
private KieServices ks = null;
private KieFileSystem kfs = null;
private KieContainer kc = null;
private KieBuilder kb = null;
private ReleaseId snashotReleaseId = null;
public boolean initRules(String commonDrl) {
ks = KieServices.Factory.get();
kfs = ks.newKieFileSystem();
kb = ks.newKieBuilder(kfs).buildAll();
snapshotReleaseId = ks.getRepository().getDefaultReleasId();
// This is a snapshot release id, so it is ok if it stays the same
kfs.generateAndWritePomXML(snapshotReleaseId);
kfs.write(String.format(%s/common.drl", DRL_PATH_PREFIX), commonDrl);
kb.buildAll();
kc = ks.newKieContainer(snapshotReleaseId);
if ( kb.getResults().hasMessages(
org.kie.api.builder.Message.Level.ERROR )) {
for( org.kie.api.builder.Message result :
kb.getResults().getMessages() ) {
System.err.println("DRL error " + message.getText() + "
in path: " + message.getPath() + " on line: " + message.getLine() + "
column: " + message.getColumn());
}
return false;
}
}
private String getRulePath(String uniqueRuleId) {
return String.format("%s/rule_%s.drl", DRL_PATH_PREFIX, uniqueRuleId);
}
private java.util.List<String> buildIncremental(String path) {
java.util.Set<String> paths = new java.util.HashSet<String>();
paths.add(path);
return buildIncremental(paths, true);
}
private java.util.Set<String>
buildIncremental(java.util.Collection<String> paths, boolean finish) {
String[] pathsArray = paths.toArray(new String[0]);
java.util.Set<String> failedPaths = new java.util.HashSet<String>();
IncrementalResults results =
((InternalKieBuilder)kBuilder).createFileSet(pathsArray).build();
List<Message> addedMessages = results.getAddedMessages();
for (Message message : addedMessages) {
if (Message.Level.ERROR == message.getLevel()) {
System.err.println("DRL error " + message.getText() +
" adding path: " + message.getPath() + " on line: " +
message.getLine() + " column: " + message.getColumn());
String failedPath = message.getPath();
if (!failedPath.startsWith(DRL_PATH_PREFIX)) {
failedPath = String.format("%s/%s",
DRL_PATH_PREFIX, failedPath);
}
failedPaths.add(failedPath);
if (finish) {
kfs.delete(failedPath);
}
}
}
if (finish && !failedPaths.isEmpty()) {
buildIncremental(paths, false);
}
List<Message> removedMessages = results.getRemovedMessages();
for (Message message : removedMessages) {
if (Message.Level.ERROR == message.getLevel()) {
System.err.println("DRL error " + message.getText() +
" removing path: " + message.getPath() + " on line: " +
message.getLine() + " column: " + message.getColumn());
String failedPath = message.getPath();
if (!failedPath.startsWith(DRL_PATH_PREFIX)) {
failedPath = String.format("%s/%s",
DRL_PATH_PREFIX, failedPath);
}
failedPaths.add(failedPath);
}
}
if (finish) {
kc.updateToVersion(snapshotReleaseId);
}
return failedPaths;
}
public boolean removeRule(String uniqueRuleId) {
String rulePath = getRulePath(uniqueRuleId);
kfs.delete(rulePath);
return buildIncremental(rulePath).isEmpty();
}
public boolean addRule(String uniqueRuleId, String rule){
if (ks == null) {
initRules();
}
String rulePath = getRulePath(uniqueRuleId);
kfs.write(rulePath, rule);
return buildIncremental(rulePath).isEmpty();
}
On Fri, Jun 6, 2014 at 4:12 AM, tia <rabarijaonadomoina(a)gmail.com> wrote:
Hello,
I'm trying to add a new rule on the fly like here:
https://github.com/droolsjbpm/drools/blob/master/drools-compiler/src/test...
Here is the method to add a rule, once the KieSession is created and
configured:
public void addRule(String rule){
KieServices ks= KieServices.Factory.get();
ReleaseId rid= ks.newReleaseId("org.kie",
"businessrules", "1.0");
KieFileSystem kfs = ks.newKieFileSystem();
kfs.generateAndWritePomXML(rid);
kfs.write("src/main/resources/rule.drl",rule);
KieBuilder kb = ks.newKieBuilder(kfs).buildAll();
if( kb.getResults().hasMessages( org.kie.api.builder.Message.Level.ERROR
)
) {
for( org.kie.api.builder.Message result :
kb.getResults().getMessages() )
{
System.err.println(result.getText());
}
}
InternalKieModule kieModule = (InternalKieModule) ks.getRepository()
.getKieModule(rid);
byte[] jar = kieModule.getBytes();
Resource jarRes = ks.getResources().newByteArrayResource(jar);
ks.getRepository().addKieModule(jarRes);
kieContainer.updateToVersion(rid);
}
But when I'm calling this method, I get the error below:
java.lang.NullPointerException
at org.drools.core.util.LinkedList.remove(LinkedList.java:168)
at
org.drools.core.phreak.AddRemoveRule.mergeSegment(AddRemoveRule.java:938)
at
org.drools.core.phreak.AddRemoveRule.correctSegmentOnSplitOnRemove(AddRemoveRule.java:377)
at org.drools.core.phreak.AddRemoveRule.removeRule(AddRemoveRule.java:182)
at
org.drools.core.reteoo.ReteooBuilder.removeTerminalNode(ReteooBuilder.java:171)
at org.drools.core.reteoo.ReteooBuilder.removeRule(ReteooBuilder.java:165)
at
org.drools.core.reteoo.ReteooRuleBase.removeRule(ReteooRuleBase.java:1406)
at
org.drools.core.reteoo.ReteooRuleBase.removeObjectsGeneratedFromResource(ReteooRuleBase.java:1652)
at
org.drools.compiler.compiler.PackageBuilder.removeObjectsGeneratedFromResource(PackageBuilder.java:3898)
at
org.drools.compiler.kie.builder.impl.KieContainerImpl.updateToVersion(KieContainerImpl.java:114)
For the line : "kieContainer.updateToVersion(rid);"
But if I'm firing the rules once (kieSession.fireAllRules();) before adding
the new rule, I don't get the exception O_o
Someone has any idea why ?
thanks!
--
View this message in context:
http://drools.46999.n3.nabble.com/NullPointerException-at-org-drools-comp...
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users