You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by pa...@apache.org on 2019/05/07 15:22:01 UTC

[sling-org-apache-sling-feature-launcher] branch master updated (c5de9e4 -> b957b3e)

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

pauls pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git.


    from c5de9e4  SLING-8386: Make the Launcher implementation and framework artefact configurable and update to felix 6.0.3 as default
     new 080ce22  Make timeout work with framework start
     new b957b3e  SLING-8406: Allow the app class path of the feature launcher to be extended by URLs and allow the launcher extension to provide a classloader implementation

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../sling/feature/launcher/impl/Bootstrap.java     | 88 ++++++----------------
 .../launcher/impl/ExtensionContextImpl.java        |  6 ++
 .../sling/feature/launcher/impl/Installation.java  |  7 +-
 .../launcher/impl/launchers/AbstractRunner.java    | 39 ++++++----
 .../launcher/impl/launchers/FrameworkRunner.java   |  1 +
 .../sling/feature/launcher/spi/Launcher.java       | 58 ++++++++++++++
 .../launcher/spi/LauncherPrepareContext.java       |  3 +
 7 files changed, 122 insertions(+), 80 deletions(-)


[sling-org-apache-sling-feature-launcher] 02/02: SLING-8406: Allow the app class path of the feature launcher to be extended by URLs and allow the launcher extension to provide a classloader implementation

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pauls pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git

commit b957b3eccf312c209e9c8c00ace726d413a2088e
Author: Karl Pauls <ka...@gmail.com>
AuthorDate: Tue May 7 17:21:52 2019 +0200

    SLING-8406: Allow the app class path of the feature launcher to be extended by URLs and allow the launcher extension to provide a classloader implementation
---
 .../sling/feature/launcher/impl/Bootstrap.java     | 88 ++++++----------------
 .../launcher/impl/ExtensionContextImpl.java        |  6 ++
 .../sling/feature/launcher/impl/Installation.java  |  7 +-
 .../launcher/impl/launchers/FrameworkRunner.java   |  1 +
 .../sling/feature/launcher/spi/Launcher.java       | 58 ++++++++++++++
 .../launcher/spi/LauncherPrepareContext.java       |  3 +
 6 files changed, 96 insertions(+), 67 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java b/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java
index 400860b..d950a6b 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java
@@ -19,8 +19,8 @@ package org.apache.sling.feature.launcher.impl;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.net.URL;
-import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -34,7 +34,6 @@ import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.io.file.ArtifactHandler;
 import org.apache.sling.feature.io.file.ArtifactManager;
 import org.apache.sling.feature.io.json.FeatureJSONWriter;
-import org.apache.sling.feature.launcher.impl.launchers.FrameworkLauncher;
 import org.apache.sling.feature.launcher.spi.Launcher;
 import org.apache.sling.feature.launcher.spi.LauncherPrepareContext;
 import org.osgi.framework.FrameworkEvent;
