<div dir="ltr">Hey,<div>I recently upgraded drools from 5.5.0.Final to 6.0.0.CR3</div><div>A rule deletion that used to work now throws a NullPointerException.</div><div>A fact has to be inserted for the Exception to be thrown.</div>
<div>Here is the log :</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
[main] INFO org.drools.compiler.kie.builder.impl.KieRepositoryImpl - KieModule was added:MemoryKieModule[ ReleaseId=org.default:artifact:1.0.0-SNAPSHOT]<br>objectInserted org.test.ProximityTest$Track@2c6c5356<br>[Rule name=ProxRule, agendaGroup=MAIN, salience=0, no-loop=false]<br>
<span class="">Exception in thread "main" </span><span class="">java.lang.NullPointerException<br></span>at org.drools.core.phreak.AddRemoveRule.deletePeerLeftTuple(<span class="">AddRemoveRule.java:687</span>)<br>
at org.drools.core.phreak.AddRemoveRule.followPeer(<span class="">AddRemoveRule.java:659</span>)<br>at org.drools.core.phreak.AddRemoveRule.processLeftTuples(<span class="">AddRemoveRule.java:620</span>)<br>at org.drools.core.phreak.AddRemoveRule.flushStagedTuples(<span class="">AddRemoveRule.java:243</span>)<br>
at org.drools.core.phreak.AddRemoveRule.removeRule(<span class="">AddRemoveRule.java:134</span>)<br>at org.drools.core.reteoo.ReteooBuilder.removeRule(<span class="">ReteooBuilder.java:172</span>)<br>at org.drools.core.reteoo.ReteooRuleBase.removeRule(<span class="">ReteooRuleBase.java:1402</span>)<br>
at org.drools.core.reteoo.ReteooRuleBase.removeRule(<span class="">ReteooRuleBase.java:1393</span>)<br>at org.drools.core.reteoo.ReteooRuleBase.removeRule(<span class="">ReteooRuleBase.java:1371</span>)<br>at org.drools.core.impl.KnowledgeBaseImpl.removeRule(<span class="">KnowledgeBaseImpl.java:210</span>)<br>
at org.test.ProximityTest.CreateKieRuleOnTheFly(<span class="">ProximityTest.java:72</span>)<br>at org.test.ProximityTest.main(<span class="">ProximityTest.java:102</span>)</blockquote></div></blockquote><div><br></div><div>
Here is a code sample that reproduces the issue :</div><div><br></div><div><br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex" class="gmail_quote">
<div><blockquote><span class="">package</span> org.test;<br><span class="">import</span> java.util.ArrayList;<br><span class="">import</span> java.util.List;<br><span class="">import</span> org.kie.api.KieBase;<br><span class="">import</span> org.kie.api.KieServices;<br>
<span class="">import</span> org.kie.api.builder.KieBuilder;<br><span class="">import</span> org.kie.api.builder.KieFileSystem;<br><span class="">import</span> org.kie.api.builder.KieRepository;<br><span class="">import</span> org.kie.api.builder.Message.Level;<br>
<span class="">import</span> org.kie.api.definition.rule.Rule;<br><span class="">import</span> org.kie.api.event.rule.ObjectDeletedEvent;<br><span class="">import</span> org.kie.api.event.rule.ObjectInsertedEvent;<br><span class="">import</span> org.kie.api.event.rule.ObjectUpdatedEvent;<br>
<span class="">import</span> org.kie.api.event.rule.WorkingMemoryEventListener;<br><span class="">import</span> org.kie.api.runtime.KieContainer;<br><span class="">import</span> org.kie.api.runtime.KieSession;<br><span class="">public</span> <span class="">class</span> ProximityTest {<br>
<span class="">private</span> <span class="">void</span> CreateKieRuleOnTheFly() {<br>KieServices ks = KieServices.Factory.get();<br>KieRepository kr = ks.getRepository();<br>KieFileSystem kfs = ks.newKieFileSystem();<br>
// Can't understand why this does not work without the<br>// <span class="">src</span>/main/resources part<br><span class="">kfs.write(</span>"src/main/resources/org/test/rule.drl"<span class="">, getRule());<br>
</span>KieBuilder kb = ks.newKieBuilder(kfs);<br>kb.buildAll(); <br><span class="">if</span> (kb.getResults().hasMessages(Level.<span class="">ERROR</span>)) {<br><span class="">throw</span> <span class="">new</span> RuntimeException(<span class="">"Build Errors:\n"<br>
</span>+ kb.getResults().toString());<br>}<br>KieContainer kContainer = ks.newKieContainer(kr.getDefaultReleaseId());<br>KieSession kSession = kContainer.newKieSession();<br>kSession.addEventListener(<span class="">new</span> WorkingMemoryEventListener() {<br>
@Override<br><span class="">public</span> <span class="">void</span> objectUpdated(ObjectUpdatedEvent oue) {<br>System.<span class="">out</span>.println(<span class="">"objectUpdated "</span> + oue.getObject());<br>
}<br>@Override<br><span class="">public</span> <span class="">void</span> objectInserted(ObjectInsertedEvent oi) {<br>System.<span class="">out</span>.println(<span class="">"objectInserted "</span> + oi.getObject());<br>
}<br>@Override<br><span class="">public</span> <span class="">void</span> objectDeleted(ObjectDeletedEvent ore) {<br>System.<span class="">out</span>.println(<span class="">"objectRetracted "</span> + ore.getOldObject());<br>
}<br>});<br>// CloseTrack closeTrack = new CloseTrack(100,200);<br>Track track = <span class="">new</span> Track(100);<br>// track.getCloseTracks().add(closeTrack);<br>// kSession.insert(track);<br>// track = new Track(200);<br>
kSession.insert(track);<br>kSession.fireAllRules();<br>KieBase kieBase = kSession.getKieBase();<br>Rule rule = kieBase.getRule(<span class="">"org.test"</span>, <span class="">"ProxRule"</span>);<br>System.<span class="">out</span>.println(rule);<br>
kieBase.removeRule(<span class="">"org.test"</span>, <span class="">"ProxRule"</span>);<br>System.<span class="">out</span>.println(<span class="">"done"</span>);<br>}<br><span class="">private</span> <span class="">static</span> String getRule() {<br>
String s = <span class="">""<br></span><span class="">+ </span>"package org.test"<br><span class="">+ </span>"\nimport org.test.ProximityTest.*"<br><span class="">+ </span>"\nrule \"ProxRule\""<br>
<span class="">+ </span>"\nwhen "<br><span class="">+ </span>"\n<span class="">        </span>$track:Track("<br>+ <span class="">"\n<span class="">        </span>)"<br></span><span class="">+ </span>"\n<span class="">        </span>$track1:Track("<br>
+ <span class="">"\n<span class="">        </span>)"<br></span><span class="">+ </span>"\n<span class="">        </span><span class="">        </span>exists (CloseTrack(closeTrackId==$track1.trackId) from $track.closeTracks)"<br>
<span class="">+ </span>"\nthen "<span class=""> + </span>"\nSystem.out.println(\"proximity asserted\"); "<br>+ <span class="">"\nend"</span>;<br>return<span class=""> s;<br></span>}<br>
/** test main */<br><span class="">public</span> <span class="">static</span> <span class="">void</span> main(String[] args) {<br>(<span class="">new</span> ProximityTest()).CreateKieRuleOnTheFly();<br>}<br><span class="">public</span> <span class="">class</span> CloseTrack {<br>
private<span class=""> </span>int<span class=""> </span><span class="">trackId</span><span class="">;<br></span><span class="">private</span><span class=""> </span><span class="">int</span><span class=""> </span>closeTrackId<span class="">;</span><br>
<span class="">public</span> CloseTrack(<span class="">int</span> i, <span class="">int</span> j) {<br><span class="">this</span>.<span class="">trackId</span> = i;<br><span class="">this</span><span class="">.</span>closeTrackId<span class=""> = j;<br>
</span>}<br><span class="">public</span> <span class="">int</span> getTrackId() {<br><span class="">return</span><span class=""> </span>trackId<span class="">;<br></span>}<br><span class="">public</span> <span class="">void</span> setTrackId(<span class="">int</span> trackId) {<br>
<span class="">this</span>.<span class="">trackId</span> = trackId;<br>}<br><span class="">public</span> <span class="">int</span> getCloseTrackId() {<br><span class="">return</span><span class=""> </span>closeTrackId<span class="">;<br>
</span>}<br><span class="">public</span> <span class="">void</span> setCloseTrackId(<span class="">int</span> closeTrackId) {<br><span class="">this</span>.<span class="">closeTrackId</span> = closeTrackId;<br>}<br>}<br>public<span class=""> </span>class<span class=""> Track {</span><br>
private<span class=""> </span>int<span class=""> </span><span class="">trackId</span><span class="">;<br></span><span class="">private</span> List<CloseTrack> <span class="">closeTracks</span> = <span class="">new</span> ArrayList<CloseTrack>();<br>
<span class="">public</span> Track(<span class="">int</span> i) {<br><span class="">this</span>.<span class="">trackId</span> = i;<br>}<br><span class="">public</span> List<CloseTrack> getCloseTracks() {<br><span class="">return</span><span class=""> </span>closeTracks<span class="">;<br>
</span>}<br><span class="">public</span> <span class="">int</span> getTrackId() {<br><span class="">return</span><span class=""> </span>trackId<span class="">;<br></span>}<br><span class="">public</span> <span class="">void</span> setTrackId(<span class="">int</span> id) {<br>
<span class="">this</span>.<span class="">trackId</span> = id;<br>}<br><span class="">public</span> <span class="">void</span> setCloseTracks(List<CloseTrack> closeTracks) {<br><span class="">this</span>.<span class="">closeTracks</span> = closeTracks;<br>
}<br>}<br>}</blockquote></div></blockquote><div><br></div><div>Hope this helps.</div><div>Thanks.</div><div><div><br></div>-- <br>N.
</div></div>