Replace activiti-osgi OsgiScriptingEngines with stock Activiti ScriptingEngines#179
Merged
Merged
Conversation
Add org.apache.felix.prefs bundle to provide org.osgi.service.prefs package (including BackingStoreException class) at runtime, fixing: INFO: org.apache.felix.webconsole.internal.compendium.PreferencesConfigurationPrinter not enabled. Reason: Class org/osgi/service/prefs/BackingStoreException missing
…ax-web INFO logs
Select-String in PowerShell is case-insensitive by default, so the Windows smoke-test step was matching benign INFO records such as "ErrorServletComponent activate" / "Registered servlet at /error" against the ERROR|SEVERE|Exception|Throwable pattern and failing the build. The equivalent Unix step uses `grep -E`, which is case-sensitive, so the same lines pass on Linux/macOS. Add the -CaseSensitive flag to both Select-String invocations in the "Test on Windows" step of .github/workflows/build.yml so the check behaves identically across OSes.
…script ### Problem The `samples/workflow` end-to-end smoke job `ui-smoke-tests (… , /myidm, samples/workflow)` consistently fails on both Java 17 and Java 26 in [Build run #25805813364](https://github.com/OpenIdentityPlatform/OpenIDM/actions/runs/25805813364) while every other matrix combination is green: | context_path | sample | result | |--------------|---------------------|----------| | (default) | samples/workflow | ✅ pass | | /myidm | samples/getting-started | ✅ pass | | /myidm | (no sample) | ✅ pass | | **/myidm** | **samples/workflow**| ❌ fail | The job's final step (`Print openidm logs`) scans `openidm/logs/*` for `ERROR|SEVERE|Exception|Throwable` and exits 1 if anything matches. With `-Dopenidm.context.path=/myidm` the workflow sample's `Accept Notice` Groovy script task in `contractorOnboarding.bpmn20.xml` was calling a hard-coded REST URL: ```groovy "url": "https://localhost:" + identityServer.getProperty('openidm.port.https') + "/openidm/selfservice/reset?_action=submitRequirements"
…iptingEngines` ## Summary Removes the use of `org.activiti.osgi.OsgiScriptingEngines` from the OpenIDM workflow bundle and wires the stock `org.activiti.engine.impl.scripting.ScriptingEngines` with an explicitly registered Groovy `ScriptEngineFactory`. This eliminates noisy `ClassNotFoundException` warnings emitted during every script-task execution and makes the script-engine resolution deterministic under OSGi without touching the rest of `activiti-osgi` (BPMN auto-deployment via `ProcessEngineFactory` is preserved). ## Motivation `activiti-osgi` 5.15 ships `Extender$BundleScriptEngineResolver`, which is invoked by `OsgiScriptingEngines` for every script execution. Its implementation parses `META-INF/services/javax.script.ScriptEngineFactory` line by line and calls `Class.forName(...)` on each line **including `#`-prefixed comments**, producing a `ClassNotFoundException` warning per script-task invocation:
maximthomas
approved these changes
May 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes the use of
org.activiti.osgi.OsgiScriptingEnginesfrom the OpenIDMworkflow bundle and wires the stock
org.activiti.engine.impl.scripting.ScriptingEngineswith an explicitly registered Groovy
ScriptEngineFactory.This eliminates noisy
ClassNotFoundExceptionwarnings emitted during everyscript-task execution and makes the script-engine resolution deterministic
under OSGi without touching the rest of
activiti-osgi(BPMN auto-deploymentvia
ProcessEngineFactoryis preserved).Motivation
activiti-osgi5.15 shipsExtender$BundleScriptEngineResolver, which isinvoked by
OsgiScriptingEnginesfor every script execution. Its implementationparses
META-INF/services/javax.script.ScriptEngineFactoryline by line andcalls
Class.forName(...)on each line including#-prefixed comments,producing a
ClassNotFoundExceptionwarning per script-task invocation:These warnings pollute CI logs and trip the OpenIDM CI log-scan that fails the
build on
Exception/ERRORpatterns.activiti-osgi5.15 has been unmaintained since 2014; this change avoidsthat code path entirely instead of forking the Extender or filtering CI logs.
Changes
openidm-workflow-activiti/.../ActivitiServiceImpl.javaOsgiScriptingEngines:javax.script.ScriptEngine,org.activiti.osgi.Extender,org.activiti.osgi.OsgiScriptingEngines,org.osgi.framework.Bundle,org.osgi.framework.ServiceFactory,org.osgi.framework.ServiceRegistration.new OsgiScriptingEngines(...)with stocknew ScriptingEngines(ScriptEngineManager)configured with an explicitlyregistered
org.codehaus.groovy.jsr223.GroovyScriptEngineFactory.Extender.ScriptEngineResolverservicein
bindScriptRegistry— nothing invokes it anymore.org.activiti.osgi.blueprint.ProcessEngineFactory(used for BPMN/BARauto-deployment via
felix.fileinstall).Portions Copyright 2024-2026 3A Systems LLC..Why register Groovy explicitly under multiple names
ScriptEngineManagerdiscovers factories viaServiceLoaderusingthe thread-context classloader. Under OSGi the TCCL does not see the
groovy-allbundle, so auto-discovery fails and Activiti throwsCan't find scripting engine for 'groovy'.ScriptingEngines.addScriptEngineFactory(factory)registers onlyunder
factory.getEngineName(), which for Groovy returns"Groovy"(capital G).BPMN script tasks use
scriptFormat="groovy"(lowercase), and lookup iscase-sensitive — registration under the engine name alone is insufficient.
The fix builds a
ScriptEngineManager, registersGroovyScriptEngineFactoryunder the engine name, all
getNames()aliases (including the lowercase"groovy"), MIME types and extensions, then passes the fully populatedmanager to
new ScriptingEngines(mgr).ScriptBindingsFactoryis wired viathe setter (the two-arg constructor that accepts both does not exist in
Activiti 5.15).
Order of initialization
The scripting/resolver/variableType wiring lives after
processEngineFactory.init()— same as the original code.init()callsbuildProcessEngine(), which is what populatesgetVariableTypes()andgetResolverFactories(); calling them beforeinit()returnsnullandthrows
NullPointerExceptionduring activation.ScriptTaskActivityBehaviorreadsContext.getProcessEngineConfiguration().getScriptingEngines()on everyinvocation, so replacing the reference in the configuration after
init()takes effect immediately.
Compatibility
activiti-osgidependency is kept at 5.15 — only itsOsgiScriptingEnginesis no longer used.ProcessEngineFactoryfrom thesame artifact continues to handle blueprint / BAR auto-deployment.
groovy-all2.4.21).Risk
Low. Script execution path is now stock Activiti, and the explicit Groovy
factory registration avoids the OSGi-classloader pitfall that affected the
auto-discovery code path. The change is internal to
openidm-workflow-activiti.Verification
mvn -pl openidm-workflow-activiti -am install -DskipTests— green.openidm-zip, unpacked, started OpenIDM withsamples/workflow.scriptFormat="groovy") execute withoutCan't find scripting engine for 'groovy'.openidm0.log.0no longer containsCannot create ScriptEngineFactory: #warnings during workflow execution.
ui-smoke-testsworkflow scenarios pass without log-scan failures.