@@ -135,22 +134,30 @@ public class Bootstrap {
                 this.logger.info("");
                 this.logger.info("Assembling launcher...");
 
-                final LauncherPrepareContext ctx = new LauncherPrepareContext()
-                {
+                final LauncherPrepareContext ctx = new LauncherPrepareContext() {
                     @Override
                     public Logger getLogger() {
                         return logger;
                     }
 
                     @Override
-                    public File getArtifactFile(final ArtifactId artifact) throws IOException
-                    {
+                    public File getArtifactFile(final ArtifactId artifact) throws IOException {
                         final ArtifactHandler handler = artifactManager.getArtifactHandler(":" + artifact.toMvnPath());
                         return handler.getFile();
                     }
 
                     @Override
-                    public void addAppJar(final File jar)
+                    public void addAppJar(final File jar) {
+                        try {
+                            config.getInstallation().addAppJar(jar.toURI().toURL());
+                        }
+                        catch (MalformedURLException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+
+                    @Override
+                    public void addAppJar(final URL jar)
                     {
                         config.getInstallation().addAppJar(jar);
                     }
@@ -265,7 +272,7 @@ public class Bootstrap {
             installation.getFrameworkProperties().put(START_LEVEL_PROP, "30");
         }
 
-        while (launcher.run(installation, createClassLoader(installation, launcher.getClass().getProtectionDomain().getCodeSource().getLocation())) == FrameworkEvent.STOPPED_SYSTEM_REFRESHED) {
+        while (launcher.run(installation, createClassLoader(installation, launcher)) == FrameworkEvent.STOPPED_SYSTEM_REFRESHED) {
             this.logger.info("Framework restart due to extension refresh");
         }
     }
@@ -276,23 +283,16 @@ public class Bootstrap {
      * @return The classloader.
      * @throws Exception If anything goes wrong
      */
-    public ClassLoader createClassLoader(final Installation installation, URL... extra) throws Exception {
+    public ClassLoader createClassLoader(final Installation installation, Launcher launcher) throws Exception {
         final List<URL> list = new ArrayList<>();
-        for(final File f : installation.getAppJars()) {
-            try {
-                list.add(f.toURI().toURL());
-            } catch (IOException e) {
-                // ignore
-            }
-        }
+
+        list.addAll(installation.getAppJars());
 
         list.add(Bootstrap.class.getProtectionDomain().getCodeSource().getLocation());
 
-        if (extra != null) {
-            for (URL url : extra) {
-                list.add(url);
-            }
-        }
+
+        // create a paranoid class loader, loading from parent last
+        final Launcher.LauncherClassLoader cl = launcher.createClassLoader();
 
         final URL[] urls = list.toArray(new URL[list.size()]);
 
@@ -302,49 +302,9 @@ public class Bootstrap {
                 this.logger.debug(" - {}", urls[i]);
             }
         }
-
-        // create a paranoid class loader, loading from parent last
-        final ClassLoader cl = new URLClassLoader(urls) {
-            @Override
-            public final Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-                // First check if it's already loaded
-                Class<?> clazz = findLoadedClass(name);
-
-                if (clazz == null) {
-
-                    try {
-                        clazz = findClass(name);
-                    } catch (ClassNotFoundException cnfe) {
-                        ClassLoader parent = getParent();
-                        if (parent != null) {
-                            // Ask to parent ClassLoader (can also throw a CNFE).
-                            clazz = parent.loadClass(name);
-                        } else {
-                            // Propagate exception
-                            throw cnfe;
-                        }
-                    }
-                }
-
-                if (resolve) {
-                    resolveClass(clazz);
-                }
-
-                return clazz;
-            }
-
-            @Override
-            public final URL getResource(final String name) {
-
-                URL resource = findResource(name);
-                ClassLoader parent = this.getParent();
-                if (resource == null && parent != null) {
-                    resource = parent.getResource(name);
-                }
-
-                return resource;
-            }
-        };
+        for (URL u : urls) {
+            cl.addURL(u);
+        }
 
         Thread.currentThread().setContextClassLoader(cl);
 
diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/ExtensionContextImpl.java b/src/main/java/org/apache/sling/feature/launcher/impl/ExtensionContextImpl.java
index 33b31a4..8f3bb6d 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/ExtensionContextImpl.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/ExtensionContextImpl.java
@@ -19,6 +19,7 @@ package org.apache.sling.feature.launcher.impl;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.net.URL;
 import java.util.Dictionary;
 import java.util.List;
 import java.util.Map;
@@ -94,6 +95,11 @@ class ExtensionContextImpl implements ExtensionContext {
     }
 
     @Override
+    public void addAppJar(URL jar) {
+        prepareContext.addAppJar(jar);
+    }
+
+    @Override
     public File getArtifactFile(ArtifactId artifact) throws IOException {
         return prepareContext.getArtifactFile(artifact);
     }
diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java b/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
index 521d7da..483359e 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
@@ -17,6 +17,7 @@
 package org.apache.sling.feature.launcher.impl;
 
 import java.io.File;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashMap;
@@ -44,7 +45,7 @@ public class Installation implements LauncherRunContext {
     private final List<Object[]> configurations = new ArrayList<>();
 
     /** The list of app jars. */
-    private final List<File> appJars = new ArrayList<>();
+    private final List<URL> appJars = new ArrayList<>();
 
     private volatile Logger logger;
 
@@ -52,7 +53,7 @@ public class Installation implements LauncherRunContext {
      * Add an application jar.
      * @param jar The application jar
      */
-    public void addAppJar(final File jar) {
+    public void addAppJar(final URL jar) {
         this.appJars.add(jar);
     }
 
@@ -60,7 +61,7 @@ public class Installation implements LauncherRunContext {
      * Get the list of application jars.
      * @return The list of app jars
      */
-    public List<File> getAppJars() {
+    public List<URL> getAppJars() {
         return this.appJars;
     }
 
diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
index 91927ed..5d84dd4 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
@@ -89,6 +89,7 @@ public class FrameworkRunner extends AbstractRunner {
         if (!this.startFramework(framework, startTimeout, TimeUnit.SECONDS)) {
             throw new TimeoutException("Waited for more than " + startTimeout + " seconds to startup framework.");
         }
+        logger.info("Framework started");
 
         logger.debug("Startup took: " + (System.currentTimeMillis() - time));
 
diff --git a/src/main/java/org/apache/sling/feature/launcher/spi/Launcher.java b/src/main/java/org/apache/sling/feature/launcher/spi/Launcher.java
index 660aec0..79aa1dc 100644
--- a/src/main/java/org/apache/sling/feature/launcher/spi/Launcher.java
+++ b/src/main/java/org/apache/sling/feature/launcher/spi/Launcher.java
@@ -16,6 +16,9 @@
  */
 package org.apache.sling.feature.launcher.spi;
 
+import java.net.URL;
+import java.net.URLClassLoader;
+
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Feature;
 
@@ -24,4 +27,59 @@ public interface Launcher {
     void prepare(LauncherPrepareContext context, ArtifactId frameworkId, Feature app) throws Exception;
 
     int run(LauncherRunContext context, ClassLoader cl) throws Exception;
+
+    default LauncherClassLoader createClassLoader() {
+        return new LauncherClassLoader();
+    }
+
+    class LauncherClassLoader extends URLClassLoader {
+        public LauncherClassLoader() {
+            super(new URL[0]);
+        }
+
+        @Override
+        public final void addURL(URL url) {
+            super.addURL(url);
+        }
+
+        @Override
+        public final Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+            // First check if it's already loaded
+            Class<?> clazz = findLoadedClass(name);
+
+            if (clazz == null) {
+
+                try {
+                    clazz = findClass(name);
+                } catch (ClassNotFoundException cnfe) {
+                    ClassLoader parent = getParent();
+                    if (parent != null) {
+                        // Ask to parent ClassLoader (can also throw a CNFE).
+                        clazz = parent.loadClass(name);
+                    } else {
+                        // Propagate exception
+                        throw cnfe;
+                    }
+                }
+            }
+
+            if (resolve) {
+                resolveClass(clazz);
+            }
+
+            return clazz;
+        }
+
+        @Override
+        public final URL getResource(final String name) {
+
+            URL resource = findResource(name);
+            ClassLoader parent = this.getParent();
+            if (resource == null && parent != null) {
+                resource = parent.getResource(name);
+            }
+
+            return resource;
+        }
+    }
 }
diff --git a/src/main/java/org/apache/sling/feature/launcher/spi/LauncherPrepareContext.java b/src/main/java/org/apache/sling/feature/launcher/spi/LauncherPrepareContext.java
index 6ba3b1a..624b9fd 100644
--- a/src/main/java/org/apache/sling/feature/launcher/spi/LauncherPrepareContext.java
+++ b/src/main/java/org/apache/sling/feature/launcher/spi/LauncherPrepareContext.java
@@ -18,6 +18,7 @@ package org.apache.sling.feature.launcher.spi;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URL;
 
 import org.apache.sling.feature.ArtifactId;
 import org.slf4j.Logger;
@@ -36,5 +37,7 @@ public interface LauncherPrepareContext {
 
     void addAppJar(File jar);
 
+    void addAppJar(URL url);
+
     File getArtifactFile(ArtifactId artifact) throws IOException;
 }


[sling-org-apache-sling-feature-launcher] 01/02: Make timeout work with framework start

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pauls pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git

commit 080ce222b14f969efe72d5e9dcb69367502394c2
Author: Karl Pauls <ka...@gmail.com>
AuthorDate: Tue May 7 17:12:09 2019 +0200

    Make timeout work with framework start
---
 .../launcher/impl/launchers/AbstractRunner.java    | 39 ++++++++++++++--------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
index af15614..b4d4275 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
@@ -32,7 +32,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -145,25 +151,32 @@ public abstract class AbstractRunner implements Callable<Integer> {
     {
         CountDownLatch latch = new CountDownLatch(1);
 
-        FrameworkListener listener = new FrameworkListener()
+        Executor executor = Executors.newSingleThreadExecutor();
+        Future<Void> result = ((ExecutorService) executor).submit(new Callable<Void>()
         {
             @Override
-            public void frameworkEvent(FrameworkEvent frameworkEvent)
+            public Void call() throws Exception
             {
-                if (frameworkEvent.getType() == FrameworkEvent.STARTED) {
-                    latch.countDown();
-                }
+                framework.start();
+                return null;
             }
-        };
-
-        framework.getBundleContext().addFrameworkListener(listener);
-
-        framework.start();
+        });
 
         try {
-            return latch.await(timeout, unit);
-        } finally {
-            framework.getBundleContext().removeFrameworkListener(listener);
+            result.get(timeout, unit);
+            return true;
+        } catch (TimeoutException ex) {
+            return false;
+        } catch (ExecutionException ex) {
+            Throwable cause = ex.getCause();
+            if (cause instanceof BundleException) {
+                throw (BundleException) cause;
+            } else {
+                throw (RuntimeException) cause;
+            }
+        }
+        finally {
+            ((ExecutorService) executor).shutdownNow();
         }
     }