Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

[enter image description here][1]I am facing some issue in Drools I want to pass date as a date type but currently we don't have any method in JSONObject to handle dates .My JSONObject looks like this.

{"id":600,"city":"Gotham","age":25,"startDate":"29-DEC-2017","endDate":"2014-08-31"}
  

My Drool condition looks like this.

package com.rules
import org.drools.core.spi.KnowledgeHelper; 
import org.json.JSONObject;
rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop  
    $cdr : JSONObject( $cdr.optString("startDate") >= '28-Dec-2017') 
    $cdr.put("Action_1" , new JSONObject().put("actionName","Complex_Rule1_Action1").put("actionTypeName","SEND OFFER").put("channelName","SMS").put("messageTemplateName","SMSTemplate").put("@timestamp",(new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new java.util.Date())).put("ruleFileName","ComplexRule1.drl").put("ruleName","ComplexRule1"));

I am currently using .optString Because we dont have any methods like optString/optInt/optBoolean for date. So how can I handle date in Drools?

Any help will be appreciated.

Regards Puneet

My new DRL looks like this :

 package com.rules
import com.aravind.drools.SuperJSONObject;
import org.drools.core.spi.KnowledgeHelper; 
import org.json.JSONObject;
rule "Convert to SuperJSONObject"
    $cdr: JSONObject()      
    insert(new SuperJSONObject($cdr));      
rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop  
    $cdr : SuperJSONObject( $cdr.getAsDate("startDate") == '28-Dec-2017')   
    $cdr.getObject().put("Action_1" , new JSONObject().put("actionName","Complex_Rule1_Action1").put("actionTypeName","SEND OFFER").put("channelName","SMS").put("messageTemplateName","SMSTemplate").put("@timestamp",(new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new java.util.Date())).put("ruleFileName","ComplexRule1.drl").put("ruleName","ComplexRule1"));
  

Class look like this :

   import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.json.*;
public class SuperJSONObject {
    public final JSONObject obj;
    SimpleDateFormat sdfmt2= new SimpleDateFormat("yyyy/MM/dd"); 
    public SuperJSONObject(JSONObject obj){
        this.obj = obj;
    public Date getAsDate(String field) throws ParseException{
        return sdfmt2.parse(this.obj.optString(field));
    public JSONObject getObject(){
        return this.obj;
  

Another Class is like this

    import java.io.File
import java.io.FileReader
import org.drools.KnowledgeBase
import org.drools.KnowledgeBaseFactory
import org.drools.builder.KnowledgeBuilder
import org.drools.builder.KnowledgeBuilderFactory
import org.drools.builder.ResourceType
import org.drools.io.ResourceFactory
import org.drools.runtime.StatefulKnowledgeSession
import org.json.JSONObject
object RunStandAloneDrools {
  def main(args: Array[String]): Unit = {
    var jsonObjectArray: Array[JSONObject] = new Array(1)
    jsonObjectArray(0) = new JSONObject("{\"id\":600,\"city\":\"Gotham\",\"age\":25,\"startDate\":\"28-Dec-2017\",\"endDate\":\"2014-08-01\"}")
    var file: String = "/home/puneet/Downloads/ComplexRule1.drl"
    var kbuilder: KnowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder()
    kbuilder.add(ResourceFactory.newReaderResource(new FileReader(new File(file))), ResourceType.DRL)
   println("Errors? " + kbuilder.getErrors.size())
    var iter = kbuilder.getErrors.iterator()
    while(iter.hasNext()){
      println(iter.next().getMessage)
    var kbase: KnowledgeBase = KnowledgeBaseFactory.newKnowledgeBase()
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages)
    var session: StatefulKnowledgeSession = kbase.newStatefulKnowledgeSession()
    callRulesEngine(jsonObjectArray,session)
    println("Done")  
  def callRulesEngine(data: Array[JSONObject], knowledgeSession: StatefulKnowledgeSession): Unit = {
    data.map ( x => callRulesEngine(x,knowledgeSession) )
  def callRulesEngine(data: JSONObject, knowledgeSession: StatefulKnowledgeSession): Unit = {
    try {
      println("Input data " + data.toString())
      knowledgeSession.insert(data)
      knowledgeSession.fireAllRules()
      println("Facts details " + knowledgeSession.getFactCount)
      println("Enriched data " + data.toString())
    } catch {
      case (e: Exception) => println("Exception", e);
  

Output is not coming as per expectations

There are multiple ways to deal with this, but the fundamental thing is for you to understand that this is NOT a Drools issue at all. Your question is more on how do get a Date from a JSONObject.

One way this could be achieved is by using a function in Drools to make the conversion.

But I don't like functions, so I'll give you another, more elaborated, way to deal with this situation (and many others where a type conversion is required).

The idea is to create a wrapper class for your JSONObject- a SuperJSONObject- that will expose all the functionality you need. For the implementation of this class I will be using composition, but you can use inheritance (or a proxy) if you want.

public class SuperJSONObject {
    public final JSONObject obj;
    public SuperJSONObject(JSONObject obj){
        this.obj = obj;
    //expose all the methods from JSONObject you want/need
    public Date getAsDate(String field){
        return someDateParser.parse(this.obj.optString(field));
    public JSONObject getObject(){
        return this.obj;

So now we have a getAsDate() method that we can use in our rules. But we first need to convert a JSONObject into a SuperJSONObject before we can even use that method. You can do this in multiple ways and places. I'll be showing how to do it in DRL.

rule "Convert to SuperJSONObject"
    $jo: JSONObject() //you may want to filter which objects are converted by adding constraints to this pattern
    insert(new SuperJSONObject($jo));

And now we are good to go. We can now write a rule using this new class as follows:

rule "ComplexRule1"
salience 100
dialect "mvel"
date-effective "16-Jan-2018 00:00"
no-loop  
    $cdr : SuperJSONObject( getAsDate("startDate") >= '28-Dec-2017') 
    $cdr.getObject().put("Action_1" , ...);

After I have written all this code, I might reconsider the option of a simple function in DRL... :P

Hope it helps,

So, where are you converting from a JSONObject into a SuperJSONObject? In my answer, I was doing it in a rule. – Esteban Aliverti Feb 7, 2018 at 9:58

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.