Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ jobs:
openidm/startup.sh &
timeout 3m bash -c 'until grep -q "OpenIDM ready" openidm/logs/openidm0.log.0 ; do sleep 5; done' || cat openidm/logs/openidm0.log.0
grep -q "OpenIDM ready" openidm/logs/openidm0.log.0
! grep "ERROR" openidm/logs/openidm0.log.0
! grep "SEVERE" openidm/logs/openidm0.log.0
! grep -E "ERROR|SEVERE|Exception|Throwable" openidm/logs/openidm0.log.0
- name: Test on Windows
if: runner.os == 'Windows'
run: |
Expand All @@ -66,8 +65,11 @@ jobs:
Start-Sleep -s 180
type logs\openidm0.log.0
findstr "OpenIDM ready" logs\openidm0.log.0
type logs\openidm0.log.0 | find /c '"ERROR"' | findstr "0"
type logs\openidm0.log.0 | find /c '"SEVERE"' | findstr "0"
if (Select-String -Path logs\openidm0.log.0 -Pattern 'ERROR|SEVERE|Exception|Throwable' -CaseSensitive -Quiet) {
Write-Host "Errors or exceptions detected in openidm0.log.0"
Select-String -Path logs\openidm0.log.0 -Pattern 'ERROR|SEVERE|Exception|Throwable' -CaseSensitive
exit 1
}
- name: Upload failure artifacts
uses: actions/upload-artifact@v7
if: ${{ failure() }}
Expand Down Expand Up @@ -127,7 +129,7 @@ jobs:
run: |
OPTS=""
if [ -n "${{ matrix.context_path }}" ]; then
OPTS="-Dlogback.configurationFile=conf/logging-config.groovy -Dopenidm.context.path=${{ matrix.context_path }}"
OPTS="-Dopenidm.context.path=${{ matrix.context_path }}"
fi
ARGS=""
if [ -n "${{ matrix.samples }}" ]; then
Expand All @@ -136,8 +138,7 @@ jobs:
OPENIDM_OPTS="$OPTS" openidm/startup.sh $ARGS &
timeout 3m bash -c 'until grep -q "OpenIDM ready" openidm/logs/openidm0.log.0 ; do sleep 5; done' || cat openidm/logs/openidm0.log.0
grep -q "OpenIDM ready" openidm/logs/openidm0.log.0
! grep "ERROR" openidm/logs/openidm0.log.0
! grep "SEVERE" openidm/logs/openidm0.log.0
! grep -E "ERROR|SEVERE|Exception|Throwable" openidm/logs/openidm0.log.0
- name: UI Smoke Tests (Playwright)
run: |
cd e2e
Expand Down Expand Up @@ -170,7 +171,23 @@ jobs:
done
else
echo "openidm/logs directory not found"
exit 0
fi
echo "----- Checking logs for errors/exceptions -----"
status=0
while IFS= read -r f; do
if grep -E -n "ERROR|SEVERE|Exception|Throwable" "$f" > /tmp/log_errors.$$ 2>/dev/null; then
echo "Found errors/exceptions in $f:"
cat /tmp/log_errors.$$
status=1
fi
rm -f /tmp/log_errors.$$
done < <(find openidm/logs -type f)
if [ "$status" -ne 0 ]; then
echo "Errors or exceptions detected in openidm logs"
exit 1
fi
echo "No errors or exceptions detected in openidm logs"
build-docker:
runs-on: 'ubuntu-latest'
services:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ FROM eclipse-temurin:25-jre-jammy
LABEL org.opencontainers.image.authors="Open Identity Platform Community"

ENV USER="openidm"
ENV OPENIDM_OPTS="-server -XX:+UseContainerSupport --add-exports java.base/com.sun.jndi.ldap=ALL-UNNAMED -Dlogback.configurationFile=conf/logging-config.groovy"
ENV OPENIDM_OPTS="-server -XX:+UseContainerSupport --add-exports java.base/com.sun.jndi.ldap=ALL-UNNAMED"

ARG VERSION

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile-alpine
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ FROM alpine:latest
LABEL org.opencontainers.image.authors="Open Identity Platform Community"

ENV USER="openidm"
ENV OPENIDM_OPTS="-server -XX:+UseContainerSupport -Dlogback.configurationFile=conf/logging-config.groovy"
ENV OPENIDM_OPTS="-server -XX:+UseContainerSupport"

ARG VERSION

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* information: "Portions copyright [year] [name of copyright owner]".
*
* Copyright 2012-2016 ForgeRock AS.
* Portions Copyrighted 2024 3A Systems LLC.
* Portions Copyrighted 2024-2026 3A Systems LLC.
*/
package org.forgerock.openidm.workflow.activiti.impl;

