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:03 UTC
[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
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;
}