This is an automated email from the ASF dual-hosted git repository.
radu pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly.git
The following commit(s) were added to refs/heads/master by this push:
new 80063be SLING-12755 - Break cyclic dependencies between the
SightlyScriptEngineFactory and the BundledUnitManagerImpl service
80063be is described below
commit 80063beb6428efb9533abbb2deb30d2dc9a94d00
Author: Radu Cotescu <[email protected]>
AuthorDate: Fri Apr 25 09:13:07 2025 +0200
SLING-12755 - Break cyclic dependencies between the
SightlyScriptEngineFactory and the BundledUnitManagerImpl service
* remove the ScriptEngineManager dependency from the UseProviders to avoid
cyclic dependencies
---
.../engine/extension/use/ScriptUseProvider.java | 58 +++++++++++++++++++---
.../engine/extension/use/UseRuntimeExtension.java | 4 +-
2 files changed, 54 insertions(+), 8 deletions(-)
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
index 5e63356..499276b 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
@@ -27,12 +27,14 @@ import javax.script.ScriptEngineManager;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScript;
import org.apache.sling.scripting.core.ScriptNameAwareReader;
+import org.apache.sling.scripting.sightly.SightlyException;
import
org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
import
org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
@@ -41,8 +43,13 @@ import
org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.scripting.sightly.use.ProviderOutcome;
import org.apache.sling.scripting.sightly.use.UseProvider;
import org.apache.sling.scripting.spi.bundle.BundledRenderUnit;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.slf4j.Logger;
@@ -73,14 +80,29 @@ public class ScriptUseProvider implements UseProvider {
private static final Logger log =
LoggerFactory.getLogger(ScriptUseProvider.class);
- @Reference
- private BundledUnitManagerImpl bundledUnitManager;
+ private final AtomicReference<ScriptEngineManager> engineManagerRef = new
AtomicReference<>();
+ private final BundleContext bundleContext;
+ private final BundledUnitManagerImpl bundledUnitManager;
+ protected final ScriptDependencyResolver scriptDependencyResolver;
- @Reference
- private ScriptEngineManager scriptEngineManager;
+ private ServiceReference<ScriptEngineManager>
scriptEngineManagerServiceReference;
- @Reference
- protected ScriptDependencyResolver scriptDependencyResolver;
+ @Activate
+ public ScriptUseProvider(
+ BundleContext bundleContext,
+ @Reference BundledUnitManagerImpl bundledUnitManager,
+ @Reference ScriptDependencyResolver scriptDependencyResolver) {
+ this.bundleContext = bundleContext;
+ this.bundledUnitManager = bundledUnitManager;
+ this.scriptDependencyResolver = scriptDependencyResolver;
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ if (scriptEngineManagerServiceReference != null) {
+ bundleContext.ungetService(scriptEngineManagerServiceReference);
+ }
+ }
@Override
public ProviderOutcome provide(String scriptName, RenderContext
renderContext, Bindings arguments) {
@@ -95,6 +117,10 @@ public class ScriptUseProvider implements UseProvider {
String scriptUrlAsString = script.toExternalForm();
bindings.remove(BundledRenderUnit.VARIABLE);
bindings.put(ScriptEngine.FILENAME, scriptUrlAsString);
+ ScriptEngineManager scriptEngineManager = getScriptEngineManager();
+ if (scriptEngineManager == null) {
+ return ProviderOutcome.failure(new SightlyException("Failed to
obtain a ScriptEngineManager."));
+ }
ScriptEngine scriptEngine =
scriptEngineManager.getEngineByExtension(extension);
if (scriptEngine != null) {
try (ScriptNameAwareReader reader = new ScriptNameAwareReader(
@@ -137,4 +163,24 @@ public class ScriptUseProvider implements UseProvider {
}
return extension;
}
+
+ @Nullable
+ private ScriptEngineManager getScriptEngineManager() {
+ ScriptEngineManager result = engineManagerRef.get();
+ if (result == null) {
+ ServiceReference<ScriptEngineManager> ref =
bundleContext.getServiceReference(ScriptEngineManager.class);
+ if (ref != null) {
+ ScriptEngineManager mgr = bundleContext.getService(ref);
+ if (mgr != null && engineManagerRef.compareAndSet(null, mgr)) {
+ this.scriptEngineManagerServiceReference = ref;
+ return mgr;
+ } else if (mgr != null) {
+ // Already initialized by another thread; unget this one
+ bundleContext.ungetService(ref);
+ }
+ }
+ return null;
+ }
+ return result;
+ }
}
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
index bdddc4e..5f0576a 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
@@ -49,7 +49,7 @@ import org.osgi.service.component.annotations.ReferencePolicy;
property = {RuntimeExtension.NAME + "=" + RuntimeExtension.USE})
public class UseRuntimeExtension implements RuntimeExtension {
- private final Map<ServiceReference, UseProvider> providersMap = new
ConcurrentSkipListMap<>();
+ private final Map<ServiceReference<UseProvider>, UseProvider> providersMap
= new ConcurrentSkipListMap<>();
@Override
public Object call(final RenderContext renderContext, Object... arguments)
{
@@ -87,7 +87,7 @@ public class UseRuntimeExtension implements RuntimeExtension {
providersMap.put(serviceReference, provider);
}
- private void unbindUseProvider(ServiceReference serviceReference) {
+ private void unbindUseProvider(ServiceReference<UseProvider>
serviceReference) {
providersMap.remove(serviceReference);
}
}