2 Replies Latest reply on Jul 7, 2013 5:04 PM by marcos.sousa

    Custom JuelScriptEngine

    marcos.sousa

      This is a prodution problem.

       

      We copy paste the orginal JuelScriptEngine from jBPM, so we can create new functions.

       

      We are getting issues in productions using decisions.

       

      To reproduce the issue we create 2 threads  invoking startProcessInstante (after task we put decision) then we see what was happen in the code, surprised we found:

      1. jBPM creates for those 2 threads our JuelExtendedScriptEngine

      2. The ELContext creates 1 new JuelExtendedScriptEngine and use this for those 2 threads - Why? How can I put ELContext to reuse the JuelExtendedScriptEngine created by jBPM?

       

      I see that inside the JuelExtendedScriptEngine every value fits ok. But the evaluation of our new function instead of use the JuelExtendedScriptEngine previous created by jBPM it uses that one created by ELContext.

       

      Remember that the code is the same as the original jBPM 4.3 JuelScriptEngine.

        • 1. Re: Custom JuelScriptEngine
          marcos.sousa

          Looks like theres is an bug somewhere or in jBPM or in JUEL!

           

          My debug trace:

           

          My function getEqual when called uses the ScriptContext from the last call instead of self ScriptContext:

          > 07-Jul-2013 17:22:57:765 [pool-1-thread-1] getEqual ScriptContext: javax.script.SimpleScriptContext@15ab821

          ...

          > 07-Jul-2013 17:22:57:843 [pool-1-thread-2] getEqual ScriptContext: javax.script.SimpleScriptContext@15ab821

           

          Interresting is that only and the only place where things fails is while calling my custom function. Looks for example the end of eval function of ScriptEngine show the right ScriptContext.

           

          07-Jul-2013 17:22:57:656 [pool-1-thread-1] factory: com.xpt.appname.bpm.script.Juel4AppnameScriptEngineFactory@1c4120e

          07-Jul-2013 17:22:57:656 [pool-1-thread-1] Juel4AppnameScriptEngine: com.xpt.appname.bpm.script.Juel4AppnameScriptEngine@17d5b2a

          07-Jul-2013 17:22:57:671 [pool-1-thread-1] Juel4AppnameScriptEngineFactory getScriptEngine com.xpt.appname.bpm.script.Juel4AppnameScriptEngine@17d5b2a

          07-Jul-2013 17:22:57:671 [pool-1-thread-1] INI eval ScriptContext javax.script.SimpleScriptContext@e47e99

          07-Jul-2013 17:22:57:687 [pool-1-thread-2] factory: com.xpt.appname.bpm.script.Juel4AppnameScriptEngineFactory@1c4120e

          07-Jul-2013 17:22:57:687 [pool-1-thread-2] Juel4AppnameScriptEngine: com.xpt.appname.bpm.script.Juel4AppnameScriptEngine@cc5c6c

          07-Jul-2013 17:22:57:687 [pool-1-thread-2] Juel4AppnameScriptEngineFactory getScriptEngine com.xpt.appname.bpm.script.Juel4AppnameScriptEngine@cc5c6c

          07-Jul-2013 17:22:57:687 [pool-1-thread-2] INI eval ScriptContext javax.script.SimpleScriptContext@15ab821

          07-Jul-2013 17:22:57:734 [pool-1-thread-1] toELContext ERRADO   elContext com.xpt.appname.bpm.script.Juel4AppnameScriptEngine$1@1868b72

          07-Jul-2013 17:22:57:734 [pool-1-thread-1] toELContext CORRECTO elContext com.xpt.appname.bpm.script.Juel4AppnameScriptEngine@17d5b2a

          07-Jul-2013 17:22:57:750 [pool-1-thread-2] toELContext ERRADO   elContext com.xpt.appname.bpm.script.Juel4AppnameScriptEngine$1@12bc418

          07-Jul-2013 17:22:57:750 [pool-1-thread-2] toELContext CORRECTO elContext com.xpt.appname.bpm.script.Juel4AppnameScriptEngine@cc5c6c

          07-Jul-2013 17:22:57:765 [pool-1-thread-1] getEqual ScriptContext: javax.script.SimpleScriptContext@15ab821

          07-Jul-2013 17:22:57:843 [pool-1-thread-1] END eval ScriptContext javax.script.SimpleScriptContext@e47e99

          07-Jul-2013 17:22:57:843 [pool-1-thread-2] getEqual ScriptContext: javax.script.SimpleScriptContext@15ab821

          07-Jul-2013 17:22:57:859 [pool-1-thread-2] END eval ScriptContext javax.script.SimpleScriptContext@15ab821

          07-Jul-2013 17:22:57:921 [pool-1-thread-1] [k = 0] [VALIDO] Instância [process-decision.95980007] [Definir Titulares] [Definir Cliente - CORRECTO] org.jbpm.pvm.internal.svc.ExecutionServiceImpl@1a95cf6

          07-Jul-2013 17:22:57:921 [pool-1-thread-2] [k = 1] [INVALIDO] Instância [process-decision.95980008] [Definir Titulares] [Definir Titulares - CORRECTO] org.jbpm.pvm.internal.svc.ExecutionServiceImpl@1a95cf6

           

          My getEqual function is:

              @Juel4AppnameFunction(name = "equal", prefix = "appname")

              public static boolean getEqual(final ScriptContext x, final String expression, final double right, final String errorKey) throws XPathExpressionException {

                  LOG.info("getEqual ScriptContext: " + x);

           

                  Document xmlObject = (Document) x.getAttribute(ProcessVariables.XML_OBJECT.getKeyName());

              }

           

          At the jpdl I have:

          ...

              <decision g="180,95,48,48" name="Validar Numero de Titulares">

                  <transition g="-75,-17" name="Numero de Titulares Valido" to="Definir Cliente">

                      <condition expr="#{appname:equal(context, &quot;count(context/primeiroTitular[classEntidade=&apos;P&apos;])&quot;, 1, &apos;bpm.0034&apos;)}" lang="juel4appname"/>

                  </transition>

                  <transition g="3,-11" name="Numero de Titulares Invalido" to="Definir Titulares"/>

              </decision>

          ...

           

          The question is who passes context (wrong) to my function?

          • 2. Re: Custom JuelScriptEngine
            marcos.sousa

            An way that looked to fit to me is:

            public ScriptEngine getScriptEngine() {

                    if (queue.isEmpty()) {

                        ScriptEngine scriptEngine = new Juel4AppnameScriptEngine(this);

             

                        try {

                            queue.put(scriptEngine);

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

             

                        return scriptEngine;

                    } else {

                        while (!queue.isEmpty()) {

                            try {

                                Thread.sleep(1 * 100L);

                            } catch (Exception e) {

                                e.printStackTrace();

                            }

                        }

             

                        ScriptEngine scriptEngine = new Juel4AppnameScriptEngine(this);

             

                        try {

                            queue.put(scriptEngine);

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

             

                        return scriptEngine;

                    }

                }

             

            Then in Juel4AppnameScriptEngine I use "Juel4ImpressionScriptEngineFactory.queue.poll();" before return eval method.