Expand All @@ -34,7 +34,6 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import javax.script.ScriptEngine;
import javax.sql.DataSource;
import javax.transaction.TransactionManager;
import org.activiti.engine.ProcessEngine;
Expand All @@ -46,8 +45,6 @@
import org.activiti.engine.impl.scripting.ResolverFactory;
import org.activiti.engine.impl.scripting.ScriptBindingsFactory;
import org.activiti.engine.impl.scripting.ScriptingEngines;
import org.activiti.osgi.Extender;
import org.activiti.osgi.OsgiScriptingEngines;
import org.activiti.osgi.blueprint.ProcessEngineFactory;
import org.forgerock.openidm.datasource.DataSourceService;
import org.forgerock.openidm.router.IDMConnectionFactory;
Expand Down Expand Up @@ -77,10 +74,7 @@
import org.forgerock.openidm.workflow.activiti.impl.session.OpenIDMSessionFactory;
import org.forgerock.util.promise.Promise;
import org.h2.jdbcx.JdbcDataSource;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
Expand Down Expand Up @@ -320,12 +314,54 @@ void activate(ComponentContext compContext) {
processEngineFactory.setBundle(compContext.getBundleContext().getBundle());
processEngineFactory.init();

// Post-init wiring: variableTypes / resolverFactories / scriptingEngines
// are populated by buildProcessEngine() inside init(), so they must be
// mutated AFTER init(). ScriptTaskActivityBehavior reads
// configuration.getScriptingEngines() on every script execution, so
// replacing it here is effective.
//ScriptResolverFactory
List<ResolverFactory> resolverFactories = configuration.getResolverFactories();
if (resolverFactories == null) {
resolverFactories = new ArrayList<ResolverFactory>();
}
resolverFactories.add(new OpenIDMResolverFactory());
configuration.setResolverFactories(resolverFactories);
configuration.getVariableTypes().addType(new JsonValueType());
configuration.setScriptingEngines(new OsgiScriptingEngines(new ScriptBindingsFactory(resolverFactories)));
// Use the stock Activiti ScriptingEngines (which delegates to javax.script
// ScriptEngineManager) instead of OsgiScriptingEngines. The latter routes
// resolution through org.activiti.osgi.Extender, whose
// BundleScriptEngineResolver naively parses
// META-INF/services/javax.script.ScriptEngineFactory line by line and
// attempts to Class.forName each '#'-comment line, producing a noisy
// ClassNotFoundException WARNING for every script-task execution
// (see activiti-osgi 5.15 Extender.java). The Groovy ScriptEngineFactory
// is registered explicitly below because OSGi class loaders prevent the
// JDK ServiceLoader inside ScriptEngineManager from discovering it in
// the groovy-all bundle.
ScriptingEngines scriptingEngines =
new ScriptingEngines(new ScriptBindingsFactory(resolverFactories));
// GroovyScriptEngineFactory.getEngineName() returns "Groovy" but
// BPMN scriptFormat="groovy" looks up by lowercase language name.
// ScriptingEngines.addScriptEngineFactory only registers under
// getEngineName(); we additionally register all language/short names
// (and mime types/extensions) directly on a pre-built ScriptEngineManager.
javax.script.ScriptEngineFactory groovyFactory =
new org.codehaus.groovy.jsr223.GroovyScriptEngineFactory();
javax.script.ScriptEngineManager mgr = new javax.script.ScriptEngineManager();
mgr.registerEngineName(groovyFactory.getEngineName(), groovyFactory);
for (String name : groovyFactory.getNames()) {
mgr.registerEngineName(name, groovyFactory);
}
for (String mime : groovyFactory.getMimeTypes()) {
mgr.registerEngineMimeType(mime, groovyFactory);
}
for (String ext : groovyFactory.getExtensions()) {
mgr.registerEngineExtension(ext, groovyFactory);
}
scriptingEngines = new ScriptingEngines(mgr);
scriptingEngines.setScriptBindingsFactory(new ScriptBindingsFactory(resolverFactories));
configuration.setScriptingEngines(scriptingEngines);


//We are done!!
processEngine = processEngineFactory.getObject();
Expand Down Expand Up @@ -477,29 +513,11 @@ protected void unbindProcessEngine(ProcessEngine processEngine) {
target = "(service.pid=org.forgerock.openidm.script)")
protected void bindScriptRegistry(ScriptRegistry scriptRegistry) {
this.idmSessionFactory.setScriptRegistry(scriptRegistry);
if (Extender.getBundleContext()!=null) {
Extender.getBundleContext().registerService(Extender.ScriptEngineResolver.class, new ServiceFactory<Extender.ScriptEngineResolver>() {
@Override
public Extender.ScriptEngineResolver getService(Bundle bundle, ServiceRegistration<Extender.ScriptEngineResolver> serviceRegistration) {
return new Extender.ScriptEngineResolver() {
@Override
public ScriptEngine resolveScriptEngine(String s) {
if (!"groovy".equalsIgnoreCase(s)) {
throw new RuntimeException("unknown resolveScriptEngine " + s);
}
return new org.codehaus.groovy.jsr223.GroovyScriptEngineImpl();
}
};
}

;

@Override
public void ungetService(Bundle bundle, ServiceRegistration<Extender.ScriptEngineResolver> serviceRegistration, Extender.ScriptEngineResolver scriptEngineResolver) {

}
}, null);
}
// The previous registration of an Extender.ScriptEngineResolver OSGi service was
// tied to OsgiScriptingEngines (now replaced by stock Activiti ScriptingEngines).
// Without OsgiScriptingEngines nothing invokes Extender.resolveScriptEngine, so the
// resolver service is no longer needed and the noisy
// BundleScriptEngineResolver code path is no longer reached at script execution time.
}

protected void unbindScriptRegistry(ScriptRegistry scriptRegistry) {
Expand Down
7 changes: 5 additions & 2 deletions openidm-zip/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
~ your own identifying information:
~ "Portions Copyrighted [year] [name of copyright owner]"
~
~ Portions Copyrighted 2019-2025 3A Systems LLC.
~ Portions Copyrighted 2019-2026 3A Systems LLC.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
Expand Down Expand Up @@ -272,6 +272,10 @@
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.webconsole.plugins.packageadmin</artifactId>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.prefs</artifactId>
</dependency>
<dependency>
<groupId>org.apache.geronimo.bundles</groupId>
<artifactId>json</artifactId>
Expand Down Expand Up @@ -897,7 +901,6 @@
</activation>
<properties>
<openidm.options>
-Dlogback.configurationFile=conf/logging-config.groovy
</openidm.options>
</properties>
<dependencies>
Expand Down
2 changes: 1 addition & 1 deletion openidm-zip/src/main/resources/bin/install-service.bat
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ set OPENIDM_OPTS_SERVICE=%OPENIDM_OPTS: =;%
rem set SERVER_START_PARAMS="-c;bin/launcher.json"
set CP=bin/launcher.jar;bin/felix.jar
rem JAVA_OPTS_SERVICE will be fed to the prunmgr.exe which requires all semi-colon delimiters
set JAVA_OPTS_SERVICE=%OPENIDM_OPTS_SERVICE%;-Djava.util.logging.config.file=conf\logging.properties;-Dlogback.configurationFile=conf\logging-config.xml;
set JAVA_OPTS_SERVICE=%OPENIDM_OPTS_SERVICE%;-Djava.util.logging.config.file=conf\logging.properties;
rem Enable debugging uncomment the line below
rem set JAVA_OPTS_SERVICE=%JAVA_OPTS_SERVICE%;-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005;

Expand Down
3 changes: 3 additions & 0 deletions openidm-zip/src/main/resources/conf/logging.properties
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ org.identityconnectors.framework.impl.api.local.LocalConnectorInfoManagerImpl.le
# Suppress warnings of failed error page model validation
org.ops4j.pax.web.service.spi.model.elements.ErrorPageModel.level=SEVERE

# Suppress noisy INFO records from pax-web bundle (servlet/error-page registration)
org.ops4j.pax.web.level=WARNING

# OrientDB 3.x: suppress harmless WARNINGs that we cannot act on
# - OScriptManager logs "ECMAScript engine not found" when no JSR-223 javascript
# engine is on the classpath (we don't ship one and don't use OrientDB JS).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
information: "Portions Copyrighted [year] [name of copyright owner]".

Copyright (c) 2011-2015 ForgeRock AS. All rights reserved.
Portions Copyright 2026 3A Systems, LLC.
-->
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="Examples" id="definitions" xsi:schemaLocation=" http://www.omg.org/spec/BPMN/20100524/MODEL http://local.openicf.forgerock.org/BPMN20.xsd">
<process id="contractorOnboarding" name="Contractor onboarding process" isExecutable="true">
Expand Down Expand Up @@ -98,8 +99,12 @@

// Automatically send the user a password reset email
// Current limitation with supplying locale via http headers requires the call to be made via http
def openidmContextPath = identityServer.getProperty('openidm.context.path', '/openidm')
if (!openidmContextPath.startsWith('/')) {
openidmContextPath = '/' + openidmContextPath
}
openidm.action("external/rest", "call", [
"url": "https://localhost:"+identityServer.getProperty('openidm.port.https')+"/openidm/selfservice/reset?_action=submitRequirements",
"url": "https://localhost:"+identityServer.getProperty('openidm.port.https')+openidmContextPath+"/selfservice/reset?_action=submitRequirements",
"method": "POST",
"headers": [
"Content-Type": "application/json",
Expand Down
2 changes: 1 addition & 1 deletion openidm-zip/src/main/resources/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ PRGDIR=`dirname "$PRG"`
[ -z "$OPENIDM_PID_FILE" ] && OPENIDM_PID_FILE="$OPENIDM_HOME"/.openidm.pid

# Only set OPENIDM_OPTS if not already set
[ -z "$OPENIDM_OPTS" ] && OPENIDM_OPTS="-Dlogback.configurationFile=conf/logging-config.groovy"
[ -z "$OPENIDM_OPTS" ] && OPENIDM_OPTS=""

# Set JDK Logger config file if it is present and an override has not been issued
PROJECT_HOME=$OPENIDM_HOME
Expand Down
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,11 @@
<artifactId>org.apache.felix.webconsole.plugins.packageadmin</artifactId>
<version>${felix.webconsole.packageadmin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.prefs</artifactId>
<version>1.1.0</version>
</dependency>

<dependency>
<groupId>org.apache.felix</groupId>
Expand Down
Loading