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

Groovy Scripting Engine holds random webapp class loader when cached

    XMLWordPrintable

Details

    • Bug Report
    • Resolution: Fixed
    • L3 - Default
    • 7.4.0, 7.3.3, 7.2.7, 7.4.0-alpha2
    • None
    • engine
    • None

    Description

      Scenario:
      Shared process engine on Tomcat. Groovy-all is in the global lib folder.
      A process application is deployed with a Groovy script. The process is started and the Groovy script evaluated. Up to now, no Groovy engine has been created which is now done. The engine is cached in the process engine configuration. After undeployment of the web application that contains the mentioned process application, all other Groovy script evaluations fail with a NullPointerException.

      Reason:
      1. Our code calls the JSR223 method ScriptEngineManager#getEngineByName
      2. This makes an SPI lookup for ScriptEngineFactories that serve scripts for the desired language
      3. The GroovyScriptEngineFactory is found and the method GroovyScriptEngineFactory#getScriptEngine() is invoked to build a new engine
      4. GroovyScriptEngineFactory#getScriptEngine() calls new GroovyScriptEngineImpl() and the constructor uses the context class loader as the parent class loader of a newly created GroovyClassLoader
      5. If the first script invocation is within the context of a process application, the context class loader is the web application's classloader
      6. After undeployment of the web application, its classloader is in an undefined state (i.e. some resources are cleared).
      7. However, it is still referenced from the GroovyScriptEngine and trying to resolve a resource from this class loader fails with a NullPointerException. This happens on any following Groovy script execution.

      Solution ideas:

      • Script engines need to be cached at a Process Application Level (keep the note below in mind)
      • it seems impossible to pass a proper classloader to GroovyScriptEngineFactory because it is called via a JSR223-SPI method which interface we have no control over
      • Since GroovyScriptEngineFactory creates a new GroovyScriptEngine with every lookup, one solution could be to remove the script engine caching. The JSR223 docs state anyway, that a ScriptEngineFactory itself can cache engines if it likes. Perhaps these implementations know better than we do whether the engines can be cached.
      • Another option could be to initialize scripting engines when the process engine is created. However this requires that we know in advance which engines are used.

      Notes:

      • This has also an impact on the script compilation option since an instance of GroovyCompiledScript keeps a reference to the ScriptEngine it was created with. When the process definition is not removed from the deployment cache when the web application is removed (isDeleteUponUndeploy = false), this results in another memory leak

      related discussion: https://groups.google.com/forum/#!msg/camunda-bpm-users/SVyoYoWPcK0/X7wIFu3nWhgJ

      mgm-controller-panel

        This is the controller panel for Smart Panels app

        Attachments

          Issue Links

            Activity

              People

                thorben.lindhauer Thorben Lindhauer
                thorben.lindhauer Thorben Lindhauer
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:

                  Salesforce