Skip to content

Commit 11934f6

Browse files
authored
Replace activiti-osgi OsgiScriptingEngines with stock Activiti ScriptingEngines (#179)
1 parent 193f550 commit 11934f6

1 file changed

Lines changed: 49 additions & 31 deletions

File tree

openidm-workflow-activiti/src/main/java/org/forgerock/openidm/workflow/activiti/impl/ActivitiServiceImpl.java

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* information: "Portions copyright [year] [name of copyright owner]".
1313
*
1414
* Copyright 2012-2016 ForgeRock AS.
15-
* Portions Copyrighted 2024 3A Systems LLC.
15+
* Portions Copyrighted 2024-2026 3A Systems LLC.
1616
*/
1717
package org.forgerock.openidm.workflow.activiti.impl;
1818

@@ -34,7 +34,6 @@
3434
import java.util.Map;
3535
import java.util.concurrent.ConcurrentHashMap;
3636
import java.util.logging.Level;
37-
import javax.script.ScriptEngine;
3837
import javax.sql.DataSource;
3938
import javax.transaction.TransactionManager;
4039
import org.activiti.engine.ProcessEngine;
@@ -46,8 +45,6 @@
4645
import org.activiti.engine.impl.scripting.ResolverFactory;
4746
import org.activiti.engine.impl.scripting.ScriptBindingsFactory;
4847
import org.activiti.engine.impl.scripting.ScriptingEngines;
49-
import org.activiti.osgi.Extender;
50-
import org.activiti.osgi.OsgiScriptingEngines;
5148
import org.activiti.osgi.blueprint.ProcessEngineFactory;
5249
import org.forgerock.openidm.datasource.DataSourceService;
5350
import org.forgerock.openidm.router.IDMConnectionFactory;
@@ -77,10 +74,7 @@
7774
import org.forgerock.openidm.workflow.activiti.impl.session.OpenIDMSessionFactory;
7875
import org.forgerock.util.promise.Promise;
7976
import org.h2.jdbcx.JdbcDataSource;
80-
import org.osgi.framework.Bundle;
8177
import org.osgi.framework.Constants;
82-
import org.osgi.framework.ServiceFactory;
83-
import org.osgi.framework.ServiceRegistration;
8478
import org.osgi.service.cm.Configuration;
8579
import org.osgi.service.cm.ConfigurationAdmin;
8680
import org.osgi.service.component.ComponentContext;
@@ -320,12 +314,54 @@ void activate(ComponentContext compContext) {
320314
processEngineFactory.setBundle(compContext.getBundleContext().getBundle());
321315
processEngineFactory.init();
322316

317+
// Post-init wiring: variableTypes / resolverFactories / scriptingEngines
318+
// are populated by buildProcessEngine() inside init(), so they must be
319+
// mutated AFTER init(). ScriptTaskActivityBehavior reads
320+
// configuration.getScriptingEngines() on every script execution, so
321+
// replacing it here is effective.
323322
//ScriptResolverFactory
324323
List<ResolverFactory> resolverFactories = configuration.getResolverFactories();
324+
if (resolverFactories == null) {
325+
resolverFactories = new ArrayList<ResolverFactory>();
326+
}
325327
resolverFactories.add(new OpenIDMResolverFactory());
326328
configuration.setResolverFactories(resolverFactories);
327329
configuration.getVariableTypes().addType(new JsonValueType());
328-
configuration.setScriptingEngines(new OsgiScriptingEngines(new ScriptBindingsFactory(resolverFactories)));
330+
// Use the stock Activiti ScriptingEngines (which delegates to javax.script
331+
// ScriptEngineManager) instead of OsgiScriptingEngines. The latter routes
332+
// resolution through org.activiti.osgi.Extender, whose
333+
// BundleScriptEngineResolver naively parses
334+
// META-INF/services/javax.script.ScriptEngineFactory line by line and
335+
// attempts to Class.forName each '#'-comment line, producing a noisy
336+
// ClassNotFoundException WARNING for every script-task execution
337+
// (see activiti-osgi 5.15 Extender.java). The Groovy ScriptEngineFactory
338+
// is registered explicitly below because OSGi class loaders prevent the
339+
// JDK ServiceLoader inside ScriptEngineManager from discovering it in
340+
// the groovy-all bundle.
341+
ScriptingEngines scriptingEngines =
342+
new ScriptingEngines(new ScriptBindingsFactory(resolverFactories));
343+
// GroovyScriptEngineFactory.getEngineName() returns "Groovy" but
344+
// BPMN scriptFormat="groovy" looks up by lowercase language name.
345+
// ScriptingEngines.addScriptEngineFactory only registers under
346+
// getEngineName(); we additionally register all language/short names
347+
// (and mime types/extensions) directly on a pre-built ScriptEngineManager.
348+
javax.script.ScriptEngineFactory groovyFactory =
349+
new org.codehaus.groovy.jsr223.GroovyScriptEngineFactory();
350+
javax.script.ScriptEngineManager mgr = new javax.script.ScriptEngineManager();
351+
mgr.registerEngineName(groovyFactory.getEngineName(), groovyFactory);
352+
for (String name : groovyFactory.getNames()) {
353+
mgr.registerEngineName(name, groovyFactory);
354+
}
355+
for (String mime : groovyFactory.getMimeTypes()) {
356+
mgr.registerEngineMimeType(mime, groovyFactory);
357+
}
358+
for (String ext : groovyFactory.getExtensions()) {
359+
mgr.registerEngineExtension(ext, groovyFactory);
360+
}
361+
scriptingEngines = new ScriptingEngines(mgr);
362+
scriptingEngines.setScriptBindingsFactory(new ScriptBindingsFactory(resolverFactories));
363+
configuration.setScriptingEngines(scriptingEngines);
364+
329365

330366
//We are done!!
331367
processEngine = processEngineFactory.getObject();
@@ -477,29 +513,11 @@ protected void unbindProcessEngine(ProcessEngine processEngine) {
477513
target = "(service.pid=org.forgerock.openidm.script)")
478514
protected void bindScriptRegistry(ScriptRegistry scriptRegistry) {
479515
this.idmSessionFactory.setScriptRegistry(scriptRegistry);
480-
if (Extender.getBundleContext()!=null) {
481-
Extender.getBundleContext().registerService(Extender.ScriptEngineResolver.class, new ServiceFactory<Extender.ScriptEngineResolver>() {
482-
@Override
483-
public Extender.ScriptEngineResolver getService(Bundle bundle, ServiceRegistration<Extender.ScriptEngineResolver> serviceRegistration) {
484-
return new Extender.ScriptEngineResolver() {
485-
@Override
486-
public ScriptEngine resolveScriptEngine(String s) {
487-
if (!"groovy".equalsIgnoreCase(s)) {
488-
throw new RuntimeException("unknown resolveScriptEngine " + s);
489-
}
490-
return new org.codehaus.groovy.jsr223.GroovyScriptEngineImpl();
491-
}
492-
};
493-
}
494-
495-
;
496-
497-
@Override
498-
public void ungetService(Bundle bundle, ServiceRegistration<Extender.ScriptEngineResolver> serviceRegistration, Extender.ScriptEngineResolver scriptEngineResolver) {
499-
500-
}
501-
}, null);
502-
}
516+
// The previous registration of an Extender.ScriptEngineResolver OSGi service was
517+
// tied to OsgiScriptingEngines (now replaced by stock Activiti ScriptingEngines).
518+
// Without OsgiScriptingEngines nothing invokes Extender.resolveScriptEngine, so the
519+
// resolver service is no longer needed and the noisy
520+
// BundleScriptEngineResolver code path is no longer reached at script execution time.
503521
}
504522

505523
protected void unbindScriptRegistry(ScriptRegistry scriptRegistry) {

0 commit comments

Comments
 (0)