[rules-users] NullPointerException at org.drools.compiler.kie.builder.impl.KieContainerImpl.updateToVersion

A. Craig West acraigwest at gmail.com
Tue Jun 10 12:23:09 EDT 2014


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 at 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/java/org/drools/compiler/integrationtests/IncrementalCompilationTest.java#L158
>
> 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-compiler-kie-builder-impl-KieContainerImpl-updateToVersion-tp4029894.html
> Sent from the Drools: User forum mailing list archive at Nabble.com.
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users


More information about the rules-users mailing list