0 Replies Latest reply on Dec 17, 2009 1:39 PM by Ivan Kronkvist

    Possible bug in timer duedatetime

    Ivan Kronkvist Newbie

      I am trying to define a timer with and absolute time for the duedatetime property. Nothing exists in the documentation about how to specify this. I had to go into the jbpm-4.2,xsd to find out how to do it. There it's indicated that there is a default format for the date spcification. In practise it turned out to be wrong. Unless I specify a format in the configuration, I will get and exception. I included the pieces of code below to illustrate it.

       

        <element name="timer">
          <complexType>
            <sequence>
              <annotation><documentation>A list of event listeners that will
              be notified when the timer fires</documentation></annotation>
              <element name="description" minOccurs="0" type="string" />
              <group ref="tns:eventListenerGroup" minOccurs="0" maxOccurs="unbounded">
              </group>
            </sequence>
            <attribute name="duedate" type="string">
              <annotation><documentation>Timer duedate expression that defines the duedate of this
              timer relative to the creation time of the timer.  E.g. '2 hours' or '4 business days'
              </documentation></annotation>
            </attribute>
            <attribute name="repeat" type="string">
              <annotation><documentation>Timer duedate expression that defines repeated scheduling
              relative to the last timer fire event.  E.g. '2 hours' or '4 business days'
              </documentation></annotation>
            </attribute>
            <attribute name="duedatetime" type="string">
              <annotation><documentation>Absolute time in format <code>HH:mm dd/MM/yyyy</code>
              (see SimpleDateFormat).  The format for the absolute time can be customized in the
              jbpm configuration.
              </documentation></annotation>
            </attribute>
          </complexType>
        </element>

      I defined the following transition timer

       

       

      <transition g="9,-16" name="DoDayEnd" to="EndDay">

       

      <timer duedatetime="#{DaySwapEod}" />

       

      </transition>

       

      and got the following error

       

      org.jbpm.api.JbpmException: no 'jbpm.duedatetime.format' in current environment
      at org.jbpm.pvm.internal.env.EnvironmentImpl.getFromCurrent(EnvironmentImpl.java:226)
      at org.jbpm.pvm.internal.env.EnvironmentImpl.getFromCurrent(EnvironmentImpl.java:212)
      at org.jbpm.jpdl.internal.xml.JpdlParser.parseTimerDefinition(JpdlParser.java:371)
      at org.jbpm.jpdl.internal.xml.JpdlParser.parseTransitions(JpdlParser.java:482)
      at org.jbpm.jpdl.internal.xml.JpdlParser.parseActivities(JpdlParser.java:306)
      at org.jbpm.jpdl.internal.xml.JpdlParser.parseDocumentElement(JpdlParser.java:254)
      at org.jbpm.pvm.internal.xml.Parser.parseDocument(Parser.java:476)
      at org.jbpm.pvm.internal.xml.Parser.execute(Parser.java:396)
      at org.jbpm.pvm.internal.xml.Parse.execute(Parse.java:158)
      at org.jbpm.pvm.internal.repository.ProcessDeployer.deploy(ProcessDeployer.java:68)
      at org.jbpm.pvm.internal.repository.DeployerManager.deploy(DeployerManager.java:46)
      at org.jbpm.pvm.internal.repository.RepositorySessionImpl.deploy(RepositorySessionImpl.java:61)
      at org.jbpm.pvm.internal.cmd.DeployCmd.execute(DeployCmd.java:47)
      at org.jbpm.pvm.internal.cmd.DeployCmd.execute(DeployCmd.java:33)
      at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
      at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:54)
      at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
      at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
      at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:55)
      at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
      at org.jbpm.pvm.internal.repository.DeploymentImpl.deploy(DeploymentImpl.java:91)

      Accordign to the documentation I should not have to specify a duedatetime format. Looking into the code I verifyt hat shoudl be the case. I bolded the lines of code below that should allow execution to continue with a default format.

       

      public TimerDefinitionImpl parseTimerDefinition(Element timerElement, Parse parse, ScopeElementImpl scopeElement) {
          TimerDefinitionImpl timerDefinition = scopeElement.createTimerDefinition();

          String duedate = XmlUtil.attribute(timerElement, "duedate");
          String duedatetime = XmlUtil.attribute(timerElement, "duedatetime");

          if (duedate!=null) {
            timerDefinition.setDueDateDescription(duedate);
           
          } else if (duedatetime!=null) {
            String dueDateTimeFormatText = (String) EnvironmentImpl.getFromCurrent("jbpm.duedatetime.format");
            if (dueDateTimeFormatText==null) {
              dueDateTimeFormatText = "HH:mm dd/MM/yyyy";
            }
            SimpleDateFormat dateFormat = new SimpleDateFormat(dueDateTimeFormatText);
            try {
              Date duedatetimeDate = dateFormat.parse(duedatetime);
              timerDefinition.setDueDate(duedatetimeDate);
            } catch (ParseException e) {
              parse.addProblem("couldn't parse duedatetime "+duedatetime, e);
            }
          } else {
            parse.addProblem("either duedate or duedatetime is required in timer", timerElement);
          }
         
          String repeat = XmlUtil.attribute(timerElement, "repeat");
          timerDefinition.setRepeat(repeat);
         
          return timerDefinition;
        }

       

      However in the EnvironmentImpl.java, when calling getFromCurrent without specifying that the property should be optional, it defaults to required and this is where the exception comes from.

       

        public static Object getFromCurrent(String name) {
          return getFromCurrent(name, true);
        }

        public static Object getFromCurrent(String name, boolean required) {
          EnvironmentImpl environment = getCurrent();
          if (environment==null) {
            if (required) {
              throw new JbpmException("no environment to get '"+name+"'");
            }
            return null;
          }
          Object object = environment.get(name);
          if (object==null) {
            if (required) {
              throw new JbpmException("no '"+name+"' in current environment");
            }
            return null;
          }
          return object;
        }