You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2015/06/10 12:49:17 UTC
svn commit: r1684637 - in
/sling/whiteboard/bdelacretaz/crankstart3/launcher: ./
src/main/java/org/apache/sling/crankstart/launcher/ src/test/resources/
Author: bdelacretaz
Date: Wed Jun 10 10:49:16 2015
New Revision: 1684637
URL: http://svn.apache.org/r1684637
Log:
SLING-4728 - work in progress - OSGi framework starts
Added:
sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartModelHelper.java
sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Launcher.java
- copied, changed from r1684398, sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Main.java
sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/crankstart-model.txt
- copied, changed from r1684404, sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/launcher-test.crank.txt
Removed:
sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Main.java
sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/launcher-test.crank.txt
Modified:
sling/whiteboard/bdelacretaz/crankstart3/launcher/pom.xml
sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartBootstrap.java
Modified: sling/whiteboard/bdelacretaz/crankstart3/launcher/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/crankstart3/launcher/pom.xml?rev=1684637&r1=1684636&r2=1684637&view=diff
==============================================================================
--- sling/whiteboard/bdelacretaz/crankstart3/launcher/pom.xml (original)
+++ sling/whiteboard/bdelacretaz/crankstart3/launcher/pom.xml Wed Jun 10 10:49:16 2015
@@ -40,7 +40,7 @@
<configuration>
<archive>
<manifest>
- <mainClass>org.apache.sling.crankstart.launcher.Main</mainClass>
+ <mainClass>org.apache.sling.crankstart.launcher.Launcher</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
@@ -56,7 +56,7 @@
<goal>unpack-dependencies</goal>
</goals>
<configuration>
- <includeGroupIds>org.slf4j,org.ops4j.pax.url</includeGroupIds>
+ <includeGroupIds>org.slf4j,org.ops4j.pax.url,org.apache.sling</includeGroupIds>
<excludeTransitive>false</excludeTransitive>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<overWriteReleases>false</overWriteReleases>
@@ -81,7 +81,7 @@
<fileset>
<directory>${basedir}</directory>
<includes>
- <include>sling-crankstart</include>
+ <include>CRANKSTART</include>
</includes>
</fileset>
</filesets>
@@ -101,34 +101,16 @@
</build>
<dependencies>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.crankstart.api</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>4.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.crankstart.api.fragment</artifactId>
- <version>1.0.3-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.crankstart.core</artifactId>
- <version>1.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.crankstart.test.services</artifactId>
- <version>1.0.1-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.crankstart.sling.extensions</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -144,6 +126,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.provisioning.model</artifactId>
+ <version>1.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.ops4j.pax.url</groupId>
<artifactId>pax-url-aether</artifactId>
<version>${pax.url.version}</version>
Modified: sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartBootstrap.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartBootstrap.java?rev=1684637&r1=1684636&r2=1684637&view=diff
==============================================================================
--- sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartBootstrap.java (original)
+++ sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartBootstrap.java Wed Jun 10 10:49:16 2015
@@ -29,8 +29,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
-import org.apache.sling.crankstart.api.CrankstartConstants;
-
/** Execute a crankstart file */
public class CrankstartBootstrap {
public static final String CLASSPATH_PREFIX = "classpath ";
@@ -68,7 +66,7 @@ public class CrankstartBootstrap {
public void start() throws Exception {
- System.setProperty(CrankstartConstants.CRANKSTART_INPUT_FILENAME, crankFile);
+ //System.setProperty(CrankstartConstants.CRANKSTART_INPUT_FILENAME, crankFile);
System.setProperty( "java.protocol.handler.pkgs", "org.ops4j.pax.url" );
final URL [] launcherClasspath = getClasspath(crankFile);
Added: sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartModelHelper.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartModelHelper.java?rev=1684637&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartModelHelper.java (added)
+++ sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/CrankstartModelHelper.java Wed Jun 10 10:49:16 2015
@@ -0,0 +1,63 @@
+/*
+ * 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.crankstart.launcher;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.apache.sling.provisioning.model.Model;
+import org.apache.sling.provisioning.model.ModelUtility;
+import org.apache.sling.provisioning.model.io.ModelReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Read and merge 1..N Sling provisioning models based on file and folder names */
+public class CrankstartModelHelper {
+ public static final String MODEL_FILE_EXT = ".txt";
+ private final Model model = new Model();
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ public void read(String ... filesOrFolderNames) throws IOException {
+ for(String name : filesOrFolderNames) {
+ final File f = new File(name);
+ if(f.isDirectory()) {
+ final String [] list = f.list();
+ for(String s : list) {
+ merge(new File(f, s));
+ }
+ } else {
+ merge(f);
+ }
+ }
+ }
+
+ public Model getModel() {
+ return model;
+ }
+
+ private void merge(File f) throws IOException {
+ if(!f.getName().endsWith(MODEL_FILE_EXT)) {
+ log.warn("Model filename does not end with {}, ignored: {}", MODEL_FILE_EXT, f.getAbsolutePath());
+ return;
+ }
+ log.info("Merging model file {}", f.getAbsolutePath());
+ final BufferedReader reader = new BufferedReader(new FileReader(f));
+ ModelUtility.merge(model, ModelReader.read(reader, f.getAbsolutePath()));
+ }
+}
\ No newline at end of file
Copied: sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Launcher.java (from r1684398, sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Main.java)
URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Launcher.java?p2=sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Launcher.java&p1=sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Main.java&r1=1684398&r2=1684637&rev=1684637&view=diff
==============================================================================
--- sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Main.java (original)
+++ sling/whiteboard/bdelacretaz/crankstart3/launcher/src/main/java/org/apache/sling/crankstart/launcher/Launcher.java Wed Jun 10 10:49:16 2015
@@ -16,21 +16,132 @@
*/
package org.apache.sling.crankstart.launcher;
-import org.apache.sling.crankstart.api.CrankstartConstants;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
-/** Execute a crankstart file */
-public class Main {
- public static final String CLASSPATH_PREFIX = "classpath ";
+import org.apache.sling.provisioning.model.Artifact;
+import org.apache.sling.provisioning.model.ArtifactGroup;
+import org.apache.sling.provisioning.model.Feature;
+import org.apache.sling.provisioning.model.Model;
+import org.apache.sling.provisioning.model.ModelUtility;
+import org.apache.sling.provisioning.model.RunMode;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Launch an OSGi app instance using the Sling provisioning model */
+public class Launcher {
+ private Model model;
+ private final Logger log = LoggerFactory.getLogger(getClass());
- public static void main(String [] args) throws Exception {
- String crankFile = "default.crank.txt";
- if(args.length < 1) {
- System.err.println("Using default crank file " + crankFile);
- System.err.println("To use a different one, provide its name as a jar file argument");
+ public Launcher(String [] args) throws IOException {
+ final CrankstartModelHelper mr = new CrankstartModelHelper();
+ mr.read(args);
+ model = ModelUtility.getEffectiveModel(mr.getModel(), null);
+ }
+
+ public void launch() throws Exception {
+ // Enable pax URL for mvn: protocol
+ System.setProperty( "java.protocol.handler.pkgs", "org.ops4j.pax.url" );
+
+ // Setup initial classpath to launch the OSGi framework
+ for(URL u : getClasspathURLs(model, ":crankstart")) {
+ addToClasspath(u);
+ }
+
+ final Map<String, String> frameworkConfig = new HashMap<String, String>();
+
+ // Start the OSGi framework
+ final FrameworkFactory factory = (FrameworkFactory)getClass().getClassLoader().loadClass("org.apache.felix.framework.FrameworkFactory").newInstance();
+ final Framework f = factory.newFramework(frameworkConfig);
+ f.start();
+ setShutdownHook(f);
+ log.info("OSGi framework started, waiting for it to stop");
+ f.waitForStop(0);
+ }
+
+ /** Slightly hacky way to add URLs to the system classloader,
+ * based on http://stackoverflow.com/questions/60764/how-should-i-load-jars-dynamically-at-runtime
+ */
+ private void addToClasspath(URL u) throws IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ final URLClassLoader sysLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
+ final Method m = URLClassLoader.class.getDeclaredMethod("addURL",new Class[]{URL.class});
+ m.setAccessible(true);
+ m.invoke(sysLoader,new Object[]{ u });
+ log.info("Added to classpath: {}", u);
+ }
+
+ /** Convert a Model feature to a set of URLs meant to setup
+ * an URLClassLoader.
+ */
+ List<URL> getClasspathURLs(Model m, String featureName) throws MalformedURLException {
+ final List<URL> result = new ArrayList<URL>();
+
+ // Add all URLs from the special feature to our classpath
+ final Feature f = m.getFeature(featureName);
+ if(f == null) {
+ log.warn("No {} feature found in provisioning model, nothing to add to our classpath", featureName);
} else {
- crankFile = args[0];
+ for(RunMode rm : f.getRunModes()) {
+ for(ArtifactGroup g : rm.getArtifactGroups()) {
+ for(Artifact a : g) {
+ final String url = mvnUrl(a);
+ try {
+ result.add(new URL(url));
+ } catch(MalformedURLException e) {
+ final MalformedURLException up = new MalformedURLException("Invalid URL [" + url + "]");
+ up.initCause(e);
+ throw up;
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ public static String mvnUrl(Artifact a) {
+ return "mvn:" + a.getGroupId() + "/" + a.getArtifactId() + "/" + a.getVersion();
+ }
+
+ private void setShutdownHook(final Framework osgiFramework) {
+ // Shutdown the framework when the JVM exits
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ if(osgiFramework != null && osgiFramework.getState() == Bundle.ACTIVE) {
+ try {
+ log.info("Stopping the OSGi framework");
+ osgiFramework.stop();
+ log.info("Waiting for the OSGi framework to exit");
+ osgiFramework.waitForStop(0);
+ log.info("OSGi framework stopped");
+ } catch(Exception e) {
+ log.error("Exception while stopping OSGi framework", e);
+ }
+ }
+ }
+ });
+ }
+
+ public static void main(String [] args) throws Exception {
+ if(args.length < 1) {
+ System.err.println("Usage: Main provisioning-model [provisioning-model ...]");
+ System.err.println("Where provisioning-model is either a Sling provisioning model file");
+ System.err.println("or a folder that contains oseveral of those.");
+ System.exit(0);
}
- System.setProperty(CrankstartConstants.CRANKSTART_JAR_PATH, Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());
- new CrankstartBootstrap(crankFile).start();
+
+ new Launcher(args).launch();
}
}
\ No newline at end of file
Copied: sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/crankstart-model.txt (from r1684404, sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/launcher-test.crank.txt)
URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/crankstart-model.txt?p2=sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/crankstart-model.txt&p1=sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/launcher-test.crank.txt&r1=1684404&r2=1684637&rev=1684637&view=diff
==============================================================================
--- sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/launcher-test.crank.txt (original)
+++ sling/whiteboard/bdelacretaz/crankstart3/launcher/src/test/resources/crankstart-model.txt Wed Jun 10 10:49:16 2015
@@ -1,67 +1,56 @@
+[feature name=:crankstart]
+
# Test the crankstart launcher by setting up an HTTP
# server with a few servlets that require specific OSGi configurations
# Default values for our variables
-defaults single.path /single
+# defaults single.path /single
-# Bootstrap classpath (variables are not supported here)
-classpath mvn:org.apache.felix/org.apache.felix.framework/4.4.0
-classpath mvn:org.slf4j/slf4j-api/1.6.2
-classpath mvn:org.slf4j/slf4j-simple/1.6.2
-classpath mvn:org.apache.sling/org.apache.sling.crankstart.core/1.0.1-SNAPSHOT
-classpath mvn:org.apache.sling/org.apache.sling.crankstart.api/1.0.1-SNAPSHOT
-classpath mvn:org.apache.sling/org.apache.sling.provisioning.model/1.1.0
+[variables]
+ felix.framework.version=4.4.0
+ slf4j.version = 1.6.2
+ http.port = 8080
+ osgi.storage.path = CRANKSTART
+
+[settings]
+ org.osgi.service.http.port = ${http.port}
+ org.osgi.framework.storage = ${osgi.storage.path}
+
+[artifacts]
+ org.apache.felix/org.apache.felix.framework/${felix.framework.version}
+ org.slf4j/slf4j-api/${slf4j.version}
+ org.slf4j/slf4j-simple/${slf4j.version}
# OSGi properties
-osgi.property org.osgi.service.http.port ${http.port}
-osgi.property org.osgi.framework.storage ${osgi.storage.path}
-
-# Start the framework. Crankstart file processing will stop here
-# if this is not the first startup.
-start.framework
+#osgi.property org.osgi.service.http.port ${http.port}
+#osgi.property org.osgi.framework.storage ${osgi.storage.path}
# The crankstart.api.fragment bundle makes the crankstart.api package available
# to bundles, required for bundles to provide crankstart extension commands like
# the test.system.property command below
-bundle mvn:org.apache.sling/org.apache.sling.crankstart.api.fragment/1.0.2
-bundle mvn:org.apache.sling/org.apache.sling.crankstart3.test.services/1.0.3-SNAPSHOT
-
-# Add provisioning model artifacts
-# TODO move all bundles there
-provisioning.model src/test/resources/provisioning-model
-
-# Now start our bundles
-start.all.bundles
+#bundle mvn:org.apache.sling/org.apache.sling.crankstart.api.fragment/1.0.2
+#bundle mvn:org.apache.sling/org.apache.sling.crankstart3.test.services/1.0.3-SNAPSHOT
# OSGi configs that activate our test servlets
-config org.apache.sling.crankstart.testservices.SingleConfigServlet
- path=${single.path}
- message=doesn't matter
-
-config.factory org.apache.sling.crankstart.testservices.ConfigFactoryServlet
- CRANKSTART_CONFIG_ID=some.unique.ID
- path=/foo
- message=Not used
+#config org.apache.sling.crankstart.testservices.SingleConfigServlet
+# path=${single.path}
+# message=doesn't matter
+
+#config.factory org.apache.sling.crankstart.testservices.ConfigFactoryServlet
+# CRANKSTART_CONFIG_ID=some.unique.ID
+# path=/foo
+# message=Not used
-config.factory org.apache.sling.crankstart.testservices.ConfigFactoryServlet
- path=/bar/test
- message=Not used
+#config.factory org.apache.sling.crankstart.testservices.ConfigFactoryServlet
+# path=/bar/test
+# message=Not used
# Test Felix format configs
-config felix.format.test FORMAT:felix.config
- mongouri="mongodb://localhost:27017"
- service.ranking.launcher.test=I"54321"
- array=["foo","bar.from.launcher.test"]
-
-config empty.config.should.work FORMAT:felix.config
+#config felix.format.test FORMAT:felix.config
+# mongouri="mongodb://localhost:27017"
+# service.ranking.launcher.test=I"54321"
+# array=["foo","bar.from.launcher.test"]
-# Prepare additional resources for the Sling installer
-sling.installer.resource mvn:org.apache.sling/org.apache.sling.junit.core/1.0.8
-sling.installer.resource mvn:org.apache.sling/org.apache.sling.commons.mime/2.1.4
-sling.installer.resource mvn:org.apache.sling/org.apache.sling.settings/1.3.0
-
-# And register the installer resources
-sling.installer.register crankstart
+#config empty.config.should.work FORMAT:felix.config
-# Informative log
-log felix http service should come up at http://localhost:${http.port}
+[configurations]
\ No newline at end of file