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

pauls pushed a commit to branch issue/SLING-7134
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-core.git


The following commit(s) were added to refs/heads/issue/SLING-7134 by this push:
     new 7cdfdaf  Use serviceloader to load engine from bundles and use the 
systemclassloader to load default engines to make sure we get nashorn in java8.
7cdfdaf is described below

commit 7cdfdaf29a64e25e88acef8b4279986587c2d066
Author: Karl Pauls <[email protected]>
AuthorDate: Mon Dec 4 23:20:17 2017 +0100

    Use serviceloader to load engine from bundles and use the systemclassloader 
to load default engines to make sure we get nashorn in java8.
---
 .../core/impl/jsr223/SlingScriptEngineManager.java | 58 +++++++++++-----------
 .../impl/jsr223/SlingScriptEngineManagerTest.java  | 29 ++++++++---
 2 files changed, 51 insertions(+), 36 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 8c52960..6f1ece9 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
@@ -48,6 +48,7 @@ import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -84,7 +85,18 @@ public class SlingScriptEngineManager extends 
ScriptEngineManager implements Bun
     private final Map<ScriptEngineFactory, Map<String, Object>> 
factoriesProperties = new HashMap<>();
     private final Set<ServiceReference<ScriptEngineFactory>> serviceReferences 
= new HashSet<>();
 
-    private ScriptEngineManager internalManager = new 
ScriptEngineManager(SlingScriptEngineManager.class.getClassLoader());
+    private final ScriptEngineManager internalManager;
+    {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(null);
+            internalManager = new 
ScriptEngineManager(ClassLoader.getSystemClassLoader());
+        }
+        finally {
+            Thread.currentThread().setContextClassLoader(loader);
+        }
+    }
+
     private SortedSet<SortableScriptEngineFactory> factories = new TreeSet<>();
     private ComponentContext componentContext;
 
@@ -168,6 +180,7 @@ public class SlingScriptEngineManager extends 
ScriptEngineManager implements Bun
     @Override
     public void bundleChanged(BundleEvent event) {
         if (event.getType() == BundleEvent.STARTED
+                && event.getBundle().getBundleId() > 0
                 && event.getBundle().getEntry(ENGINE_FACTORY_SERVICE) != null) 
{
             synchronized (this.engineSpiBundles) {
                 this.engineSpiBundles.add(event.getBundle());
@@ -224,45 +237,30 @@ public class SlingScriptEngineManager extends 
ScriptEngineManager implements Bun
         readWriteLock.writeLock().lock();
         try {
             factories = new TreeSet<>();
-            internalManager = new 
ScriptEngineManager(SlingScriptEngineManager.class.getClassLoader());
             long fakeBundleIdCounter = Long.MIN_VALUE;
             // first add the platform factories
             for (ScriptEngineFactory factory : 
internalManager.getEngineFactories()) {
                 SortableScriptEngineFactory ssef = new 
SortableScriptEngineFactory(factory, fakeBundleIdCounter++, 0);
                 factories.add(ssef);
             }
-            // then factories from SPI Bundles
-            for (Bundle bundle : engineSpiBundles) {
-                URL url = bundle.getEntry(ENGINE_FACTORY_SERVICE);
-                InputStream ins = null;
-                try {
-                    ins = url.openStream();
-                    BufferedReader reader = new BufferedReader(new 
InputStreamReader(ins, StandardCharsets.UTF_8));
-                    String line;
-                    while ((line = reader.readLine()) != null) {
-                        if (!line.startsWith("#") && line.trim().length() > 0) 
{
-                            try {
-                                Class<ScriptEngineFactory> clazz = 
(Class<ScriptEngineFactory>) bundle.loadClass(line);
-                                SortableScriptEngineFactory ssef = new 
SortableScriptEngineFactory(clazz.getDeclaredConstructor()
-                                        .newInstance(), fakeBundleIdCounter++, 
0);
-                                factories.add(ssef);
-                            } catch (Throwable t) {
-                                LOG.error("Cannot register ScriptEngineFactory 
" + line, t);
-                            }
-                        }
-                    }
-                } catch (IOException ioe) {
-                    LOG.error("Unable to process bundle " + 
bundle.getSymbolicName(), ioe);
-                } finally {
-                    if (ins != null) {
-                        try {
-                            ins.close();
-                        } catch (IOException ioe) {
-                            LOG.error("Unable to release stream resource.", 
ioe);
+            ClassLoader loader = 
Thread.currentThread().getContextClassLoader();
+            try {
+                Thread.currentThread().setContextClassLoader(null);
+                // then factories from SPI Bundles
+                for (Bundle bundle : engineSpiBundles) {
+                    try {
+                        ScriptEngineManager manager = new 
ScriptEngineManager(bundle.adapt(BundleWiring.class).getClassLoader());
+                        for (ScriptEngineFactory factory : 
manager.getEngineFactories()) {
+                            factories.add(new 
SortableScriptEngineFactory(factory, fakeBundleIdCounter++, 0));
                         }
+                    } catch (Exception ex) {
+                        LOG.error("Unable to process bundle " + 
bundle.getSymbolicName(), ex);
                     }
                 }
             }
+            finally {
+                Thread.currentThread().setContextClassLoader(loader);
+            }
             // and finally factories registered as OSGi services
             if (componentContext != null) {
                 factoriesProperties.clear();
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 a6df3c4..33a46f4 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
@@ -22,10 +22,13 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URL;
+import java.security.SecureClassLoader;
 import java.util.Collections;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Vector;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -43,6 +46,7 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventConstants;
 import org.osgi.service.event.EventHandler;
@@ -127,15 +131,28 @@ public class SlingScriptEngineManagerTest {
 
     @Test
     public void testBundledScriptEngineFactory() throws Exception {
-        URL url = createFactoryFile().toURI().toURL();
+        final URL url = createFactoryFile().toURI().toURL();
         Bundle bundle = mock(Bundle.class);
-        
when(bundle.getEntry(SlingScriptEngineManager.ENGINE_FACTORY_SERVICE)).thenReturn(url);
-        when(bundle.loadClass(SCRIPT_ENGINE_FACTORY.getName())).thenAnswer(new 
Answer<Class>() {
+        BundleWiring wiring = mock(BundleWiring.class);
+        ClassLoader loader = new SecureClassLoader(){
+            @Override
+            protected Class<?> loadClass(String name, boolean resolve) throws 
ClassNotFoundException {
+                return name.equals(SCRIPT_ENGINE_FACTORY.getName()) ? 
SCRIPT_ENGINE_FACTORY : null;
+            }
+
             @Override
-            public Class answer(InvocationOnMock invocation) {
-                return SCRIPT_ENGINE_FACTORY;
+            public Enumeration<URL> getResources(String name) throws 
IOException {
+                Vector v = new Vector();
+                v.add(url);
+                return v.elements();
             }
-        });
+        };
+
+        when(bundle.getBundleId()).thenReturn(1L);
+        when(bundle.adapt(BundleWiring.class)).thenReturn(wiring);
+        when(wiring.getClassLoader()).thenReturn(loader);
+
+        
when(bundle.getEntry(SlingScriptEngineManager.ENGINE_FACTORY_SERVICE)).thenReturn(url);
 
         BundleEvent bundleEvent = new BundleEvent(BundleEvent.STARTED, bundle);
         SlingScriptEngineManager slingScriptEngineManager = 
context.getService(SlingScriptEngineManager.class);

-- 
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].

Reply via email to