[BPMN] เมื่อ Timer Start Event ทำให้เกิดปัญหา duedate is null

หลังจากทำ Thesis มาเรื่อยๆ ผมได้มาลองใช้ Timer Start Event ของแบบจำลอง BPMN พอจะ Deploy เท่านั้นแหละ ?

ERROR org.camunda.bpm.engine.context - ENGINE-16004 Exception while closing command context: duedate is null
  org.camunda.bpm.engine.exception.NullValueException:duedate is null
   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_152]
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_152]
   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_152]
   at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_152]
   at org.camunda.bpm.engine.impl.util.EnsureUtil.generateException(EnsureUtil.java:344) ~[camunda-engine-7.8.0.jar:7.8.0]
   ....

พระเจ้า !!!! ทำไมทำร้ายเด็กน้อยอย่างฉันเช่นนี้

ผมติดปัญหานี้มาประมาณ 2 สัปดาห์ครับ

ระหว่างที่ทำก็ไล่ถาม Google ตรวจการกำหนด Config ไปเรื่อยๆ จนถึงเวลาแล้วทีผม ต้องเอา Stacktrace มาลองไล่ Code ของตัว BPMN Engine ใน GitHub ครับ ซึ่งพอไล่ๆไปแล้ว

  • abstract class JobDeclaration ผมสงสัย Method resolveDueDate เพราะ มัน Code ที่น่าสงสัยครับ Return null เฉย
  • หลังจากขุดไปเรื่อยๆ เจอ Ticket อันนึงครับ อันนี้ >> https://app.camunda.com/jira/browse/CAM-4135 โดยสิ่งที่ผมสงสัย คือ ตัว XML Config ครับ

พบสาเหตุแล้ว

  • หลังจากไล่ Code มานานเลย ผมสังเกตุว่าเวลาที่กำหนดในแบบจำลอง มันเป็นเวลาในอดีตครับ 2018-04-30 แต่ในเวลาปัจจุบัน คือ 2018-06-05 และพอไล่ไปดู Code อีก ซับซ้อนมากครับ แต่ใจความสำคัญ คือ ว่าวันที่กำหนดใน Timer Start Event เป็นวันที่ในอดีต เมื่อเทียบกับวันที่ของ BPMN Engine แล้ว มันจะไปกำหนดค่า jobExecutorAcquireByDueDate  ที่อยู่ใน Class  ProcessEngineConfiguration ให้มีค่าเป็น false ครับ
  • อ๋อ สรุปว่า Config XML ที่เจอ อาจจะยังไม่จำเป็นต้องใช้ [ผมของไปขุดเพิ่มเติมก่อน] แต่ตอนนี้ที่รู้แน่ๆ คือ ถ้า Code ถ้ามันตีความได้ว่า วันที่เราส่งไปในรูปแบบ ISO 8601 แล้วพบว่าเป็นวันในอดีต ระบบมัน Set Duedate เป็น null แทน
    • ถ้าในเครื่องจริง อาจจะต้องย้อนเวลาของ OS เอาครับ
    • แต่ถ้าทำพวก Unit Test สามารถใช้ตัว ClockUtil  ได้ครับ โดยจะเอาไว้ในส่วนของ @Before หรือ @BeforeClass ของ JUnit4 ก็ได้ครับ ตาม Code ตัวอย่าง ดังนี้
      @BeforeClass
      public static void setupClass() {
         DateTime current = new DateTime(2018, 03, 30, 12, 00, 00);
         ClockUtil.setCurrentTime(current.toDate());
         System.out.println(current.toString());
      }

มาลองดูผลลัพธ์กันครับ

  • สามารถทำงานได้แล้วครับ ^___^

Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts to your email.