You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by en...@apache.org on 2022/06/28 19:00:42 UTC

[sling-org-apache-sling-scripting-core] branch master updated: SLING-11398 handle ScriptEngineFactory defined in a fragment (#18)

This is an automated email from the ASF dual-hosted git repository.

enorman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-core.git


The following commit(s) were added to refs/heads/master by this push:
     new ffa2e01  SLING-11398 handle ScriptEngineFactory defined in a fragment (#18)
ffa2e01 is described below

commit ffa2e01b22a3324a80fdd703efd8911e70856628
Author: Eric Norman <en...@apache.org>
AuthorDate: Tue Jun 28 12:00:37 2022 -0700

    SLING-11398 handle ScriptEngineFactory defined in a fragment (#18)
---
 .../core/impl/jsr223/SlingScriptEngineManager.java | 23 +++++-
 .../impl/jsr223/SlingScriptEngineManagerTest.java  | 14 ++--
 .../sling/scripting/core/it/SLING_11398IT.java     | 82 ++++++++++++++++++++++
 3 files changed, 110 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManager.java b/src/main/java/org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManager.java
index ac77167..63db942 100644
--- a/src/main/java/org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManager.java
+++ b/src/main/java/org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManager.java
@@ -110,7 +110,8 @@ public class SlingScriptEngineManager extends ScriptEngineManager implements Bun
 
     static final String EVENT_TOPIC_SCRIPT_MANAGER_UPDATED = "org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManager/UPDATED";
 
-    static final String ENGINE_FACTORY_SERVICE = "META-INF/services/" + ScriptEngineFactory.class.getName();
+    static final String META_INF_SERVICES = "META-INF/services";
+    static final String FACTORY_NAME = ScriptEngineFactory.class.getName();
 
     private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
 
@@ -247,7 +248,8 @@ public class SlingScriptEngineManager extends ScriptEngineManager implements Bun
     public void bundleChanged(BundleEvent event) {
         if (event.getType() == BundleEvent.STARTED
                 && event.getBundle().getBundleId() > 0
-                && event.getBundle().getEntry(ENGINE_FACTORY_SERVICE) != null) {
+                   // SLING-11398 - use findEntries instead of getEntry to support fragments
+                && event.getBundle().findEntries(META_INF_SERVICES, FACTORY_NAME, false) != null) {
             synchronized (this.engineSpiBundles) {
                 this.engineSpiBundles.add(event.getBundle());
             }
@@ -302,6 +304,23 @@ public class SlingScriptEngineManager extends ScriptEngineManager implements Bun
 
         this.bundleContext = bundleContext;
         bundleContext.addBundleListener(this);
+        registerInitialScriptEngineFactories();
+    }
+
+    /**
+     * Handles any spi bundles that were already started before we started listening
+     */
+    private void registerInitialScriptEngineFactories() {
+        Bundle[] bundles = this.bundleContext.getBundles();
+        for (Bundle bundle : bundles) {
+            if (bundle.getState() == Bundle.ACTIVE
+                    && bundle.getBundleId() > 0
+                    && bundle.findEntries(META_INF_SERVICES, FACTORY_NAME, false) != null) {
+                synchronized (this.engineSpiBundles) {
+                    this.engineSpiBundles.add(bundle);
+                }
+            }
+        }
         updateFactories();
     }
 
diff --git a/src/test/java/org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManagerTest.java b/src/test/java/org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManagerTest.java
index 3289267..761a114 100644
--- a/src/test/java/org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManagerTest.java
+++ b/src/test/java/org/apache/sling/scripting/core/impl/jsr223/SlingScriptEngineManagerTest.java
@@ -18,6 +18,12 @@
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 package org.apache.sling.scripting.core.impl.jsr223;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -49,12 +55,6 @@ import org.osgi.service.event.Event;
 import org.osgi.service.event.EventConstants;
 import org.osgi.service.event.EventHandler;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 public class SlingScriptEngineManagerTest {
 
     private static Class<?> SCRIPT_ENGINE_FACTORY = DummyScriptEngineFactory.class;
@@ -163,7 +163,7 @@ public class SlingScriptEngineManagerTest {
         when(bundle.adapt(BundleWiring.class)).thenReturn(wiring);
         when(wiring.getClassLoader()).thenReturn(loader);
 
-        when(bundle.getEntry(SlingScriptEngineManager.ENGINE_FACTORY_SERVICE)).thenReturn(url);
+        when(bundle.findEntries(SlingScriptEngineManager.META_INF_SERVICES, SlingScriptEngineManager.FACTORY_NAME, false)).thenReturn(Collections.enumeration(Collections.singleton(url)));
 
         BundleEvent bundleEvent = new BundleEvent(BundleEvent.STARTED, bundle);
         SlingScriptEngineManager slingScriptEngineManager = context.getService(SlingScriptEngineManager.class);
diff --git a/src/test/java/org/apache/sling/scripting/core/it/SLING_11398IT.java b/src/test/java/org/apache/sling/scripting/core/it/SLING_11398IT.java
new file mode 100644
index 0000000..09e891b
--- /dev/null
+++ b/src/test/java/org/apache/sling/scripting/core/it/SLING_11398IT.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.scripting.core.it;
+
+import static org.junit.Assert.assertNotNull;
+import static org.ops4j.pax.exam.CoreOptions.composite;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.vmOption;
+
+import javax.inject.Inject;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.options.ModifiableCompositeOption;
+import org.ops4j.pax.exam.options.extra.VMOption;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+/**
+ * Tests for SLING-11398 - verify serviceloader ScriptEngineFactory defined in a fragment bundle
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class SLING_11398IT extends ScriptingCoreTestSupport {
+
+    @Inject
+    private ScriptEngineManager scriptEngineManager;
+
+    @Configuration
+    public Option[] configuration() {
+        return options(
+            baseConfiguration(),
+            optionalRemoteDebug(),
+            mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy").version("3.0.9").startLevel(1),
+            // factory is defined in this fragment artifact – other versions of this bundle (e.g. 3.0.1) were 
+            //  released as regular bundle, not as fragment
+            mavenBundle().groupId("org.codehaus.groovy").artifactId("groovy-jsr223").version("3.0.9").noStart()
+        );
+    }
+
+    /**
+     * Optionally configure remote debugging on the port supplied by the "debugPort"
+     * system property.
+     */
+    protected ModifiableCompositeOption optionalRemoteDebug() {
+        VMOption option = null;
+        String property = System.getProperty("debugPort");
+        if (property != null) {
+            option = vmOption(String.format("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=%s", property));
+        }
+        return composite(option);
+    }
+
+    @Test
+    public void testGroovyScriptEngineAvailable() {
+        ScriptEngine engineByExtension = scriptEngineManager.getEngineByExtension("groovy");
+        assertNotNull(engineByExtension);
+    }
+
+}