Uploaded image for project: 'camunda BPM'
  1. camunda BPM
  2. CAM-14852

Script Task (using GraalJS) and request scoped Spring beans

XMLWordPrintable

    • Icon: Bug Report Bug Report
    • Resolution: Fixed
    • Icon: L3 - Default L3 - Default
    • 7.19.0
    • 7.16.0, 7.17.0
    • engine, spring-boot
    • None

      Environment (Required on creation):

      Spring Boot and Camunda Spring Boot Starter.

      Description (Required on creation; please attach any relevant screenshots, stacktraces, log files, etc. to the ticket):

      A process that has a Timer (or anything async) that ends up executing a Script Task with Javascript using GraalJS as part of the job, while having a Spring Bean that is request scoped, will throw the following exception:

      Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
          at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-5.3.18.jar:5.3.18]
          at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:42) ~[spring-web-5.3.18.jar:5.3.18]
          at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:371) ~[spring-beans-5.3.18.jar:5.3.18]
          ... 99 common frames omitted 
      
      

      As this is ran in a job that is being processed by Camunda, this thread is not web related, so any Request scoped beans won't be accessible.

      Steps to reproduce (Required on creation):

      1. Create a Spring Boot project with Camunda Spring Boot starter
      2. Add attached sample.bpmn 
      3. Create a random bean that has @RequestScope
      4. Start process instance and wait till timer picks up job, exception above will be thrown.

      Observed Behavior (Required on creation):

      The Camunda Spring Boot starter adds a SpringBeansResolverFactory which will add all beans in the application context as a context for all scripts to be used.

      When executing javascript with GraalJS, Camunda will eventually call evaluate() on the ScriptEngine, which in this case is GraalJS and passes along the ScriptBindings (Camunda implementation of Bindings) to GraalJSScriptEngine which will eventually call getOrCreateGraalJSBindings. This method basically moves the Camunda Script Bindings to an internal object of GraalJS, the way they do it is using putAll(). This putAll uses the entrySet() method, which is implemented on the Camunda's ScriptBindings which ends up calling calculateBindingMap() method.

      Now, if you have a process instance that ends up executing a Script Task as part of a Job (timer, async before, etc) AND have a Spring bean set with @RequestScope, it will throw the above mentioned exception. Which in this case is happening because of calculateBindingMap() is retrieving the value of all beans.

      Expected behavior (Required on creation):

      The SpringBeansResolverFactory should only include all beans that are of scope Singleton.

      Root Cause (Required on prioritization):

      The Root Cause for this is the SpringBeansResolverFactory, as its adding all beans regardless of scope to the bindings for the script engine.

      Solution Ideas (Optional):

      Hints (optional):

        This is the controller panel for Smart Panels app

          1. CAM-14852.tar
            37 kB
            Tassilo Weidner
          2. sample.bpmn
            3 kB
            Niels Leemburg

              tassilo.weidner Tassilo Weidner
              nleemburg Niels Leemburg
              Tassilo Weidner Tassilo Weidner
              Yana Vasileva Yana Vasileva
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: