You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2019/04/29 08:57:46 UTC
[sling-org-apache-sling-feature-launcher] branch master updated:
SLING-8379 : Separate launch logic from command line parsing
This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git
The following commit(s) were added to refs/heads/master by this push:
new 1c8b7f8 SLING-8379 : Separate launch logic from command line parsing
1c8b7f8 is described below
commit 1c8b7f8892879a33fe4f114f11cc6f24af83c394
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon Apr 29 10:56:44 2019 +0200
SLING-8379 : Separate launch logic from command line parsing
---
.../sling/feature/launcher/impl/Bootstrap.java | 329 +++++++++++++++++++++
.../feature/launcher/impl/LauncherConfig.java | 10 +
.../apache/sling/feature/launcher/impl/Main.java | 287 +-----------------
3 files changed, 342 insertions(+), 284 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
new file mode 100644
index 0000000..94ee0e8
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Bootstrap.java
@@ -0,0 +1,329 @@
+/*
+ * 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.feature.launcher.impl;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.feature.ArtifactId;
+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;
+import org.slf4j.Logger;
+
+/**
+ * This is the bootstrap class. ´ß
+ */
+public class Bootstrap {
+
+ private final LauncherConfig config;
+
+ private final Logger logger;
+
+ public Bootstrap(final LauncherConfig config, final Logger logger) {
+ this.config = config;
+ this.logger = logger;
+ }
+
+ /**
+ * Get an artifact id for the Apache Felix framework
+ *
+ * @param version The version to use or {@code null} for the default version
+ * @return The artifact id
+ * @throws IllegalArgumentException If the provided version is invalid
+ */
+ private ArtifactId getFelixFrameworkId(final String version) {
+ return new ArtifactId("org.apache.felix", "org.apache.felix.framework", version != null ? version : "6.0.1",
+ null, null);
+ }
+
+
+ private void prepare() {
+ this.config.getVariables().put("sling.home", this.config.getHomeDirectory().getAbsolutePath());
+ if (this.config.getVariables().get("repository.home") == null) {
+ this.config.getVariables().put("repository.home",
+ this.config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "repository");
+ }
+ this.config.getVariables().put("sling.launchpad",
+ this.config.getHomeDirectory().getAbsolutePath() + "/launchpad");
+
+ final Installation installation = this.config.getInstallation();
+
+ // set sling home, and use separate locations for launchpad and properties
+ installation.getFrameworkProperties().put("sling.home", this.config.getHomeDirectory().getAbsolutePath());
+ installation.getFrameworkProperties().put("sling.launchpad",
+ this.config.getHomeDirectory().getAbsolutePath() + "/launchpad");
+ if (!installation.getFrameworkProperties().containsKey("repository.home")) {
+ installation.getFrameworkProperties().put("repository.home",
+ this.config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "repository");
+ }
+ installation.getFrameworkProperties().put("sling.properties", "conf/sling.properties");
+ installation.getFrameworkProperties().put("sling.feature",
+ getApplicationFeatureFile(this.config).toURI().toString());
+
+
+ // additional OSGi properties
+ // move storage inside launcher
+ if ( installation.getFrameworkProperties().get(STORAGE_PROPERTY) == null ) {
+ installation.getFrameworkProperties().put(STORAGE_PROPERTY,
+ this.config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "framework");
+ }
+ // set start level to 30
+ if ( installation.getFrameworkProperties().get(START_LEVEL_PROP) == null ) {
+ installation.getFrameworkProperties().put(START_LEVEL_PROP, "30");
+ }
+ }
+
+ public void run() {
+ this.logger.info("");
+ this.logger.info("Apache Sling Application Launcher");
+ this.logger.info("---------------------------------");
+
+
+ this.logger.info("Initializing...");
+ prepare();
+
+ final Launcher launcher = new FrameworkLauncher();
+
+ try (ArtifactManager artifactManager = ArtifactManager.getArtifactManager(this.config)) {
+
+ this.logger.info("Artifact Repositories: {}", Arrays.toString(this.config.getRepositoryUrls()));
+ this.logger.info("Assembling provisioning model...");
+
+ try {
+ boolean restart = this.config.getFeatureFiles().length == 0;
+
+ Map<ArtifactId, Feature> loadedFeatures = new HashMap<>();
+ final Feature app = assemble(artifactManager, loadedFeatures);
+
+ this.logger.info("");
+ this.logger.info("Assembling launcher...");
+
+ final LauncherPrepareContext ctx = new LauncherPrepareContext()
+ {
+ @Override
+ 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)
+ {
+ config.getInstallation().addAppJar(jar);
+ }
+ };
+
+ launcher.prepare(ctx, getFelixFrameworkId(this.config.getFrameworkVersion()), app);
+
+ FeatureProcessor.prepareLauncher(ctx, this.config, app, loadedFeatures);
+
+ this.logger.info("Using {} local artifacts, {} cached artifacts, and {} downloaded artifacts",
+ this.config.getLocalArtifacts(), this.config.getCachedArtifacts(),
+ this.config.getDownloadedArtifacts());
+
+ if (restart) {
+ this.config.getInstallation().getInstallableArtifacts().clear();
+ this.config.getInstallation().getConfigurations().clear();
+ this.config.getInstallation().getBundleMap().clear();
+ }
+ } catch ( final Exception iae) {
+ this.logger.error("Error while assembling launcher: {}", iae.getMessage(), iae);
+ System.exit(1);
+ }
+ }
+ catch (IOException ex) {
+ this.logger.error("Unable to setup artifact manager: {}", ex.getMessage(), ex);
+ System.exit(1);
+ }
+
+ try {
+ run(launcher);
+ } catch ( final Exception iae) {
+ this.logger.error("Error while running launcher: {}", iae.getMessage(), iae);
+ System.exit(1);
+ }
+ }
+
+ private Feature assemble(final ArtifactManager artifactManager,
+ Map<ArtifactId, Feature> loadedFeatures) throws IOException
+ {
+ if (this.config.getFeatureFiles().length == 0) {
+ File application = getApplicationFeatureFile(this.config);
+ if (application.isFile()) {
+ this.config.addFeatureFiles(application.toURI().toURL().toString());
+ }
+ else {
+ throw new IllegalStateException("No feature(s) to launch found and none where specified");
+ }
+ return FeatureProcessor.createApplication(this.config, artifactManager, loadedFeatures);
+ }
+ else
+ {
+ final Feature app = FeatureProcessor.createApplication(this.config, artifactManager, loadedFeatures);
+
+ // write application back
+ final File file = getApplicationFeatureFile(this.config);
+ file.getParentFile().mkdirs();
+
+ try (final FileWriter writer = new FileWriter(file))
+ {
+ FeatureJSONWriter.write(writer, app);
+ }
+ catch (final IOException ioe)
+ {
+ this.logger.error("Error while writing application file: {}", ioe.getMessage(), ioe);
+ System.exit(1);
+ }
+ return app;
+ }
+ }
+
+ private static File getApplicationFeatureFile(final LauncherConfig launcherConfig) {
+ return new File(launcherConfig.getHomeDirectory(), "resources" + File.separatorChar + "provisioning" + File.separatorChar + "application.json");
+ }
+
+ private static final String STORAGE_PROPERTY = "org.osgi.framework.storage";
+
+ private static final String START_LEVEL_PROP = "org.osgi.framework.startlevel.beginning";
+
+ /**
+ * Run launcher.
+ * @throws Exception If anything goes wrong
+ */
+ private void run(final Launcher launcher) throws Exception {
+ this.logger.info("");
+ this.logger.info("Starting launcher...");
+ this.logger.info("Launcher Home: {}", config.getHomeDirectory().getAbsolutePath());
+ this.logger.info("Cache Directory: {}", config.getCacheDirectory().getAbsolutePath());
+ this.logger.info("");
+
+ final Installation installation = config.getInstallation();
+
+ // set sling home, and use separate locations for launchpad and properties
+ installation.getFrameworkProperties().put("sling.home", config.getHomeDirectory().getAbsolutePath());
+ installation.getFrameworkProperties().put("sling.launchpad", config.getHomeDirectory().getAbsolutePath() + "/launchpad");
+ if (!installation.getFrameworkProperties().containsKey("repository.home")) {
+ installation.getFrameworkProperties().put("repository.home", config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "repository");
+ }
+ installation.getFrameworkProperties().put("sling.properties", "conf/sling.properties");
+ installation.getFrameworkProperties().put("sling.feature", getApplicationFeatureFile(config).toURI().toString());
+
+
+ // additional OSGi properties
+ // move storage inside launcher
+ if ( installation.getFrameworkProperties().get(STORAGE_PROPERTY) == null ) {
+ installation.getFrameworkProperties().put(STORAGE_PROPERTY, config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "framework");
+ }
+ // set start level to 30
+ if ( installation.getFrameworkProperties().get(START_LEVEL_PROP) == null ) {
+ installation.getFrameworkProperties().put(START_LEVEL_PROP, "30");
+ }
+
+ while (launcher.run(installation, createClassLoader(installation)) == FrameworkEvent.STOPPED_SYSTEM_REFRESHED) {
+ this.logger.info("Framework restart due to extension refresh");
+ }
+ }
+
+ /**
+ * Create the class loader.
+ * @param installation The launcher configuration
+ * @return The classloader.
+ * @throws Exception If anything goes wrong
+ */
+ public ClassLoader createClassLoader(final Installation installation) 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.add(Bootstrap.class.getProtectionDomain().getCodeSource().getLocation());
+
+ final URL[] urls = list.toArray(new URL[list.size()]);
+
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("App classpath: ");
+ for (int i = 0; i < urls.length; i++) {
+ 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;
+ }
+ };
+
+ Thread.currentThread().setContextClassLoader(cl);
+
+ return cl;
+ }
+}
diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java b/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
index e35aec2..dfc8ef4 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
@@ -49,6 +49,8 @@ public class LauncherConfig
private final Map<String,String> variables = new HashMap<>();
+ private volatile String frameworkVersion;
+
/**
* Create a new configuration object.
* Set the default values
@@ -103,4 +105,12 @@ public class LauncherConfig
public Map<String,String> getVariables() {
return this.variables;
}
+
+ public String getFrameworkVersion() {
+ return frameworkVersion;
+ }
+
+ public void setFrameworkVersion(final String frameworkVersion) {
+ this.frameworkVersion = frameworkVersion;
+ }
}
diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/Main.java b/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
index aad8b63..1d7b603 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
@@ -17,15 +17,6 @@
package org.apache.sling.feature.launcher.impl;
import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
@@ -34,15 +25,6 @@ import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
-import org.apache.sling.feature.ArtifactId;
-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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,8 +43,6 @@ public class Main {
return LOGGER;
}
- private static volatile String m_frameworkVersion = null; // DEFAULT is null
-
/** Split a string into key and value */
private static String[] split(final String val) {
final int pos = val.indexOf('=');
@@ -145,7 +125,7 @@ public class Main {
config.setHomeDirectory(new File(cl.getOptionValue(homeOption.getOpt())));
}
if (cl.hasOption(frameworkOption.getOpt())) {
- m_frameworkVersion = cl.getOptionValue(frameworkOption.getOpt());
+ config.setFrameworkVersion(cl.getOptionValue(frameworkOption.getOpt()));
}
} catch ( final ParseException pe) {
Main.LOG().error("Unable to parse command line: {}", pe.getMessage(), pe);
@@ -157,19 +137,6 @@ public class Main {
}
}
-
- /**
- * Get an artifact id for the Apache Felix framework
- *
- * @param version The version to use or {@code null} for the default version
- * @return The artifact id
- * @throws IllegalArgumentException If the provided version is invalid
- */
- public static ArtifactId getFelixFrameworkId(final String version) {
- return new ArtifactId("org.apache.felix", "org.apache.felix.framework", version != null ? version : "6.0.1",
- null, null);
- }
-
public static void main(final String[] args) {
// setup logging
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
@@ -181,255 +148,7 @@ public class Main {
final LauncherConfig launcherConfig = new LauncherConfig();
parseArgs(launcherConfig, args);
- launcherConfig.getVariables().put("sling.home", launcherConfig.getHomeDirectory().getAbsolutePath());
- if (launcherConfig.getVariables().get("repository.home") == null ) {
- launcherConfig.getVariables().put("repository.home", launcherConfig.getHomeDirectory().getAbsolutePath() + File.separatorChar + "repository");
- }
- launcherConfig.getVariables().put("sling.launchpad", launcherConfig.getHomeDirectory().getAbsolutePath() + "/launchpad");
-
- final Installation installation = launcherConfig.getInstallation();
-
- // set sling home, and use separate locations for launchpad and properties
- installation.getFrameworkProperties().put("sling.home", launcherConfig.getHomeDirectory().getAbsolutePath());
- installation.getFrameworkProperties().put("sling.launchpad", launcherConfig.getHomeDirectory().getAbsolutePath() + "/launchpad");
- if (!installation.getFrameworkProperties().containsKey("repository.home")) {
- installation.getFrameworkProperties().put("repository.home", launcherConfig.getHomeDirectory().getAbsolutePath() + File.separatorChar + "repository");
- }
- installation.getFrameworkProperties().put("sling.properties", "conf/sling.properties");
- installation.getFrameworkProperties().put("sling.feature", getApplicationFeatureFile(launcherConfig).toURI().toString());
-
-
- // additional OSGi properties
- // move storage inside launcher
- if ( installation.getFrameworkProperties().get(STORAGE_PROPERTY) == null ) {
- installation.getFrameworkProperties().put(STORAGE_PROPERTY, launcherConfig.getHomeDirectory().getAbsolutePath() + File.separatorChar + "framework");
- }
- // set start level to 30
- if ( installation.getFrameworkProperties().get(START_LEVEL_PROP) == null ) {
- installation.getFrameworkProperties().put(START_LEVEL_PROP, "30");
- }
-
- Main.LOG().info("");
- Main.LOG().info("Apache Sling Application Launcher");
- Main.LOG().info("---------------------------------");
-
-
- Main.LOG().info("Initializing...");
-
- final Launcher launcher = new FrameworkLauncher();
-
- try (ArtifactManager artifactManager = ArtifactManager.getArtifactManager(launcherConfig)) {
-
- Main.LOG().info("Artifact Repositories: {}", Arrays.toString(launcherConfig.getRepositoryUrls()));
- Main.LOG().info("Assembling provisioning model...");
-
- try {
- boolean restart = launcherConfig.getFeatureFiles().length == 0;
-
- Map<ArtifactId, Feature> loadedFeatures = new HashMap<>();
- final Feature app = assemble(launcherConfig, artifactManager, loadedFeatures);
-
- Main.LOG().info("");
- Main.LOG().info("Assembling launcher...");
-
- final LauncherPrepareContext ctx = new LauncherPrepareContext()
- {
- @Override
- 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)
- {
- launcherConfig.getInstallation().addAppJar(jar);
- }
- };
-
- launcher.prepare(ctx, getFelixFrameworkId(m_frameworkVersion), app);
-
- FeatureProcessor.prepareLauncher(ctx, launcherConfig, app, loadedFeatures);
-
- Main.LOG().info("Using {} local artifacts, {} cached artifacts, and {} downloaded artifacts",
- launcherConfig.getLocalArtifacts(), launcherConfig.getCachedArtifacts(), launcherConfig.getDownloadedArtifacts());
-
- if (restart) {
- launcherConfig.getInstallation().getInstallableArtifacts().clear();
- launcherConfig.getInstallation().getConfigurations().clear();
- launcherConfig.getInstallation().getBundleMap().clear();
- }
- } catch ( final Exception iae) {
- Main.LOG().error("Error while assembling launcher: {}", iae.getMessage(), iae);
- System.exit(1);
- }
- }
- catch (IOException ex) {
- Main.LOG().error("Unable to setup artifact manager: {}", ex.getMessage(), ex);
- System.exit(1);
- }
-
- try {
- run(launcherConfig, launcher);
- } catch ( final Exception iae) {
- Main.LOG().error("Error while running launcher: {}", iae.getMessage(), iae);
- System.exit(1);
- }
- }
-
- private static Feature assemble(final LauncherConfig launcherConfig, final ArtifactManager artifactManager,
- Map<ArtifactId, Feature> loadedFeatures) throws IOException
- {
- if (launcherConfig.getFeatureFiles().length == 0) {
- File application = getApplicationFeatureFile(launcherConfig);
- if (application.isFile()) {
- launcherConfig.addFeatureFiles(application.toURI().toURL().toString());
- }
- else {
- throw new IllegalStateException("No feature(s) to launch found and none where specified");
- }
- return FeatureProcessor.createApplication(launcherConfig, artifactManager, loadedFeatures);
- }
- else
- {
- final Feature app = FeatureProcessor.createApplication(launcherConfig, artifactManager, loadedFeatures);
-
- // write application back
- final File file = getApplicationFeatureFile(launcherConfig);
- file.getParentFile().mkdirs();
-
- try (final FileWriter writer = new FileWriter(file))
- {
- FeatureJSONWriter.write(writer, app);
- }
- catch (final IOException ioe)
- {
- Main.LOG().error("Error while writing application file: {}", ioe.getMessage(), ioe);
- System.exit(1);
- }
- return app;
- }
- }
-
- private static File getApplicationFeatureFile(final LauncherConfig launcherConfig) {
- return new File(launcherConfig.getHomeDirectory(), "resources" + File.separatorChar + "provisioning" + File.separatorChar + "application.json");
- }
-
- private static final String STORAGE_PROPERTY = "org.osgi.framework.storage";
-
- private static final String START_LEVEL_PROP = "org.osgi.framework.startlevel.beginning";
-
- /**
- * Run launcher.
- * @param config The configuration
- * @throws Exception If anything goes wrong
- */
- private static void run(final LauncherConfig config, final Launcher launcher) throws Exception {
- Main.LOG().info("");
- Main.LOG().info("Starting launcher...");
- Main.LOG().info("Launcher Home: {}", config.getHomeDirectory().getAbsolutePath());
- Main.LOG().info("Cache Directory: {}", config.getCacheDirectory().getAbsolutePath());
- Main.LOG().info("");
-
- final Installation installation = config.getInstallation();
-
- // set sling home, and use separate locations for launchpad and properties
- installation.getFrameworkProperties().put("sling.home", config.getHomeDirectory().getAbsolutePath());
- installation.getFrameworkProperties().put("sling.launchpad", config.getHomeDirectory().getAbsolutePath() + "/launchpad");
- if (!installation.getFrameworkProperties().containsKey("repository.home")) {
- installation.getFrameworkProperties().put("repository.home", config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "repository");
- }
- installation.getFrameworkProperties().put("sling.properties", "conf/sling.properties");
- installation.getFrameworkProperties().put("sling.feature", getApplicationFeatureFile(config).toURI().toString());
-
-
- // additional OSGi properties
- // move storage inside launcher
- if ( installation.getFrameworkProperties().get(STORAGE_PROPERTY) == null ) {
- installation.getFrameworkProperties().put(STORAGE_PROPERTY, config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "framework");
- }
- // set start level to 30
- if ( installation.getFrameworkProperties().get(START_LEVEL_PROP) == null ) {
- installation.getFrameworkProperties().put(START_LEVEL_PROP, "30");
- }
-
- while (launcher.run(installation, createClassLoader(installation)) == FrameworkEvent.STOPPED_SYSTEM_REFRESHED) {
- Main.LOG().info("Framework restart due to extension refresh");
- }
- }
-
- /**
- * Create the class loader.
- * @param installation The launcher configuration
- * @return The classloader.
- * @throws Exception If anything goes wrong
- */
- public static ClassLoader createClassLoader(final Installation installation) 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.add(Main.class.getProtectionDomain().getCodeSource().getLocation());
-
- final URL[] urls = list.toArray(new URL[list.size()]);
-
- if ( Main.LOG().isDebugEnabled() ) {
- Main.LOG().debug("App classpath: ");
- for (int i = 0; i < urls.length; i++) {
- Main.LOG().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;
- }
- };
-
- Thread.currentThread().setContextClassLoader(cl);
-
- return cl;
+ final Bootstrap bootstrap = new Bootstrap(launcherConfig, Main.LOG());
+ bootstrap.run();
}
}