Fix Property mapping /authzRoles transformation script encountered exception javax.script.ScriptException: Script status is 8#181
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:
…files
## Summary
Replaces the two inline JavaScript transforms in
`openidm-zip/src/main/resources/samples/workflow/conf/sync.json` (mapping
`systemXmlfileAccounts_managedUser`, properties
`roles → authzRoles` and `→ roles`) with file-based scripts under
`samples/workflow/script/`.
## Motivation
The CI job `ui-smoke-tests (17, samples/workflow)` failed even though every
Playwright test passed (one was retried as flaky). The "Print openidm logs"
step found this in `openidm/logs/openidm0.log.0` and exited 1:
```
WARNING: Property mapping /authzRoles transformation script encountered exception
javax.script.ScriptException: Script status is 8
at org.forgerock.script.registry.ScriptRegistryImpl$LibraryRecord.invoke(ScriptRegistryImpl.java:507)
...
org.forgerock.openidm.sync.SynchronizationException:
Transformation script error : Script status is 8 for attribute '/authzRoles'
```
`8` is `CompilationHandler.STARTING` (`UNINSTALLED=1, INSTALLED=2,
RESOLVED=4, STARTING=8, ACTIVE=32`). `ScriptRegistryImpl#invoke`:
```java
if (null != target) return method.invoke(target, arguments);
else throw new ScriptException("Script status is " + status);
```
Inline scripts embedded directly in `sync.json` are compiled and registered
asynchronously when the mapping config is loaded. The first reconciliation
that runs immediately after boot can hit the script while it is still
transitioning `STARTING → ACTIVE` (`target == null`) and throw. The same
recon retried a few seconds later succeeds — exactly what we see in the
failed run logs.
File-based scripts are registered through the same path used by every other
OpenIDM sample (e.g. existing `correlationQuery.js`, `usecase/.../*.js`,
`sample5/getEffectiveAssignments.js`) and are guaranteed to be `ACTIVE` by
the time mappings run, so the race window does not exist.
## Changes
### `openidm-zip/src/main/resources/samples/workflow/script/rolesToAuthzRoles.js` (new)
Replaces the inline transform that turns the comma-separated XML `roles`
attribute into the array form expected by `managed/user.authzRoles`:
```js
source.split(',').map(function (r) {
return {'_ref' : (r.indexOf('openidm-') === 0
? 'repo/internal/role/'
: 'managed/role/') + r };
})
```
The file version adds `null/empty` guards, so a missing `<ri:roles/>` no
longer throws but yields `[]`.
### `openidm-zip/src/main/resources/samples/workflow/script/authzRolesToRoles.js` (new)
Replaces the inline transform that flattens `authzRoles` back into the
comma-separated XML `roles` value:
```js
openidm.query('managed/user/' + source._id + '/authzRoles',
{'_queryFilter': 'true'})
.result.map(function (r) { return r._ref.split('/').pop(); })
.join(',')
```
Adds defensive checks for `source` / `source._id` and an empty query result.
### `openidm-zip/src/main/resources/samples/workflow/conf/sync.json`
Two `"transform"` blocks updated:
```diff
- "transform" : {
- "type" : "text/javascript",
- "source" : "source.split(',').map(function (r) { ... })"
- },
+ "transform" : {
+ "type" : "text/javascript",
+ "file" : "script/rolesToAuthzRoles.js"
+ },
```
```diff
- "transform" : {
- "type" : "text/javascript",
- "source" : "openidm.query('managed/user/' + source._id + ...).result.map(...).join(',')"
- },
+ "transform" : {
+ "type" : "text/javascript",
+ "file" : "script/authzRolesToRoles.js"
+ },
```
No other changes to mappings, policies, properties or test data.
## Compatibility
- Same observable behaviour: same input → same output (plus graceful
handling of empty/null sources, which previously threw).
- Same mapping shape, same property names, no schema or config-format
changes.
- Sample assembly already packages
`samples/workflow/script/correlationQuery.js`; the two new files end up
in `samples/workflow/script/` of the distribution zip with no assembly
changes.
## Verification
- `python3 -m json.tool sync.json` — config still valid JSON.
- `mvn -pl openidm-zip package -DskipTests` — green.
- Built `openidm-*.zip` contains:
- `openidm/samples/workflow/script/rolesToAuthzRoles.js`
- `openidm/samples/workflow/script/authzRolesToRoles.js`
- updated `openidm/samples/workflow/conf/sync.json` referencing both files.
- Local run of `samples/workflow` reconciliations (Step 2 a-d of the README)
no longer logs `Script status is 8 for attribute '/authzRoles'`; the
strict CI log scan (`grep -E "ERROR|SEVERE|Exception|Throwable"` over
`openidm/logs/*`) is clean.
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.
samples/workflow: extract role-mapping transforms into
script/*.jsfilesSummary
Replaces the two inline JavaScript transforms in
openidm-zip/src/main/resources/samples/workflow/conf/sync.json(mappingsystemXmlfileAccounts_managedUser, propertiesroles → authzRolesand→ roles) with file-based scripts undersamples/workflow/script/.Motivation
The CI job
ui-smoke-tests (17, samples/workflow)failed even though everyPlaywright test passed (one was retried as flaky). The "Print openidm logs"
step found this in
openidm/logs/openidm0.log.0and exited 1:8isCompilationHandler.STARTING(UNINSTALLED=1, INSTALLED=2, RESOLVED=4, STARTING=8, ACTIVE=32).ScriptRegistryImpl#invoke:Inline scripts embedded directly in
sync.jsonare compiled and registeredasynchronously when the mapping config is loaded. The first reconciliation
that runs immediately after boot can hit the script while it is still
transitioning
STARTING → ACTIVE(target == null) and throw. The samerecon retried a few seconds later succeeds — exactly what we see in the
failed run logs.
File-based scripts are registered through the same path used by every other
OpenIDM sample (e.g. existing
correlationQuery.js,usecase/.../*.js,sample5/getEffectiveAssignments.js) and are guaranteed to beACTIVEbythe time mappings run, so the race window does not exist.
Changes
openidm-zip/src/main/resources/samples/workflow/script/rolesToAuthzRoles.js(new)Replaces the inline transform that turns the comma-separated XML
rolesattribute into the array form expected by
managed/user.authzRoles:The file version adds
null/emptyguards, so a missing<ri:roles/>nolonger throws but yields
[].openidm-zip/src/main/resources/samples/workflow/script/authzRolesToRoles.js(new)Replaces the inline transform that flattens
authzRolesback into thecomma-separated XML
rolesvalue:Adds defensive checks for
source/source._idand an empty query result.openidm-zip/src/main/resources/samples/workflow/conf/sync.jsonTwo
"transform"blocks updated:No other changes to mappings, policies, properties or test data.
Compatibility
handling of empty/null sources, which previously threw).
changes.
samples/workflow/script/correlationQuery.js; the two new files end upin
samples/workflow/script/of the distribution zip with no assemblychanges.
Verification
python3 -m json.tool sync.json— config still valid JSON.mvn -pl openidm-zip package -DskipTests— green.openidm-*.zipcontains:openidm/samples/workflow/script/rolesToAuthzRoles.jsopenidm/samples/workflow/script/authzRolesToRoles.jsopenidm/samples/workflow/conf/sync.jsonreferencing both files.samples/workflowreconciliations (Step 2 a-d of the README)no longer logs
Script status is 8 for attribute '/authzRoles'; thestrict CI log scan (
grep -E "ERROR|SEVERE|Exception|Throwable"overopenidm/logs/*) is clean.