You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2020/01/07 20:44:33 UTC
[sling-whiteboard] branch master updated: Removed an older project,
created both Sling Feature Starter and the Slingstarter Feature
Maven Plugin
This is an automated email from the ASF dual-hosted git repository.
andysch pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git
The following commit(s) were added to refs/heads/master by this push:
new a59ccc7 Removed an older project, created both Sling Feature Starter and the Slingstarter Feature Maven Plugin
a59ccc7 is described below
commit a59ccc778cca844dc276996a7fdc3907f86f6dd8
Author: Andreas Schaefer <sc...@iMac.local>
AuthorDate: Tue Jan 7 12:44:19 2020 -0800
Removed an older project, created both Sling Feature Starter and the Slingstarter Feature Maven Plugin
---
.../pom.xml | 259 ------------
.../src/main/fm/boot_boot.json | 114 -----
.../src/main/fm/composum_composum-nodes.json | 43 --
.../src/main/fm/healthcheck_healthcheck.json | 106 -----
.../src/main/fm/launchpad_launchpad.json | 19 -
.../src/main/fm/oak_oak.json | 120 ------
.../src/main/fm/repoinit_repoinit.json | 66 ---
.../src/main/fm/scripting_sling.json | 96 -----
.../src/main/fm/sling-caconfig_sling-caconfig.json | 28 --
.../main/fm/sling-discovery_sling-discovery.json | 45 --
.../src/main/fm/sling-event_sling-event.json | 32 --
...els-jacksonexporter_models-jacksonexporter.json | 25 --
.../main/fm/sling-validation_sling-validation.json | 32 --
.../src/main/fm/sling_sling.json | 450 --------------------
.../src/main/fm/sling_slingshot.json | 39 --
.../src/main/fm/standalone_standalone.json | 16 -
.../src/main/fm/webapp_webapp.json | 4 -
sling-org-apache-sling-feature-starter/Readme.md | 23 +
sling-org-apache-sling-feature-starter/pom.xml | 86 +++-
.../src/main/resources/feature-sling12.json | 2 +-
sling-slingstart-feature-maven-plugin/Readme.md | 51 +++
sling-slingstart-feature-maven-plugin/pom.xml | 348 ++++++++++++++++
.../maven/slingstart/feature/BuildConstants.java | 105 +++++
.../slingstart/feature/launcher/Launcher.java | 96 +++++
.../slingstart/feature/launcher/LauncherMBean.java | 34 ++
.../maven/slingstart/feature/launcher/Main.java | 113 +++++
.../feature/run/AbstractStartStopMojo.java | 82 ++++
.../slingstart/feature/run/ControlListener.java | 160 +++++++
.../slingstart/feature/run/LauncherCallable.java | 369 +++++++++++++++++
.../feature/run/LaunchpadEnvironment.java | 152 +++++++
.../maven/slingstart/feature/run/PortHelper.java | 49 +++
.../slingstart/feature/run/ProcessDescription.java | 81 ++++
.../feature/run/ProcessDescriptionProvider.java | 106 +++++
.../feature/run/ServerConfiguration.java | 219 ++++++++++
.../maven/slingstart/feature/run/StartMojo.java | 461 +++++++++++++++++++++
.../maven/slingstart/feature/run/StopMojo.java | 88 ++++
36 files changed, 2617 insertions(+), 1502 deletions(-)
diff --git a/sling-org-apache-sling-feature-model-starter/pom.xml b/sling-org-apache-sling-feature-model-starter/pom.xml
deleted file mode 100644
index 3a4188f..0000000
--- a/sling-org-apache-sling-feature-model-starter/pom.xml
+++ /dev/null
@@ -1,259 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
- <!--
- 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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.sling</groupId>
- <artifactId>sling</artifactId>
- <version>35</version>
- <relativePath />
- </parent>
-
- <artifactId>org.apache.sling.feature.model.starter</artifactId>
- <packaging>slingosgifeature</packaging>
- <version>12-SNAPSHOT</version>
-
- <name>Apache Sling Feature Module Starter Application</name>
- <description>
- The Sling Starter application built from Feature Models
- </description>
-
-<!-- <scm>-->
-<!-- <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-starter.git</connection>-->
-<!-- <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-starter.git</developerConnection>-->
-<!-- <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-starter.git</url>-->
-<!-- <tag>HEAD</tag>-->
-<!-- </scm>-->
-
- <properties>
- <sling.java.version>8</sling.java.version>
- <IT.expected.bundles.count>126</IT.expected.bundles.count>
- <slingfeature-maven-plugin.version>1.1.10</slingfeature-maven-plugin.version>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>ianal-maven-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>verify-legal-files</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <configuration>
- <filesets>
- <fileset>
- <directory>${basedir}</directory>
- <includes>
- <include>derby.log</include>
- <include>cachedir/**</include>
- <include>sling/**</include>
- <include>jackrabbit/**</include>
- <include>coverage.ec</include>
- </includes>
- </fileset>
- </filesets>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.sling</groupId>
- <artifactId>slingfeature-maven-plugin</artifactId>
- <version>${slingfeature-maven-plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <features>src/main/fm</features>
- </configuration>
- <executions>
- <execution>
- <id>aggregate-base-feature</id>
- <phase>generate-test-sources</phase>
- <goals>
- <goal>aggregate-features</goal>
- </goals>
- <configuration>
- <aggregates>
- <aggregate>
- <classifier>sling12</classifier>
- <filesInclude>**/*.json</filesInclude>
- <includeArtifact>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.jcr.packageinit</artifactId>
- <version>0.0.1-SNAPSHOT</version>
-<!-- <classifier>jcr-packageinit</classifier>-->
- <type>pom</type>
- </includeArtifact>
- </aggregate>
- </aggregates>
- </configuration>
- </execution>
- <execution>
- <id>attach-base-feature</id>
- <phase>process-test-sources</phase>
- <goals>
- <goal>attach-features</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-<!-- <plugin>-->
-<!-- <groupId>org.apache.sling</groupId>-->
-<!-- <artifactId>slingstart-maven-plugin</artifactId>-->
-<!-- <extensions>true</extensions>-->
-<!-- <executions>-->
-<!-- <execution>-->
-<!-- <id>start-container</id>-->
-<!-- <goals>-->
-<!-- <goal>start</goal>-->
-<!-- <goal>stop</goal>-->
-<!-- </goals>-->
-<!-- </execution>-->
-<!-- </executions> -->
-<!-- <configuration>-->
-<!-- <createWebapp>true</createWebapp>-->
-<!-- <servers>-->
-<!-- <server>-->
-<!-- <port>${http.port}</port>-->
-<!-- <controlPort>${sling.control.port}</controlPort>-->
-<!-- </server>-->
-<!-- </servers> -->
-<!-- </configuration>-->
-<!-- </plugin>-->
-
-<!-- <plugin>-->
-<!-- <groupId>org.codehaus.mojo</groupId>-->
-<!-- <artifactId>build-helper-maven-plugin</artifactId>-->
-<!-- <executions>-->
-<!-- <execution>-->
-<!-- <id>reserve-network-port</id>-->
-<!-- <goals>-->
-<!-- <!– pre-integration-test is too late –>-->
-<!-- <goal>reserve-network-port</goal>-->
-<!-- </goals>-->
-<!-- <phase>process-resources</phase>-->
-<!-- <configuration>-->
-<!-- <portNames>-->
-<!-- <portName>http.port</portName>-->
-<!-- <portName>sling.control.port</portName>-->
-<!-- </portNames>-->
-<!-- </configuration>-->
-<!-- </execution>-->
-<!-- </executions>-->
-<!-- </plugin>-->
-
-<!-- <plugin>-->
-<!-- <artifactId>maven-failsafe-plugin</artifactId>-->
-<!-- <executions>-->
-<!-- <execution>-->
-<!-- <goals>-->
-<!-- <goal>integration-test</goal>-->
-<!-- <goal>verify</goal>-->
-<!-- </goals>-->
-<!-- </execution>-->
-<!-- </executions>-->
-<!-- <configuration>-->
-<!-- <systemPropertyVariables>-->
-<!-- <launchpad.http.port>${http.port}</launchpad.http.port>-->
-<!-- <IT.expected.bundles.count>${IT.expected.bundles.count}</IT.expected.bundles.count>-->
-<!-- </systemPropertyVariables>-->
-<!-- </configuration>-->
-<!-- </plugin> -->
- </plugins>
-
- <pluginManagement>
- <plugins>
- <plugin>
- <!-- Extend RAT configuration from parent pom -->
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <configuration>
- <excludes combine.children="append">
- <!-- Exclude sling instance -->
- <exclude>sling/**</exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
-
- </build>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient</artifactId>
- <version>4.5.6</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <version>1.11.0</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>launch</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.sling</groupId>
- <artifactId>slingfeature-maven-plugin</artifactId>
- <version>1.0.7-SNAPSHOT</version>
- <extensions>true</extensions>
- <dependencies>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.launcher</artifactId>
- <version>1.0.7-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.feature.extension.content</artifactId>
- <version>1.0.5-SNAPSHOT</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <id>launch-it</id>
- <phase>install</phase>
- <goals>
- <goal>launch-features</goal>
- </goals>
- <configuration>
- <selection>
- <includeClassifier>sling12</includeClassifier>
- </selection>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
-
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/boot_boot.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/boot_boot.json
deleted file mode 100644
index 543c3f0..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/boot_boot.json
+++ /dev/null
@@ -1,114 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:boot:12-SNAPSHOT",
- "variables":{
- "slf4j.version":"1.7.25"
- },
- "bundles":[
- {
- "id":"org.apache.aries:org.apache.aries.util:1.1.3",
- "start-order":"1"
- },
- {
- "id":"org.apache.commons:commons-lang3:3.8.1",
- "start-order":"1"
- },
- {
- "id":"org.apache.felix:org.apache.felix.configadmin:1.9.14",
- "start-order":"1"
- },
- {
- "id":"org.apache.felix:org.apache.felix.eventadmin:1.5.0",
- "start-order":"1"
- },
- {
- "id":"org.apache.geronimo.specs:geronimo-annotation_1.3_spec:1.1",
- "start-order":"1"
- },
- {
- "id":"org.apache.geronimo.specs:geronimo-atinject_1.0_spec:1.1",
- "start-order":"1"
- },
- {
- "id":"org.apache.geronimo.specs:geronimo-ws-metadata_2.0_spec:1.1.3",
- "start-order":"1"
- },
- {
- "id":"org.apache.servicemix.bundles:org.apache.servicemix.bundles.jaxb-impl:2.2.11_1",
- "start-order":"1"
- },
- {
- "id":"org.apache.servicemix.bundles:org.apache.servicemix.bundles.saaj-impl:1.3.23_2",
- "start-order":"1"
- },
- {
- "id":"org.apache.servicemix.specs:org.apache.servicemix.specs.jaxb-api-2.2:2.9.0",
- "start-order":"1"
- },
- {
- "id":"org.apache.servicemix.specs:org.apache.servicemix.specs.jaxws-api-2.2:2.9.0",
- "start-order":"1"
- },
- {
- "id":"org.apache.servicemix.specs:org.apache.servicemix.specs.saaj-api-1.3:2.8.0",
- "start-order":"1"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.log:5.1.10",
- "start-order":"1"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.logservice:1.0.6",
- "start-order":"1"
- },
- {
- "id":"org.apache.sling:org.apache.sling.installer.core:3.9.0",
- "start-order":"1"
- },
- {
- "id":"org.apache.sling:org.apache.sling.installer.factory.configuration:1.2.2",
- "start-order":"1"
- },
- {
- "id":"org.apache.sling:org.apache.sling.installer.provider.file:1.1.0",
- "start-order":"1"
- },
- {
- "id":"org.apache.sling:org.apache.sling.javax.activation:0.1.0",
- "start-order":"1"
- },
- {
- "id":"org.apache.sling:org.apache.sling.settings:1.3.10",
- "start-order":"1"
- },
- {
- "id":"org.jvnet.staxex:stax-ex:1.7.6",
- "start-order":"1"
- },
- {
- "id":"org.osgi:org.osgi.util.function:1.1.0",
- "start-order":"1"
- },
- {
- "id":"org.osgi:org.osgi.util.promise:1.1.0",
- "start-order":"1"
- },
- {
- "id":"org.slf4j:jcl-over-slf4j:1.7.25",
- "start-order":"1"
- },
- {
- "id":"org.slf4j:log4j-over-slf4j:1.7.25",
- "start-order":"1"
- },
- {
- "id":"org.slf4j:slf4j-api:1.7.25",
- "start-order":"1"
- }
- ],
- "framework-properties":{
- "sling.run.mode.install.options":"oak_tar,oak_mongo",
- "localIndexDir":"${sling.home}/repository/index",
- "repository.home":"${sling.home}/repository"
- }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/composum_composum-nodes.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/composum_composum-nodes.json
deleted file mode 100644
index 56297ef..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/composum_composum-nodes.json
+++ /dev/null
@@ -1,43 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:composum_composum-nodes:12-SNAPSHOT",
- "variables":{
- "composum.nodes.version":"1.11.3"
- },
- "bundles":[
- {
- "id":"com.composum.sling.core:composum-sling-core-commons:1.11.3",
- "start-order":"20"
- },
- {
- "id":"com.composum.sling.core:composum-sling-core-console:1.11.3",
- "start-order":"20"
- },
- {
- "id":"com.composum.sling.core:composum-sling-core-jslibs:1.11.3",
- "start-order":"20"
- },
- {
- "id":"com.composum.sling.core:composum-sling-package-manager:1.11.3",
- "start-order":"20"
- },
- {
- "id":"com.composum.sling.core:composum-sling-user-management:1.11.3",
- "start-order":"20"
- },
- {
- "id":"org.apache.jackrabbit.vault:org.apache.jackrabbit.vault:3.2.4",
- "start-order":"20"
- }
- ],
- "configurations":{
- "org.apache.sling.jcr.base.internal.LoginAdminWhitelist.fragment~composum":{
- "whitelist.bundles":[
- "com.composum.core.commons",
- "com.composum.core.pckgmgr",
- "com.composum.core.pckginstall"
- ],
- "whitelist.name":"composum"
- }
- }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/healthcheck_healthcheck.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/healthcheck_healthcheck.json
deleted file mode 100644
index f83dc3c..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/healthcheck_healthcheck.json
+++ /dev/null
@@ -1,106 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:healthcheck:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.felix:org.apache.felix.healthcheck.api:2.0.2",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.healthcheck.core:2.0.6",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.healthcheck.generalchecks:2.0.4",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.healthcheck.webconsoleplugin:2.0.0",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.hc.api:1.0.4",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.hc.support:1.0.6",
- "start-order":"20"
- }
- ],
- "configurations":{
- "org.apache.felix.hc.generalchecks.BundlesStartedCheck":{
- "hc.tags":[
- "bundles"
- ]
- },
- "org.apache.felix.hc.generalchecks.CpuCheck":{
- "hc.tags":[
- "cpu",
- "system-resources"
- ],
- "cpuPercentageThresholdWarn":95
- },
- "org.apache.felix.hc.generalchecks.DiskSpaceCheck":{
- "hc.tags":[
- "diskspace",
- "system-resources"
- ],
- "diskPaths":[
- "."
- ]
- },
- "org.apache.felix.hc.generalchecks.FrameworkStartCheck":{
- "hc.tags":[
- "systemalive"
- ],
- "targetStartLevel:Integer":"30"
- },
- "org.apache.felix.hc.generalchecks.MemoryCheck":{
- "hc.tags":[
- "memory",
- "system-resources"
- ],
- "heapUsedPercentageThresholdCritical":100,
- "heapUsedPercentageThresholdWarn":95
- },
- "org.apache.felix.hc.generalchecks.ServicesCheck":{
- "hc.tags":[
- "systemalive"
- ],
- "services.list":[
- "org.apache.sling.jcr.api.SlingRepository",
- "org.apache.sling.engine.auth.Authenticator",
- "org.apache.sling.api.resource.ResourceResolverFactory",
- "org.apache.sling.api.servlets.ServletResolver",
- "javax.script.ScriptEngineManager"
- ]
- },
- "org.apache.felix.hc.generalchecks.ThreadUsageCheck":{
- "hc.tags":[
- "threads",
- "cpu",
- "system-resources"
- ]
- },
- "org.apache.felix.hc.core.impl.filter.ServiceUnavailableFilter~startupandshutdown":{
- "osgi.http.whiteboard.filter.regex":"(?!/system/).*",
- "avoid404DuringStartup":true,
- "service.ranking:Integer":"2147483647",
- "includeExecutionResult":false,
- "osgi.http.whiteboard.context.select":"(osgi.http.whiteboard.context.name=*)",
- "tags":[
- "systemalive"
- ],
- "autoDisableFilter":true,
- "responseTextFor503":"classpath:org.apache.sling.starter.content:content/content/startup/index.html"
- },
- "org.apache.felix.hc.core.impl.servlet.HealthCheckExecutorServlet~default":{
- "servletPath":"/system/health"
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~hc-support":{
- "user.mapping":[
- "org.apache.sling.hc.support=sling-readall"
- ]
- }
- }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/launchpad_launchpad.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/launchpad_launchpad.json
deleted file mode 100644
index d36c980..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/launchpad_launchpad.json
+++ /dev/null
@@ -1,19 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:launchpad:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.sling:org.apache.sling.launchpad.base:6.0.2-2.6.36",
- "start-order":"20"
- }
- ],
- "framework-properties":{
- "sling.jre.java.xml":",javax.xml;version=\"2.1.0\",javax.xml.datatype;uses:=\"javax.xml.namespace\";version=\"2.1.0\",javax.xml.namespace;version=\"2.1.0\",javax.xml.parsers;uses:=\"javax.xml.validation,org.w3c.dom,org.xml.sax,org.xml.sax.helpers\";version=\"2.1.0\",javax.xml.stream;uses:=\"javax.xml.namespace,javax.xml.stream.events,javax.xml.stream.util,javax.xml.transform\";version=\"1.0.0\",javax.xml.stream.events;uses:=\"javax.xml.namespace,javax.xml.stream\";version=\"1.0.0 [...]
- "felix.systempackages.calculate.uses":"true",
- "org.osgi.framework.system.packages":"org.osgi.framework;version=\"1.9\",org.osgi.framework.dto;version=\"1.8\";uses:=\"org.osgi.dto\",org.osgi.framework.hooks.bundle;version=\"1.1\";uses:=\"org.osgi.framework\",org.osgi.framework.hooks.resolver;version=\"1.0\";uses:=\"org.osgi.framework.wiring\",org.osgi.framework.hooks.service;version=\"1.1\";uses:=\"org.osgi.framework\",org.osgi.framework.hooks.weaving;version=\"1.1\";uses:=\"org.osgi.framework.wiring\",org.osgi.framework.laun [...]
- "felix.systempackages.substitution":"true",
- "sling.jre-jpms":"{dollar}{felix.jpms.java.base}{dollar}{felix.jpms.java.compiler}{dollar}{felix.jpms.java.datatransfer}{dollar}{felix.jpms.java.desktop}{dollar}{felix.jpms.java.instrument}{dollar}{felix.jpms.java.logging}{dollar}{felix.jpms.java.management}{dollar}{felix.jpms.java.management.rmi}{dollar}{felix.jpms.java.naming}{dollar}{felix.jpms.java.net.http}{dollar}{felix.jpms.java.prefs}{dollar}{felix.jpms.java.rmi}{dollar}{felix.jpms.java.scripting}{dollar}{felix.jpms.java. [...]
- "sling.jpms.java.xml":"{dollar}{sling.jre.java.xml},javax.xml.catalog;uses:=\"javax.xml.namespace\";version=\"1.0.0\"",
- "sling.jre-1.8":",java.applet;version=\"{dollar}{felix.detect.java.version}\",java.awt;version=\"{dollar}{felix.detect.java.version}\",java.awt.color;version=\"{dollar}{felix.detect.java.version}\",java.awt.datatransfer;version=\"{dollar}{felix.detect.java.version}\",java.awt.dnd;version=\"{dollar}{felix.detect.java.version}\",java.awt.event;version=\"{dollar}{felix.detect.java.version}\",java.awt.font;version=\"{dollar}{felix.detect.java.version}\",java.awt.geom;version=\"{dolla [...]
- }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/oak_oak.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/oak_oak.json
deleted file mode 100644
index 4871cd8..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/oak_oak.json
+++ /dev/null
@@ -1,120 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:oak:12-SNAPSHOT",
- "variables":{
- "oak.version":"1.16.0"
- },
- "bundles":[
- {
- "id":"org.apache.felix:org.apache.felix.jaas:1.0.2",
- "start-order":"10"
- },
- {
- "id":"org.apache.jackrabbit:oak-api:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-blob-plugins:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-blob:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-commons:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-core-spi:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-core:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-jcr:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-lucene:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-query-spi:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-security-spi:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-store-composite:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-store-document:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:oak-store-spi:1.16.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.oak.server:1.2.2",
- "start-order":"16"
- },
- {
- "id":"org.apache.jackrabbit:oak-segment-tar:1.16.0",
- "run-modes":"oak_tar",
- "start-order":"15"
- }
- ],
- "configurations":{
- "org.apache.felix.jaas.ConfigurationSpi":{
- "jaas.defaultRealmName":"jackrabbit.oak",
- "jaas.configProviderName":"FelixJaasProvider"
- },
- "org.apache.jackrabbit.oak.security.authentication.AuthenticationConfigurationImpl":{
- "org.apache.jackrabbit.oak.authentication.configSpiName":"FelixJaasProvider"
- },
- "org.apache.jackrabbit.oak.security.user.RandomAuthorizableNodeName":{
- "length:Integer":"21"
- },
- "org.apache.jackrabbit.oak.security.user.UserConfigurationImpl":{
- "groupsPath":"/home/groups",
- "defaultDepth":"1",
- "importBehavior":"besteffort",
- "usersPath":"/home/users"
- },
- "org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider":{
- "userPrivilegeNames":[
- "jcr:all"
- ],
- "groupPrivilegeNames":[
- "jcr:read"
- ],
- "enabledActions":[
- "org.apache.jackrabbit.oak.spi.security.user.action.AccessControlAction"
- ]
- },
- "org.apache.felix.jaas.Configuration.factory~GuestLoginModule":{
- "jaas.controlFlag":"optional",
- "jaas.classname":"org.apache.jackrabbit.oak.spi.security.authentication.GuestLoginModule",
- "jaas.ranking:Integer":"300"
- },
- "org.apache.felix.jaas.Configuration.factory~LoginModuleImpl":{
- "jaas.controlFlag":"required",
- "jaas.classname":"org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl"
- },
- "org.apache.felix.jaas.Configuration.factory~TokenLoginModule":{
- "jaas.controlFlag":"sufficient",
- "jaas.classname":"org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule",
- "jaas.ranking:Integer":"200"
- },
- "org.apache.jackrabbit.oak.segment.SegmentNodeStoreService":{
- "name":"Default NodeStore"
- }
- }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/repoinit_repoinit.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/repoinit_repoinit.json
deleted file mode 100644
index 2c75958..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/repoinit_repoinit.json
+++ /dev/null
@@ -1,66 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:repoinit:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.sling:org.apache.sling.jcr.repoinit:1.1.10",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.provisioning.model:1.8.4",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.repoinit.parser:1.2.4",
- "start-order":"20"
- }
- ],
- "repoinit:TEXT|true":[
- "# general",
- "create path (sling:OrderedFolder) /content",
- "set ACL for everyone",
- "allow jcr:read\ton /content",
- "end",
- "",
- "# sling-mapping",
- "create service user sling-mapping",
- "",
- "set ACL for sling-mapping",
- "allow jcr:read on /",
- "end",
- "",
- "# sling-readall",
- "create service user sling-readall",
- "",
- "set ACL for sling-readall",
- "allow jcr:read on /",
- "end",
- "",
- "# sling-xss",
- "create service user sling-xss",
- "",
- "create path (sling:Folder) /apps/sling/xss",
- "",
- "set ACL for sling-xss",
- "allow jcr:read on /apps/sling/xss",
- "end",
- "",
- "# sling-i18n",
- "create service user sling-i18n",
- "",
- "set ACL for sling-i18n",
- "allow jcr:read on /",
- "end",
- "",
- "# sling-jcr-install",
- "create service user sling-jcr-install",
- "",
- "# used for config OSGi writeback",
- "create path (sling:Folder) /apps/sling/install",
- "",
- "set ACL for sling-jcr-install",
- "allow\tjcr:read\ton\t/",
- "allow\trep:write\ton /apps/sling/install",
- "end"
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/scripting_sling.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/scripting_sling.json
deleted file mode 100644
index 818dbd6..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/scripting_sling.json
+++ /dev/null
@@ -1,96 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:scripting_sling:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.antlr:antlr4-runtime:4.7.1",
- "start-order":"20"
- },
- {
- "id":"org.apache.servicemix.bundles:org.apache.servicemix.bundles.rhino:1.7.10_1",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.api:2.2.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.core:2.0.56",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.el-api:1.0.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.javascript:3.0.4",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.jsp-api:1.0.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.jsp.taglib:2.4.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.jsp:2.3.4",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.sightly.compiler.java:1.1.2-1.4.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.sightly.compiler:1.1.2-1.4.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.sightly.js.provider:1.0.28",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.sightly.models.provider:1.0.8",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.sightly.repl:1.0.6",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.sightly.runtime:1.1.0-1.4.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.scripting.sightly:1.1.2-1.4.0",
- "start-order":"20"
- }
- ],
- "configurations":{
- "org.apache.sling.scripting.core.impl.ScriptCacheImpl":{
- "org.apache.sling.scripting.cache.additional_extensions":[
- "js"
- ]
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~scripting":{
- "user.mapping":[
- "org.apache.sling.scripting.core=sling-scripting",
- "org.apache.sling.scripting.sightly.js.provider=sling-scripting"
- ]
- }
- },
- "repoinit:TEXT|true":[
- "#<<< SLING-5848 - Define service user and ACLs for Scripting",
- "create service user sling-scripting",
- "",
- "create path (sling:Folder) /libs",
- "create path (sling:Folder) /apps",
- "",
- "set ACL for sling-scripting",
- "deny jcr:all on /",
- "allow jcr:read on /libs,/apps",
- "end",
- "# SLING-5848 - Define service user and ACLs for Scripting >>>"
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-caconfig_sling-caconfig.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-caconfig_sling-caconfig.json
deleted file mode 100644
index cc3131d..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-caconfig_sling-caconfig.json
+++ /dev/null
@@ -1,28 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-caconfig:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.sling:org.apache.sling.caconfig.api:1.1.2",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.caconfig.impl:1.4.14",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.caconfig.spi:1.3.4",
- "start-order":"20"
- }
- ],
- "configurations":{
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~sling-caconfig":{
- "user.mapping":[
- "org.apache.sling.caconfig.impl=sling-readall"
- ]
- }
- },
- "repoinit:TEXT|true":[
- "create path (sling:Folder) /conf"
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-discovery_sling-discovery.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-discovery_sling-discovery.json
deleted file mode 100644
index c50f992..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-discovery_sling-discovery.json
+++ /dev/null
@@ -1,45 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-discovery:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.sling:org.apache.sling.discovery.api:1.0.4",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.discovery.base:2.0.8",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.discovery.commons:1.0.20",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.discovery.oak:1.2.28",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.discovery.support:1.0.4",
- "start-order":"20"
- }
- ],
- "configurations":{
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~sling.discovery":{
- "user.mapping":[
- "org.apache.sling.discovery.commons=sling-discovery",
- "org.apache.sling.discovery.base=sling-discovery",
- "org.apache.sling.discovery.oak=sling-discovery"
- ]
- }
- },
- "repoinit:TEXT|true":[
- "create service user sling-discovery",
- "",
- "create path (sling:Folder) /var/discovery",
- "create path (sling:Folder) /var/discovery/oak",
- "",
- "set ACL for sling-discovery",
- "allow jcr:read,rep:write on /var/discovery",
- "end"
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-event_sling-event.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-event_sling-event.json
deleted file mode 100644
index 8cd957e..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-event_sling-event.json
+++ /dev/null
@@ -1,32 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-event:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.sling:org.apache.sling.event.dea:1.1.4",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.event:4.2.12",
- "start-order":"20"
- }
- ],
- "configurations":{
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~sling.event":{
- "user.mapping":[
- "org.apache.sling.event=sling-event",
- "org.apache.sling.event.dea=sling-event"
- ]
- }
- },
- "repoinit:TEXT|true":[
- "create service user sling-event",
- "",
- "create path (sling:Folder) /var",
- "create path (sling:Folder) /var/eventing",
- "",
- "set ACL for sling-event",
- "allow jcr:read,rep:write on /var/eventing",
- "end"
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-models-jacksonexporter_models-jacksonexporter.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-models-jacksonexporter_models-jacksonexporter.json
deleted file mode 100644
index f2e664c..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-models-jacksonexporter_models-jacksonexporter.json
+++ /dev/null
@@ -1,25 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-models-jacksonexporter_models-jacksonexporter:12-SNAPSHOT",
- "variables":{
- "jackson.version":"2.9.9"
- },
- "bundles":[
- {
- "id":"com.fasterxml.jackson.core:jackson-annotations:2.9.9",
- "start-order":"20"
- },
- {
- "id":"com.fasterxml.jackson.core:jackson-core:2.9.9",
- "start-order":"20"
- },
- {
- "id":"com.fasterxml.jackson.core:jackson-databind:2.9.9",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.models.jacksonexporter:1.0.8",
- "start-order":"20"
- }
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-validation_sling-validation.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-validation_sling-validation.json
deleted file mode 100644
index da06699..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-validation_sling-validation.json
+++ /dev/null
@@ -1,32 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-validation:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.sling:org.apache.sling.validation.api:1.0.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.validation.core:1.0.4",
- "start-order":"20"
- }
- ],
- "configurations":{
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~validation":{
- "user.mapping":[
- "org.apache.sling.validation.core=sling-validation"
- ]
- }
- },
- "repoinit:TEXT|true":[
- "create service user sling-validation",
- "",
- "create path (sling:Folder) /apps",
- "create path (sling:Folder) /libs",
- "",
- "set ACL for sling-validation",
- "allow jcr:read on /apps",
- "allow jcr:read on /libs",
- "end"
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_sling.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_sling.json
deleted file mode 100644
index cca427c..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_sling.json
+++ /dev/null
@@ -1,450 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling:12-SNAPSHOT",
- "variables":{
- "jackrabbit.version":"2.18.2"
- },
- "bundles":[
- {
- "id":"commons-codec:commons-codec:1.12",
- "start-order":"20"
- },
- {
- "id":"commons-collections:commons-collections:3.2.2",
- "start-order":"20"
- },
- {
- "id":"javax.mail:mail:1.5.0-b01",
- "start-order":"20"
- },
- {
- "id":"org.apache.commons:commons-collections4:4.2",
- "start-order":"20"
- },
- {
- "id":"org.apache.commons:commons-math:2.2",
- "start-order":"20"
- },
- {
- "id":"org.apache.geronimo.bundles:jstl:1.2_1",
- "start-order":"20"
- },
- {
- "id":"org.apache.httpcomponents:httpclient-osgi:4.5.6",
- "start-order":"20"
- },
- {
- "id":"org.apache.httpcomponents:httpcore-osgi:4.4.10",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.adapter:2.1.10",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.auth.form:1.0.14",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.bundleresource.impl:2.3.2",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.classloader:1.4.4",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.compiler:2.3.6",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.fsclassloader:1.0.10",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.mime:2.2.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.osgi:2.4.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.scheduler:2.7.2",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.threads:3.2.18",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.engine:2.6.18",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.fsresource:2.1.14",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.i18n:2.5.14",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.installer.console:1.0.2",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.installer.hc:2.0.2",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.installer.provider.jcr:3.1.26",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.contentloader:2.3.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.resource:3.0.18",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.models.api:1.3.8",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.models.impl:1.4.10",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.resourceresolver:1.6.8",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.serviceuser.webconsole:1.0.0",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.serviceusermapper:1.4.4",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.servlets.get:2.1.40",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.servlets.post:2.3.30",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.servlets.resolver:2.5.2",
- "start-order":"20"
- },
- {
- "id":"org.apache.sling:org.apache.sling.xss:2.1.8",
- "start-order":"20"
- },
- {
- "id":"org.apache.felix:org.apache.felix.metatype:1.2.2",
- "start-order":"4"
- },
- {
- "id":"org.apache.felix:org.apache.felix.scr:2.1.16",
- "start-order":"4"
- },
- {
- "id":"commons-fileupload:commons-fileupload:1.3.3",
- "start-order":"5"
- },
- {
- "id":"commons-io:commons-io:2.6",
- "start-order":"5"
- },
- {
- "id":"org.apache.aries.jmx:org.apache.aries.jmx.api:1.1.5",
- "start-order":"5"
- },
- {
- "id":"org.apache.aries.jmx:org.apache.aries.jmx.core:1.1.8",
- "start-order":"5"
- },
- {
- "id":"org.apache.aries.jmx:org.apache.aries.jmx.whiteboard:1.2.0",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.bundlerepository:2.0.10",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.http.whiteboard:4.0.0",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.inventory:1.0.6",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.prefs:1.1.0",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.webconsole.plugins.ds:2.1.0",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.webconsole.plugins.event:1.1.8",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.webconsole.plugins.memoryusage:1.0.8",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.webconsole.plugins.obr:1.0.4",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.webconsole.plugins.packageadmin:1.0.4",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.webconsole:4.3.8",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.api:2.20.0",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.auth.core:1.4.2",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.johnzon:1.1.2",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.log.webconsole:1.0.0",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.extensions.threaddump:0.2.2",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.extensions.webconsolebranding:1.0.2",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.extensions.webconsolesecurityprovider:1.2.2",
- "start-order":"5"
- },
- {
- "id":"org.apache.sling:org.apache.sling.starter.content:1.0.4",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.http.sslfilter:1.2.6",
- "start-order":"10"
- },
- {
- "id":"org.apache.pdfbox:fontbox:2.0.16",
- "start-order":"10"
- },
- {
- "id":"org.apache.pdfbox:jempbox:1.8.16",
- "start-order":"10"
- },
- {
- "id":"org.apache.pdfbox:pdfbox:2.0.16",
- "start-order":"10"
- },
- {
- "id":"org.apache.tika:tika-core:1.21",
- "start-order":"10"
- },
- {
- "id":"org.apache.tika:tika-parsers:1.21",
- "start-order":"10"
- },
- {
- "id":"com.google.guava:guava:15.0",
- "start-order":"15"
- },
- {
- "id":"io.dropwizard.metrics:metrics-core:3.2.6",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:jackrabbit-api:2.18.2",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:jackrabbit-data:2.18.2",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:jackrabbit-jcr-commons:2.18.2",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:jackrabbit-jcr-rmi:2.18.2",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:jackrabbit-spi-commons:2.18.2",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:jackrabbit-spi:2.18.2",
- "start-order":"15"
- },
- {
- "id":"org.apache.jackrabbit:jackrabbit-webdav:2.18.2",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.commons.metrics:1.2.6",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.api:2.4.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.base:3.0.6",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.davex:1.3.10",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.jackrabbit.accessmanager:3.0.4",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.jackrabbit.usermanager:2.2.8",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.jcr-wrapper:2.0.0",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.registration:1.0.6",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.webconsole:1.0.2",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.jcr.webdav:2.3.8",
- "start-order":"15"
- },
- {
- "id":"org.apache.sling:org.apache.sling.resource.filter:1.0.0",
- "start-order":"15"
- }
- ],
- "configurations":{
- "org.apache.sling.commons.log.LogManager":{
- "org.apache.sling.commons.log.packagingDataEnabled":true,
- "org.apache.sling.commons.log.pattern":"%d{dd.MM.yyyy HH:mm:ss.SSS} *%level* [%thread] %logger %msg%n",
- "org.apache.sling.commons.log.level":"info",
- "org.apache.sling.commons.log.file":"logs/error.log",
- "org.apache.sling.commons.log.file.number:Integer":"7",
- "org.apache.sling.commons.log.file.size":"'.'yyyy-MM-dd"
- },
- "org.apache.sling.engine.impl.log.RequestLogger":{
- "access.log.enabled":true,
- "request.log.outputtype:Integer":"0",
- "access.log.output":"log.access",
- "request.log.output":"log.request",
- "request.log.enabled":true,
- "access.log.outputtype:Integer":"0"
- },
- "org.apache.sling.jcr.davex.impl.servlets.SlingDavExServlet":{
- "alias":"/server"
- },
- "org.apache.sling.jcr.webdav.impl.servlets.SimpleWebDavServlet":{
- "dav.root":"/dav"
- },
- "org.apache.sling.commons.log.LogManager.factory.config~access.log":{
- "org.apache.sling.commons.log.pattern":"%msg%n",
- "org.apache.sling.commons.log.names":[
- "log.access"
- ],
- "org.apache.sling.commons.log.level":"info",
- "org.apache.sling.commons.log.file":"logs/access.log"
- },
- "org.apache.sling.commons.log.LogManager.factory.config~request.log":{
- "org.apache.sling.commons.log.pattern":"%msg%n",
- "org.apache.sling.commons.log.names":[
- "log.request"
- ],
- "org.apache.sling.commons.log.level":"info",
- "org.apache.sling.commons.log.file":"logs/request.log"
- },
- "org.apache.sling.jcr.base.internal.LoginAdminWhitelist.fragment~sling":{
- "whitelist.bundles":[
- "org.apache.sling.discovery.commons",
- "org.apache.sling.discovery.base",
- "org.apache.sling.discovery.oak",
- "org.apache.sling.extensions.webconsolesecurityprovider",
- "org.apache.sling.i18n",
- "org.apache.sling.jcr.base",
- "org.apache.sling.jcr.contentloader",
- "org.apache.sling.jcr.jackrabbit.usermanager",
- "org.apache.sling.jcr.oak.server",
- "org.apache.sling.jcr.repoinit",
- "org.apache.sling.jcr.webconsole",
- "org.apache.sling.servlets.post",
- "org.apache.sling.serviceuser.webconsole"
- ],
- "whitelist.name":"sling"
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~i18n":{
- "user.mapping":[
- "org.apache.sling.i18n=sling-i18n"
- ]
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~jcr-install":{
- "user.mapping":[
- "org.apache.sling.installer.provider.jcr=sling-jcr-install"
- ]
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~jcr-resource":{
- "user.mapping":[
- "org.apache.sling.jcr.resource:validation=sling-readall"
- ]
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~observation":{
- "user.mapping":[
- "org.apache.sling.jcr.resource:observation=sling-readall"
- ]
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~resourceresolver":{
- "user.mapping":[
- "org.apache.sling.resourceresolver:mapping=sling-mapping",
- "org.apache.sling.resourceresolver:hierarchy=sling-readall",
- "org.apache.sling.resourceresolver:observation=sling-readall",
- "org.apache.sling.resourceresolver:console=sling-readall"
- ]
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~servletsresolver":{
- "user.mapping":[
- "org.apache.sling.servlets.resolver:console=sling-readall",
- "org.apache.sling.servlets.resolver:scripts=sling-scripting"
- ]
- },
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~xss":{
- "user.mapping":[
- "org.apache.sling.xss=sling-xss"
- ]
- }
- }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_slingshot.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_slingshot.json
deleted file mode 100644
index 1628f03..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_slingshot.json
+++ /dev/null
@@ -1,39 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling_slingshot:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.sling:org.apache.sling.sample.slingshot:0.9.0",
- "start-order":"20"
- }
- ],
- "configurations":{
- "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~sling.slingshot":{
- "user.mapping":[
- "org.apache.sling.sample.slingshot=slingshot-service"
- ]
- }
- },
- "repoinit:TEXT|true":[
- "create service user slingshot-service",
- "create user slingshot1 with password slingshot1",
- "create user slingshot2 with password slingshot2",
- "",
- "create path (sling:Folder) /content/slingshot",
- "create path (sling:Folder) /content/slingshot/users",
- "create path (sling:Folder) /content/slingshot/users/slingshot1",
- "create path (sling:Folder) /content/slingshot/users/slingshot2",
- "",
- "set ACL for slingshot-service",
- "allow jcr:read,rep:write on /content/slingshot",
- "end",
- "",
- "set ACL for slingshot1",
- "allow jcr:read,rep:write on /content/slingshot/users/slingshot1",
- "end",
- "",
- "set ACL for slingshot2",
- "allow jcr:read,rep:write on /content/slingshot/users/slingshot2",
- "end"
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/standalone_standalone.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/standalone_standalone.json
deleted file mode 100644
index 4bf9d52..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/standalone_standalone.json
+++ /dev/null
@@ -1,16 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:standalone:12-SNAPSHOT",
- "bundles":[
- {
- "id":"org.apache.felix:org.apache.felix.http.jetty:4.0.8",
- "run-modes":":standalone",
- "start-order":"5"
- },
- {
- "id":"org.apache.felix:org.apache.felix.http.servlet-api:1.1.2",
- "run-modes":":standalone",
- "start-order":"5"
- }
- ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/webapp_webapp.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/webapp_webapp.json
deleted file mode 100644
index 94fe38e..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/webapp_webapp.json
+++ /dev/null
@@ -1,4 +0,0 @@
-
-{
- "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:webapp:12-SNAPSHOT"
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-starter/Readme.md b/sling-org-apache-sling-feature-starter/Readme.md
new file mode 100644
index 0000000..cf65ebd
--- /dev/null
+++ b/sling-org-apache-sling-feature-starter/Readme.md
@@ -0,0 +1,23 @@
+# Sling Feature Starter
+
+This project is the Feature Model based version of the **sling-org-apache-sling-starter**
+module and creates an executable JAR file for now.
+It is also a test case for the Slingstart Feature Maven Plugin.
+
+## Build
+
+This plugin depends on the **Sling Start Maven Plugin** (also in the Sling
+Whiteboard) which is for now extracted in its own profile **launch**:
+
+1. Go to **sling-slingstart-feature-maven-plugin** module in Sling Whiteboard
+2. Build with: `mvn clean install`
+3. Go back to **sling-org-apache-sling-feature-starter**
+4. Build and Launch it with: `mvn clean install -P launch`
+5. Sling will come up and is accessible on the temporary port but the build
+will not end
+
+## Issues
+
+This module must be able to launch Sling in a demon (background) thread
+so that the starter can exit. The question is if that is added here or to
+the Feature Launcher module.
diff --git a/sling-org-apache-sling-feature-starter/pom.xml b/sling-org-apache-sling-feature-starter/pom.xml
index 0189bc3..593e430 100644
--- a/sling-org-apache-sling-feature-starter/pom.xml
+++ b/sling-org-apache-sling-feature-starter/pom.xml
@@ -32,18 +32,33 @@
<sling.java.version>8</sling.java.version>
<picocli.version>3.6.0</picocli.version>
<appassembler-maven-plugin.version>2.0.0</appassembler-maven-plugin.version>
+ <org.apache.sling.feature.extension.content.version>1.0.4</org.apache.sling.feature.extension.content.version>
+ <org.apache.sling.feature.launcher.version>1.1.0</org.apache.sling.feature.launcher.version>
+ <org.apache.sling.feature.io.version>1.1.0</org.apache.sling.feature.io.version>
+ <org.apache.felix.converter.version>1.0.8</org.apache.felix.converter.version>
</properties>
<!-- <scm>-->
-<!-- <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git</connection>-->
-<!-- <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git</developerConnection>-->
-<!-- <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-feature-launcher.git</url>-->
+<!-- <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-starter.git</connection>-->
+<!-- <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-starter.git</developerConnection>-->
+<!-- <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-feature-starter.git</url>-->
<!-- <tag>HEAD</tag>-->
<!-- </scm>-->
<build>
<plugins>
<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>ianal-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>verify-legal-files</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
@@ -131,22 +146,22 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.feature.extension.content</artifactId>
- <version>1.0.4</version>
+ <version>${org.apache.sling.feature.extension.content.version}</version>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.feature.launcher</artifactId>
- <version>1.1.0</version>
+ <version>${org.apache.sling.feature.launcher.version}</version>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.feature.io</artifactId>
- <version>1.1.0</version>
+ <version>${org.apache.sling.feature.io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.converter</artifactId>
- <version>1.0.8</version>
+ <version>${org.apache.felix.converter.version}</version>
</dependency>
<dependency>
@@ -168,4 +183,61 @@
<scope>test</scope>
</dependency>
</dependencies>
+ <profiles>
+ <profile>
+ <id>launch</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>reserve-network-port</id>
+ <goals>
+ <!-- pre-integration-test is too late -->
+ <goal>reserve-network-port</goal>
+ </goals>
+ <phase>process-resources</phase>
+ <configuration>
+ <portNames>
+ <portName>http.port</portName>
+ <portName>sling.control.port</portName>
+ </portNames>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>slingstart-feature-maven-plugin</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <id>start-container</id>
+ <goals>
+ <goal>start</goal>
+ <goal>stop</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <launchpadJar>${project.build.directory}/${project.artifactId}-${project.version}.jar</launchpadJar>
+ <parallelExecution>false</parallelExecution>
+<!-- <createWebapp>false</createWebapp>-->
+ <servers>
+ <server>
+ <port>${http.port}</port>
+ <controlPort>${sling.control.port}</controlPort>
+ <debug>true</debug>
+ <stdOutFile>launchpad.out</stdOutFile>
+ </server>
+ </servers>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
diff --git a/sling-org-apache-sling-feature-starter/src/main/resources/feature-sling12.json b/sling-org-apache-sling-feature-starter/src/main/resources/feature-sling12.json
index c847732..85b68c4 100644
--- a/sling-org-apache-sling-feature-starter/src/main/resources/feature-sling12.json
+++ b/sling-org-apache-sling-feature-starter/src/main/resources/feature-sling12.json
@@ -1023,7 +1023,7 @@
"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling_slingshot:12-SNAPSHOT",
"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:standalone:12-SNAPSHOT",
"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:webapp:12-SNAPSHOT",
- "org.apache.sling:org.apache.sling.jcr.packageinit:slingosgifeature:0.0.1-SNAPSHOT"
+ "org.apache.sling:org.apache.sling.jcr.packageinit:slingosgifeature:jcr-packageinit:0.0.1-SNAPSHOT"
],
"repoinit:TEXT|true":[
"# general",
diff --git a/sling-slingstart-feature-maven-plugin/Readme.md b/sling-slingstart-feature-maven-plugin/Readme.md
new file mode 100644
index 0000000..fea9136
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/Readme.md
@@ -0,0 +1,51 @@
+# Sling Start Feature Maven Plugin
+
+This Maven Plugin is the Feature Model based version of the Slingstart
+Maven Plugin. It does not depend on the predecessor to keep the PM and FM
+based code base separate.
+
+## Build
+
+This plugin is built like usual with:
+```
+mvn clean install
+```
+
+## Usage
+
+The plugin can be used (see **sling-org-apache-sling-feature-starter**
+module in Sling Whiteboard) like this:
+```
+<plugin>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>slingstart-feature-maven-plugin</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <id>start-container</id>
+ <goals>
+ <goal>start</goal>
+ <goal>stop</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <launchpadJar>${project.build.directory}/${project.artifactId}-${project.version}.jar</launchpadJar>
+ <parallelExecution>false</parallelExecution>
+ <servers>
+ <server>
+ <port>${http.port}</port>
+ <controlPort>${sling.control.port}</controlPort>
+ <debug>true</debug>
+ <stdOutFile>launchpad.out</stdOutFile>
+ </server>
+ </servers>
+ </configuration>
+</plugin>
+```
+
+## Issues
+
+The Feature Launcher does not support to be started in the background and
+so this plugin will be not end the build when Sling is started.
diff --git a/sling-slingstart-feature-maven-plugin/pom.xml b/sling-slingstart-feature-maven-plugin/pom.xml
new file mode 100644
index 0000000..2b6891e
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/pom.xml
@@ -0,0 +1,348 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>35</version>
+ <relativePath />
+ </parent>
+
+ <artifactId>slingstart-feature-maven-plugin</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Apache Sling SlingStart Feature Maven Plugin</name>
+ <description>
+ Maven Plugin supporting Sling Feature Launchpad
+ </description>
+ <url>https://sling.apache.org/components/slingstart-maven-plugin/</url>
+
+ <properties>
+ <maven.version>3.0.5</maven.version>
+ <maven.site.path>${project.artifactId}-archives/${project.artifactId}-LATEST</maven.site.path>
+ <sling.java.version>8</sling.java.version>
+ <org.apache.sling.feature.extension.content.version>1.0.4</org.apache.sling.feature.extension.content.version>
+ <org.apache.sling.feature.launcher.version>1.1.0</org.apache.sling.feature.launcher.version>
+ <org.apache.sling.feature.io.version>1.1.0</org.apache.sling.feature.io.version>
+ <org.apache.felix.converter.version>1.0.8</org.apache.felix.converter.version>
+ <org.apache.sling.feature.starter.version>0.0.1-SNAPSHOT</org.apache.sling.feature.starter.version>
+ <org.apache.sling.feature.version>1.1.0</org.apache.sling.feature.version>
+ <org.apache.sling.feature.analyser.version>1.1.0</org.apache.sling.feature.analyser.version>
+ <org.apache.sling.feature.modelconverter.version>1.0.8</org.apache.sling.feature.modelconverter.version>
+ </properties>
+
+<!-- <scm>-->
+<!-- <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-slingstart-maven-plugin.git</connection>-->
+<!-- <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-slingstart-maven-plugin.git</developerConnection>-->
+<!-- <url>https://gitbox.apache.org/repos/asf?p=sling-slingstart-maven-plugin.git</url>-->
+<!-- <tag>HEAD</tag>-->
+<!-- </scm>-->
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>enforce-java</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireJavaVersion>
+ <message>${project.name} must be compiled with Java 1.8 or higher.</message>
+ <version>1.${sling.java.version}.0</version>
+ </requireJavaVersion>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ <version>1.7.1</version>
+ <executions>
+ <execution>
+ <id>generate-metadata</id>
+ <goals>
+ <goal>generate-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>mojo-descriptor</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>generated-helpmojo</id>
+ <goals>
+ <goal>helpmojo</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-scm-publish-plugin</artifactId>
+ <configuration>
+ <checkoutDirectory>${user.home}/maven-sites/${maven.site.path}</checkoutDirectory>
+ <tryUpdate>true</tryUpdate>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>src/site/markdown/**</exclude>
+ <exclude>src/test/resources/**</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <!-- for https://issues.apache.org/jira/browse/SUREFIRE-1067 -->
+ <version>2.20.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <!-- for https://issues.apache.org/jira/browse/SUREFIRE-855 -->
+ <version>2.20.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <systemPropertyVariables>
+ <project.version>${project.version}</project.version>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+<!-- <dependency>-->
+<!-- <groupId>org.apache.sling</groupId>-->
+<!-- <artifactId>org.apache.sling.provisioning.model</artifactId>-->
+<!-- <version>1.8.4</version>-->
+<!-- </dependency>-->
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.feature.starter</artifactId>
+ <version>${org.apache.sling.feature.starter.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.feature</artifactId>
+ <version>${org.apache.sling.feature.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.feature.analyser</artifactId>
+ <version>${org.apache.sling.feature.analyser.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.feature.modelconverter</artifactId>
+ <version>${org.apache.sling.feature.modelconverter.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.feature.io</artifactId>
+ <version>${org.apache.sling.feature.io.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>3.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- for converting Maven to OSGi versions -->
+ <dependency>
+ <groupId>biz.aQute.bnd</groupId>
+ <artifactId>biz.aQute.bndlib</artifactId>
+ <version>4.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interactivity-api</artifactId>
+ <version>1.0-alpha-6</version>
+ </dependency>
+ <!-- We use a class from the config admin implementation to read config files -->
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.configadmin</artifactId>
+ <version>1.8.10</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.converter</artifactId>
+ <version>1.0.10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.configurator</artifactId>
+ <version>1.0.10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.johnzon</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-archiver</artifactId>
+ <version>2.4.4</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>3.0.17</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-filtering</artifactId>
+ <version>1.2</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>maven-project</artifactId>
+ <groupId>org.apache.maven</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.osgi</artifactId>
+ <version>2.4.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- The following artifacts are purely used by the unit tests
+ so these dependencies ensures that they are in the .m2 directory prior to executing the tests.
+ Whenever you modify these, you must also modify the references in org.apache.sling.maven.slingstart.PreparePackageMojoTest! -->
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.classloader</artifactId>
+ <version>1.3.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.contentdetection</artifactId>
+ <version>1.0.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.mime</artifactId>
+ <version>2.1.8</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.threads</artifactId>
+ <version>3.2.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+
+</project>
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/BuildConstants.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/BuildConstants.java
new file mode 100644
index 0000000..94161f3
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/BuildConstants.java
@@ -0,0 +1,105 @@
+/*
+ * 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.maven.slingstart.feature;
+
+//import org.apache.sling.provisioning.model.ModelConstants;
+//import org.apache.sling.provisioning.model.io.ModelArchiveWriter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class BuildConstants {
+
+ // CONTEXTS
+ public static final String CONTEXT_GLOBAL = "slingstart:global";
+// public static final String CONTEXT_STANDALONE = "slingstart" + ModelConstants.RUN_MODE_STANDALONE;
+// public static final String CONTEXT_WEBAPP = "slingstart" + ModelConstants.RUN_MODE_WEBAPP;
+ public static final String CONTEXT_STANDALONE = "slingstart" + ":standalone";
+ public static final String CONTEXT_WEBAPP = "slingstart" + ":webapp";
+
+ // Model artifact name
+ public static final String MODEL_ARTIFACT_NAME = "slingstart.txt";
+
+ // Types
+
+ public static final String TYPE_JAR = "jar";
+
+ public static final String TYPE_WAR = "war";
+
+ public static final String TYPE_POM = "pom";
+
+ public static final String TYPE_TXT = "txt";
+
+ public static final String PACKAGING_PARTIAL_SYSTEM = "slingfeature";
+
+ public static final String PACKAGING_SLINGSTART = "slingstart";
+
+ // Classifiers
+
+ public static final String CLASSIFIER_PARTIAL_SYSTEM = "slingfeature";
+
+ public static final String CLASSIFIER_BASE = "base";
+
+ public static final String CLASSIFIER_APP = "app";
+
+ public static final String CLASSIFIER_WEBAPP = "webapp";
+
+// public static final String CLASSIFIER_MAR = ModelArchiveWriter.DEFAULT_EXTENSION;
+
+ // Manifest attributes
+
+ public static final String ATTR_BUILT_BY = "Built-By";
+
+ public static final String ATTR_CREATED_BY = "Created-By";
+
+ public static final String ATTR_IMPLEMENTATION_VERSION = "Implementation-Version";
+
+ public static final String ATTR_IMPLEMENTATION_VENDOR = "Implementation-Vendor";
+
+ public static final String ATTR_IMPLEMENTATION_BUILD = "Implementation-Build";
+
+ public static final String ATTR_IMPLEMENTATION_VENDOR_ID = "Implementation-Vendor-Id";
+
+ public static final String ATTR_IMPLEMENTATION_TITLE = "Implementation-Title";
+
+ public static final String ATTR_SPECIFICATION_TITLE = "Specification-Title";
+
+ public static final String ATTR_SPECIFICATION_VENDOR = "Specification-Vendor";
+
+ public static final String ATTR_SPECIFICATION_VERSION = "Specification-Version";
+
+ public static final String ATTR_MAIN_CLASS = "Main-Class";
+
+ public static final String ATTR_VALUE_MAIN_CLASS = "org.apache.sling.launchpad.app.Main";
+
+ public static final List<String> ATTRS_EXCLUDES = new ArrayList<String>();
+ static {
+ ATTRS_EXCLUDES.add(ATTR_BUILT_BY);
+ ATTRS_EXCLUDES.add(ATTR_CREATED_BY);
+ ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_VERSION);
+ ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_VENDOR);
+ ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_BUILD);
+ ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_VENDOR_ID);
+ ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_TITLE);
+ ATTRS_EXCLUDES.add(ATTR_SPECIFICATION_TITLE);
+ ATTRS_EXCLUDES.add(ATTR_SPECIFICATION_VENDOR);
+ ATTRS_EXCLUDES.add(ATTR_SPECIFICATION_VERSION);
+ }
+
+ // build constants
+ public static final String WEBAPP_OUTDIR = "slingstart-webapp";
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Launcher.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Launcher.java
new file mode 100644
index 0000000..668756c
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Launcher.java
@@ -0,0 +1,96 @@
+/*
+ * 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.maven.slingstart.feature.launcher;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Launcher implements LauncherMBean {
+
+ private final int listenerPort;
+
+ public Launcher(final int listenerPort) {
+ this.listenerPort = listenerPort;
+ }
+
+ @Override
+ public void startupFinished() {
+ final List<String> hosts = new ArrayList<String>();
+ hosts.add("localhost");
+ hosts.add("127.0.0.1");
+
+ boolean done = false;
+ int index = 0;
+ while ( !done && index < hosts.size() ) {
+ final String hostName = hosts.get(index);
+ final int twoMinutes = 2 * 60 * 1000;
+
+ Socket clientSocket = null;
+ DataOutputStream out = null;
+ BufferedReader in = null;
+ try {
+ clientSocket = new Socket();
+ clientSocket.connect(new InetSocketAddress(hostName, listenerPort), twoMinutes);
+ // without that, read() call on the InputStream associated with this Socket is infinite
+ clientSocket.setSoTimeout(twoMinutes);
+
+ out = new DataOutputStream(clientSocket.getOutputStream());
+ in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+ out.writeBytes("started\n");
+ in.readLine();
+ done = true;
+ } catch (final Throwable ignore) {
+ // catch Throwable because InetSocketAddress and Socket#connect throws unchecked exceptions
+ // we ignore this for now
+ } finally {
+ if ( in != null ) {
+ try {
+ in.close();
+ } catch ( final IOException ioe) {
+ // ignore
+ }
+ }
+ if ( out != null ) {
+ try {
+ out.close();
+ } catch ( final IOException ioe) {
+ // ignore
+ }
+ }
+ if ( clientSocket != null ) {
+ try {
+ clientSocket.close();
+ } catch (final IOException e) {
+ // ignore
+ }
+ }
+ }
+ index++;
+ }
+ }
+
+ @Override
+ public void startupProgress(Float ratio) {
+ // nothing to do
+ }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/LauncherMBean.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/LauncherMBean.java
new file mode 100644
index 0000000..a221885
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/LauncherMBean.java
@@ -0,0 +1,34 @@
+/*
+ * 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.maven.slingstart.feature.launcher;
+
+/**
+ * The launcher MBean interface.
+ */
+public interface LauncherMBean {
+
+ /**
+ * Notify the launcher about the finish of the startup.
+ */
+ void startupFinished();
+
+ /**
+ * Notify the launcher about the progress of the startup.
+ * @param ratio Startup progress ratio
+ */
+ void startupProgress(Float ratio);
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Main.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Main.java
new file mode 100644
index 0000000..9db0523
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Main.java
@@ -0,0 +1,113 @@
+/*
+ * 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.maven.slingstart.feature.launcher;
+
+import aQute.bnd.build.Run;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.io.File;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+
+/**
+ * Main class for launching Apache Sling.
+ *
+ */
+public class Main {
+
+ /** Arguments to pass to the real main class */
+ private final String[] startupArgs;
+
+ /** Verbose flag */
+ private final boolean verbose;
+
+ /** App jar */
+ private final File appJar;
+
+ /** Listener port. */
+ private final int listenerPort;
+
+ /** Main class default value */
+ private final static String MAIN_CLASS_DEF = "org.apache.sling.feature.starter.app.SlingStarter";
+
+ /** Delimeter string */
+ private final static String DELIM =
+ "-------------------------------------------------------------------";
+
+ /**
+ * Create a new launcher
+ * First argument is the launchpad jar
+ * Second argument is the listener port
+ * Third argument is verbose
+ */
+ public Main(final String[] args) {
+ if ( args == null || args.length < 3 ) {
+ throw new IllegalArgumentException("Missing configuration: " + args);
+ }
+ this.appJar = new File(args[0]);
+ this.listenerPort = Integer.valueOf(args[1]);
+ this.verbose = Boolean.valueOf(args[2]);
+ System.out.println("App Jar: " + appJar);
+ System.out.println("Listener Port: " + listenerPort);
+ System.out.println("Verbose: " + verbose);
+ this.startupArgs = new String[args.length-3];
+ System.arraycopy(args, 3, this.startupArgs, 0, this.startupArgs.length);
+ }
+
+ /**
+ * Startup
+ */
+ public void run() throws Exception {
+ if (verbose) {
+ System.out.println(DELIM);
+ System.out.println("Slingstart application: " + this.appJar);
+ System.out.println("Main class: " + MAIN_CLASS_DEF);
+ System.out.println("Listener Port: " + String.valueOf(this.listenerPort));
+ System.out.println("Arguments: " + Arrays.toString(this.startupArgs));
+ System.out.println(DELIM);
+ }
+
+ final ClassLoader cl = new URLClassLoader(new URL[] {this.appJar.toURI().toURL()});
+ Thread.currentThread().setContextClassLoader(cl);
+
+ // create and register mbean
+ final MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
+ jmxServer.registerMBean(new Launcher(this.listenerPort),
+ new ObjectName("org.apache.sling.feature.launchpad:type=Launcher"));
+
+ final Class<?> mainClass = cl.loadClass(MAIN_CLASS_DEF);
+ final Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);
+ mainMethod.invoke(null, (Object)this.startupArgs);
+ }
+
+ public static void main(final String[] args) {
+ try {
+ final Main m = new Main(args);
+ m.run();
+ } catch(RuntimeException e) {
+ throw e;
+ } catch ( final Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
+
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/AbstractStartStopMojo.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/AbstractStartStopMojo.java
new file mode 100644
index 0000000..2970289
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/AbstractStartStopMojo.java
@@ -0,0 +1,82 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.codehaus.plexus.components.interactivity.Prompter;
+import org.codehaus.plexus.components.interactivity.PrompterException;
+
+import java.io.File;
+import java.util.List;
+
+public abstract class AbstractStartStopMojo extends AbstractMojo {
+
+ /**
+ * Set this to "true" to skip starting the launchpad
+ */
+ @Parameter(property = "maven.test.skip", defaultValue = "false")
+ protected boolean skipLaunchpad;
+
+ /**
+ * Parameter containing the list of server configurations
+ */
+ @Parameter
+ protected List<ServerConfiguration> servers;
+
+ /**
+ * The system properties file will contain all started instances with their ports etc.
+ */
+ @Parameter(defaultValue = "${project.build.directory}/launchpad-runner.properties")
+ protected File systemPropertiesFile;
+
+ /**
+ * If {@code true} this mojo blocks until you press the Enter key.
+ */
+ @Parameter
+ protected boolean shouldBlockUntilKeyIsPressed;
+
+ @Component
+ private Prompter prompter;
+
+ protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (this.skipLaunchpad) {
+ this.getLog().info("Executing of this mojo is disabled by configuration.");
+ return;
+ }
+
+ doExecute();
+ }
+
+ protected void blockIfNecessary() throws MojoFailureException {
+ if (shouldBlockUntilKeyIsPressed) {
+ // http://stackoverflow.com/a/21977269/5155923
+ try {
+ prompter.prompt("Press Enter to continue");
+ } catch (PrompterException e) {
+ throw new MojoFailureException("Could not prompt for user input. Maven is probably running in non-interactive mode! Do not use parameter 'shouldBlockUntilKeyIsPressed' in that case", e);
+ }
+ }
+
+ }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ControlListener.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ControlListener.java
new file mode 100644
index 0000000..0202a91
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ControlListener.java
@@ -0,0 +1,160 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/**
+ * Control listener.
+ * This class listens for the startup of a launchpad instance.
+ */
+public class ControlListener implements Runnable {
+
+ // command sent by the client to notify startup
+ private static final String COMMAND_STARTED = "started";
+
+ private static final String RESPONSE_OK = "ok";
+
+ // The default interface to listen on
+ private static final String DEFAULT_LISTEN_INTERFACE = "127.0.0.1";
+
+ // The port to listen on
+ private final int port;
+
+ private volatile boolean started = false;
+
+ private volatile boolean stopped = false;
+
+ private volatile ServerSocket server;
+
+ public ControlListener(final int p) {
+ this.port = p;
+ final Thread listener = new Thread(this);
+ listener.setDaemon(true);
+ listener.setName("Launchapd startup listener");
+ listener.start();
+ }
+
+ public int getPort() {
+ return this.port;
+ }
+
+ public boolean isStarted() {
+ return this.started;
+ }
+
+ public void stop() {
+ stopped = true;
+ if ( server != null ) {
+ try {
+ server.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Implements the server thread receiving commands from clients and acting
+ * upon them.
+ */
+ @Override
+ public void run() {
+ final InetSocketAddress socketAddress = getSocketAddress(this.port);
+ try {
+ server = new ServerSocket();
+ server.bind(socketAddress);
+ } catch (final IOException ioe) {
+ return;
+ }
+
+ try {
+ while (!stopped) {
+
+ final Socket s = server.accept();
+
+ try {
+ final String commandLine = readLine(s);
+ if (commandLine == null) {
+ final String msg = "ERR: missing command";
+ writeLine(s, msg);
+ continue;
+ }
+
+ final String command = commandLine;
+
+ if (COMMAND_STARTED.equals(command)) {
+ writeLine(s, RESPONSE_OK);
+ this.started = true;
+ this.stopped = true;
+ break;
+
+ } else {
+ final String msg = "ERR:" + command;
+ writeLine(s, msg);
+
+ }
+ } finally {
+ try {
+ s.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+ } catch (final IOException ioe) {
+ // ignore
+ } finally {
+ try {
+ server.close();
+ } catch (final IOException ignore) {
+ // ignore
+ }
+ }
+ }
+
+ private String readLine(final Socket socket) throws IOException {
+ final BufferedReader br = new BufferedReader(new InputStreamReader(
+ socket.getInputStream(), "UTF-8"));
+ return br.readLine();
+ }
+
+ private void writeLine(final Socket socket, final String line) throws IOException {
+ final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
+ socket.getOutputStream(), "UTF-8"));
+ bw.write(line);
+ bw.write("\r\n");
+ bw.flush();
+ }
+
+ private static InetSocketAddress getSocketAddress(final int port) {
+ final String address = DEFAULT_LISTEN_INTERFACE;
+
+ final InetSocketAddress addr = new InetSocketAddress(address, port);
+ if (!addr.isUnresolved()) {
+ return addr;
+ }
+
+ return null;
+ }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LauncherCallable.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LauncherCallable.java
new file mode 100644
index 0000000..d05c4e4
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LauncherCallable.java
@@ -0,0 +1,369 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.shared.utils.StringUtils;
+import org.apache.sling.maven.slingstart.feature.launcher.Main;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.lang.ProcessBuilder.Redirect;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A callable for launchpad an instance
+ */
+public class LauncherCallable implements Callable<ProcessDescription> {
+
+ private final LaunchpadEnvironment environment;
+ private final ServerConfiguration configuration;
+ private final Log logger;
+
+ public LauncherCallable(final Log logger,
+ final ServerConfiguration configuration,
+ final LaunchpadEnvironment environment) {
+ this.logger = logger;
+ this.configuration = configuration;
+ this.environment = environment;
+ }
+
+ /**
+ * @see Callable#call()
+ */
+ @Override
+ public ProcessDescription call() throws Exception {
+
+ // fail if launchpad with this id is already started
+ if (!ProcessDescriptionProvider.getInstance().isRunConfigurationAvailable(configuration.getId())) {
+ throw new Exception("Launchpad with id " + configuration.getId() + " is not available");
+ }
+
+ // get the launchpad jar
+ final File launchpad = this.environment.prepare(this.configuration.getFolder());
+
+ // Lock the launchpad id
+ final String launchpadKey = ProcessDescriptionProvider.getInstance().getId(configuration.getId());
+
+ // start launchpad
+ ProcessDescription cfg = this.start(launchpad);
+
+ // Add thread hook to shutdown launchpad
+ if (environment.isShutdownOnExit()) {
+ cfg.installShutdownHook();
+ }
+
+ // Add configuration to the config provider
+ ProcessDescriptionProvider.getInstance().addRunConfiguration(cfg, launchpadKey);
+
+ boolean started = false;
+ try {
+ final long endTime = System.currentTimeMillis() + this.environment.getReadyTimeOutSec() * 1000;
+ boolean finished = false;
+ while ( !started && !finished && System.currentTimeMillis() < endTime ) {
+ Thread.sleep(5000);
+ started = cfg.getControlListener().isStarted();
+ try {
+ // if we get an exit value, the process has stopped
+ cfg.getProcess().exitValue();
+ finished = true;
+ } catch ( final IllegalThreadStateException itse) {
+ // everything as expected
+ }
+
+ }
+
+ if ( finished ) {
+ throw new Exception("Launchpad did exit unexpectedly.");
+ }
+ if ( !started ) {
+ throw new Exception("Launchpad did not start successfully in " + this.environment.getReadyTimeOutSec() + " seconds.");
+ }
+ // now check for the availability of the HTTP port
+ boolean httpAvailable = isLocalhostPortAvailable(Integer.valueOf(this.configuration.getPort()));
+ // repeat until http service is up as well
+ while ( !httpAvailable && System.currentTimeMillis() < endTime ) {
+ Thread.sleep(1000);
+ httpAvailable = isLocalhostPortAvailable(Integer.valueOf(this.configuration.getPort()));
+ }
+ if ( !httpAvailable ) {
+ throw new Exception("Launchpad did not start http service on port " + this.configuration.getPort() + " successfully in " + this.environment.getReadyTimeOutSec() + " seconds.");
+ }
+ this.logger.info("Started Launchpad '" + configuration.getId() +
+ "' at port " + configuration.getPort()+ " [run modes: " + configuration.getRunmode()+ "]");
+ } finally {
+ // stop control port
+ cfg.getControlListener().stop();
+
+ // call launchpad stop routine if not properly started
+ if (!started) {
+ stop(this.logger, cfg);
+ ProcessDescriptionProvider.getInstance().removeRunConfiguration(cfg.getId());
+ cfg = null;
+ }
+ }
+
+ return cfg;
+ }
+
+ private boolean isLocalhostPortAvailable(int port) throws IOException {
+ // https://stackoverflow.com/questions/46436813/difference-between-a-connection-refused-exception-and-a-timeout-in-httpclient
+ Socket clientSocket = new Socket();
+ try {
+ clientSocket.connect(new InetSocketAddress("127.0.0.1", port), 500);
+ // without that, read() call on the InputStream associated with this Socket is infinite
+ this.logger.debug("Successfully connected to localhost, port " + port);
+ clientSocket.close();
+ return true;
+ } catch (SocketTimeoutException e) {
+ // we ran into a timeout (port most probably blocked by firewall)
+ this.logger.debug("Ran into a timeout while connecting to localhost, port " + port, e);
+ return false;
+ } catch (ConnectException e) {
+ // port not bound
+ this.logger.debug("Could not connect to localhost, port " + port, e);
+ return false;
+ } finally {
+ clientSocket.close();
+ }
+ }
+
+ public boolean isRunning() {
+ return getControlPortFile(this.configuration.getFolder()).exists();
+ }
+
+ private void add(final List<String> args, final String value) {
+ if ( value != null ) {
+ final String[] single = value.trim().split(" ");
+ for(final String v : single) {
+ if ( v.trim().length() > 0 ) {
+ args.add(v.trim());
+ }
+ }
+ }
+ }
+
+ private ProcessDescription start(final File jar) throws Exception {
+ final ProcessDescription cfg = new ProcessDescription(this.configuration.getId(), this.configuration.getFolder());
+
+ final ProcessBuilder builder = new ProcessBuilder();
+ final List<String> args = new ArrayList<String>();
+
+ String javaHome = System.getenv("JAVA_HOME");
+ String javaCmd = javaHome != null ? Paths.get(javaHome, "bin", "java").toString() : "java";
+
+ args.add(javaCmd);
+ add(args, this.configuration.getVmOpts());
+ add(args, this.configuration.getVmDebugOpts(this.environment.getDebug()));
+
+ args.add("-cp");
+ args.add("bin");
+ args.add(Main.class.getName());
+ // first three arguments: jar, listener port, verbose
+ args.add(jar.getPath());
+ args.add(String.valueOf(cfg.getControlListener().getPort()));
+ args.add("true");
+
+ // from here on launchpad properties
+ add(args, this.configuration.getOpts());
+
+ final String contextPath = this.configuration.getContextPath();
+ if ( contextPath != null && contextPath.length() > 0 && !contextPath.equals("/") ) {
+ args.add("-r");
+ args.add(contextPath);
+ }
+
+ if ( this.configuration.getPort() != null ) {
+ args.add("-p");
+ args.add(this.configuration.getPort());
+ }
+
+ if ( this.configuration.getControlPort() != null ) {
+ args.add("-j");
+ args.add(this.configuration.getControlPort());
+ }
+ if ( this.configuration.getRunmode() != null && this.configuration.getRunmode().length() > 0 ) {
+ args.add("-Dsling.run.modes=" + this.configuration.getRunmode());
+ }
+ if ( !this.environment.isShutdownOnExit() ) {
+ args.add("start");
+ }
+
+ builder.command(args.toArray(new String[args.size()]));
+ builder.directory(this.configuration.getFolder());
+ builder.redirectErrorStream(true);
+ logger.info("Starting Launchpad " + this.configuration.getId() + "...");
+ String stdOutFile = this.configuration.getStdOutFile();
+ if (StringUtils.isNotBlank(stdOutFile)) {
+ File absoluteStdOutFile = new File(builder.directory(), stdOutFile);
+ // make sure to create the parent directories (if they do not exist yet)
+ absoluteStdOutFile.getParentFile().mkdirs();
+ builder.redirectOutput(absoluteStdOutFile);
+ logger.info("Redirecting stdout and stderr to " + absoluteStdOutFile);
+ } else {
+ builder.redirectOutput(Redirect.INHERIT);
+ }
+
+ logger.debug("Launchpad cmd: " + builder.command());
+ logger.debug("Launchpad dir: " + builder.directory());
+
+ try {
+ logger.info("Before Builder start()");
+ cfg.setProcess(builder.start());
+ logger.info("After Builder start(), cfg: " + cfg);
+ } catch (final IOException e) {
+ if (cfg.getProcess() != null) {
+ cfg.getProcess().destroy();
+ cfg.setProcess(null);
+ }
+ throw new Exception("Could not start the Launchpad", e);
+ }
+
+ return cfg;
+ }
+
+ public static void stop(final Log LOG, final ProcessDescription cfg) throws Exception {
+ boolean isNew = false;
+
+ if (cfg.getProcess() != null || isNew ) {
+ LOG.info("Stopping Launchpad '" + cfg.getId() + "'");
+ boolean destroy = true;
+ final int twoMinutes = 2 * 60 * 1000;
+ final File controlPortFile = getControlPortFile(cfg.getDirectory());
+ LOG.debug("Control port file " + controlPortFile + " exists: " + controlPortFile.exists());
+ if ( controlPortFile.exists() ) {
+ // reading control port
+ int controlPort = -1;
+ String secretKey = null;
+ LineNumberReader lnr = null;
+ String serverName = null;
+ try {
+ lnr = new LineNumberReader(new FileReader(controlPortFile));
+ final String portLine = lnr.readLine();
+ final int pos = portLine.indexOf(':');
+ controlPort = Integer.parseInt(portLine.substring(pos + 1));
+ if ( pos > 0 ) {
+ serverName = portLine.substring(0, pos);
+ }
+ secretKey = lnr.readLine();
+ } catch ( final NumberFormatException ignore) {
+ // we ignore this
+ LOG.debug("Error reading control port file " + controlPortFile, ignore);
+ } catch ( final IOException ignore) {
+ // we ignore this
+ LOG.debug("Error reading control port file " + controlPortFile, ignore);
+ } finally {
+ IOUtils.closeQuietly(lnr);
+ }
+
+ if ( controlPort != -1 ) {
+ final List<String> hosts = new ArrayList<String>();
+ if ( serverName != null ) {
+ hosts.add(serverName);
+ }
+ hosts.add("localhost");
+ hosts.add("127.0.0.1");
+ LOG.debug("Found control port " + controlPort);
+ int index = 0;
+ while ( destroy && index < hosts.size() ) {
+ final String hostName = hosts.get(index);
+
+ Socket clientSocket = null;
+ DataOutputStream out = null;
+ BufferedReader in = null;
+ try {
+ LOG.debug("Trying to connect to " + hostName + ":" + controlPort);
+ clientSocket = new Socket();
+ // set a socket timeout
+ clientSocket.connect(new InetSocketAddress(hostName, controlPort), twoMinutes);
+ // without that, read() call on the InputStream associated with this Socket is infinite
+ clientSocket.setSoTimeout(twoMinutes);
+
+ LOG.debug(hostName + ":" + controlPort + " connection estabilished, sending the 'stop' command...");
+
+ out = new DataOutputStream(clientSocket.getOutputStream());
+ in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+ if (secretKey != null) {
+ out.writeBytes(secretKey);
+ out.write(' ');
+ }
+ out.writeBytes("stop\n");
+ in.readLine();
+ destroy = false;
+ LOG.debug("'stop' command sent to " + hostName + ":" + controlPort);
+ } catch (final Throwable ignore) {
+ // catch Throwable because InetSocketAddress and Socket#connect throws unchecked exceptions
+ // we ignore this for now
+ LOG.debug("Error sending 'stop' command to " + hostName + ":" + controlPort + " due to: " + ignore.getMessage());
+ } finally {
+ IOUtils.closeQuietly(in);
+ IOUtils.closeQuietly(out);
+ IOUtils.closeQuietly(clientSocket);
+ }
+ index++;
+ }
+ }
+ }
+ if ( cfg.getProcess() != null ) {
+ final Process process = cfg.getProcess();
+
+ if (!destroy) {
+ LOG.debug("Waiting for process to stop...");
+ process.waitFor(twoMinutes, TimeUnit.MILLISECONDS);
+ if (process.isAlive()) {
+ LOG.debug("Process timeout out after 2 minutes");
+ destroy = true;
+ } else {
+ LOG.debug("Process stopped");
+ }
+ }
+
+ if (destroy) {
+ LOG.debug("Destroying process...");
+ process.destroy();
+ process.waitFor(twoMinutes, TimeUnit.MILLISECONDS);
+ LOG.debug("Process destroyed");
+ }
+
+ cfg.setProcess(null);
+ }
+ } else {
+ LOG.warn("Launchpad already stopped");
+ }
+ }
+
+ private static File getControlPortFile(final File directory) {
+ final File launchpadDir = new File(directory, LaunchpadEnvironment.WORK_DIR_NAME);
+ final File confDir = new File(launchpadDir, "conf");
+ final File controlPortFile = new File(confDir, "controlport");
+ return controlPortFile;
+ }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LaunchpadEnvironment.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LaunchpadEnvironment.java
new file mode 100644
index 0000000..150679c
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LaunchpadEnvironment.java
@@ -0,0 +1,152 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Common settings for all launchpad instances.
+ */
+public class LaunchpadEnvironment {
+
+ /** The work directory created by starting launchpad. */
+ public static final String WORK_DIR_NAME = "sling";
+
+ private final File launchpadJar;
+ private final boolean cleanWorkingDirectory;
+ private final boolean shutdownOnExit;
+ private final int readyTimeOutSec;
+ private final String debug;
+
+ public LaunchpadEnvironment(final File launchpadJar,
+ final boolean cleanWorkingDirectory,
+ final boolean shutdownOnExit,
+ final int readyTimeOutSec,
+ final String debug) {
+ this.launchpadJar = launchpadJar;
+ this.cleanWorkingDirectory = cleanWorkingDirectory;
+ this.shutdownOnExit = shutdownOnExit;
+ this.readyTimeOutSec = readyTimeOutSec;
+ this.debug = debug;
+ }
+
+ public boolean isShutdownOnExit() {
+ return this.shutdownOnExit;
+ }
+
+ public int getReadyTimeOutSec() {
+ return this.readyTimeOutSec;
+ }
+
+ /**
+ * Check if the launchpad folder exists.
+ */
+ private void ensureFolderExists(final File folder) {
+ if (!folder.exists()) {
+ folder.mkdirs();
+ }
+ if (this.cleanWorkingDirectory) {
+ final File work = new File(folder, WORK_DIR_NAME);
+ org.apache.commons.io.FileUtils.deleteQuietly(work);
+ }
+ }
+
+ private File installLaunchpad(final File folder) throws IOException {
+ if (this.launchpadJar.getParentFile().getAbsolutePath().equals(folder.getAbsolutePath())) {
+ return this.launchpadJar;
+ }
+ try {
+ FileUtils.copyFileToDirectory(this.launchpadJar, folder);
+ return new File(folder, this.launchpadJar.getName());
+ } catch (final IOException ioe) {
+ throw new IOException("Unable to copy " + this.launchpadJar + " to " + folder, ioe);
+ }
+ }
+
+ private void installLauncher(final File folder) throws IOException {
+ final File binDir = new File(folder, "bin");
+ copyResource("org/apache/sling/maven/slingstart/feature/launcher/Launcher.class", binDir);
+ copyResource("org/apache/sling/maven/slingstart/feature/launcher/LauncherMBean.class", binDir);
+ copyResource("org/apache/sling/maven/slingstart/feature/launcher/Main.class", binDir);
+ }
+
+ /**
+ * Prepare a new instance.
+ * @param folder The target folder for the instance
+ * @return The launchpad jar
+ * @throws IOException if an error occurs.
+ */
+ public File prepare(final File folder) throws IOException {
+ this.ensureFolderExists(folder);
+
+ // copy launchpadJar
+ final File launchpad = this.installLaunchpad(folder);
+
+ // install launcher
+ this.installLauncher(folder);
+
+ return launchpad;
+ }
+
+ private void copyResource(final String resource,
+ final File dir)
+ throws IOException {
+ final int lastSlash = resource.lastIndexOf('/');
+ final File baseDir;
+ if ( lastSlash > 0 ) {
+ final String filePath = resource.substring(0, lastSlash).replace('/', File.separatorChar);
+ baseDir = new File(dir, filePath);
+ } else {
+ baseDir = dir;
+ }
+ baseDir.mkdirs();
+ final File file = new File(baseDir, resource.substring(lastSlash + 1));
+ final InputStream is = LaunchpadEnvironment.class.getClassLoader().getResourceAsStream(resource);
+ if ( is == null ) {
+ throw new IOException("Resource not found: " + resource);
+ }
+ final FileOutputStream fos = new FileOutputStream(file);
+ final byte[] buffer = new byte[2048];
+ int l;
+ try {
+ while ( (l = is.read(buffer)) > 0 ) {
+ fos.write(buffer, 0, l);
+ }
+ } finally {
+ if ( fos != null ) {
+ fos.close();
+ }
+ if ( is != null ) {
+ is.close();
+ }
+ }
+ }
+
+ /**
+ *
+ * @return the global debug parameter for all Sling instances. Set through {@link StartMojo#debug}.
+ */
+ public String getDebug() {
+ return debug;
+ }
+
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/PortHelper.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/PortHelper.java
new file mode 100644
index 0000000..23d64c3
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/PortHelper.java
@@ -0,0 +1,49 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Simple helper class to find a new port.
+ */
+public class PortHelper {
+
+ private static final Set<Integer> USED_PORTS = new HashSet<Integer>();
+
+ public static synchronized int getNextAvailablePort()
+ throws MojoExecutionException {
+ int unusedPort = 0;
+ do {
+ try {
+ final ServerSocket socket = new ServerSocket( 0 );
+ unusedPort = socket.getLocalPort();
+ socket.close();
+ } catch ( final IOException e ) {
+ throw new MojoExecutionException( "Error getting an available port from system", e );
+ }
+ } while ( USED_PORTS.contains(unusedPort));
+ USED_PORTS.add(unusedPort);
+
+ return unusedPort;
+ }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescription.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescription.java
new file mode 100644
index 0000000..ca8c563
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescription.java
@@ -0,0 +1,81 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+import java.io.File;
+
+/**
+ * A running launchpad process.
+ */
+public class ProcessDescription {
+
+ private final String id;
+ private final File directory;
+ private final ControlListener listener;
+ private volatile Process process;
+
+ public ProcessDescription(final String id, final File directory) throws MojoExecutionException {
+ this.id = id;
+ this.directory = directory;
+ this.listener = new ControlListener(PortHelper.getNextAvailablePort());
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public File getDirectory() {
+ return directory;
+ }
+
+ public ControlListener getControlListener() {
+ return this.listener;
+ }
+
+ public Process getProcess() {
+ return process;
+ }
+
+ public void setProcess(final Process process) {
+ this.process = process;
+ }
+
+ /**
+ * Install a shutdown hook
+ */
+ public void installShutdownHook() {
+ final ProcessDescription cfg = this;
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ if ( cfg.getProcess() != null ) {
+ System.out.println("Terminating launchpad " + cfg.getId());
+ cfg.getProcess().destroy();
+ cfg.setProcess(null);
+ }
+ }
+ });
+ }
+
+ @Override
+ public String toString() {
+ return "RunningProcessDescription [id=" + id + ", directory="
+ + directory + ", process=" + process + "]";
+ }
+}
\ No newline at end of file
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescriptionProvider.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescriptionProvider.java
new file mode 100644
index 0000000..cfb22e8
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescriptionProvider.java
@@ -0,0 +1,106 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A singleton which is responsible to provide {@link ProcessDescription}s
+ */
+public class ProcessDescriptionProvider {
+
+ private static final String DEFAULT_KEY = "DEFAULT_LAUNCHPAD";
+
+ private static ProcessDescriptionProvider ourInstance = new ProcessDescriptionProvider();
+ private final Map<String, ProcessDescription> configs = new HashMap<String, ProcessDescription>();
+ private final Map<String, String> lockedIds = new HashMap<String, String>();
+
+ private ProcessDescriptionProvider() {
+ // private constructor
+ }
+
+ public static ProcessDescriptionProvider getInstance() {
+ return ourInstance;
+ }
+
+ /**
+ * Prepare an ID for a launchpad that will be started, before saving the config.
+ * @param launchpadId the id of the launchpad to lock
+ * @return id key used to add to configs
+ */
+ public synchronized String getId(final String launchpadId) throws Exception {
+ final String id = (launchpadId == null ? DEFAULT_KEY : launchpadId);
+ if (configs.containsKey(id) || lockedIds.containsKey(id)) {
+ throw new Exception("Launchpad Id " + id + " is already in use");
+ }
+
+ String ts = String.valueOf(System.currentTimeMillis());
+ lockedIds.put(id, ts);
+ return ts;
+ }
+
+ /**
+ *
+ * @param launchpadId
+ * @param unlockKey
+ * @return
+ */
+ public synchronized boolean cancelId(final String launchpadId, final String unlockKey) {
+ final String id = (launchpadId == null ? DEFAULT_KEY : launchpadId);
+ if (lockedIds.containsKey(id) && lockedIds.get(id).equals(unlockKey)) {
+ lockedIds.remove(id);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ *
+ * @param launchpadId
+ * @return
+ */
+ public synchronized ProcessDescription getRunConfiguration(final String launchpadId) {
+ final String id = (launchpadId == null ? DEFAULT_KEY : launchpadId);
+ return configs.get(id);
+ }
+
+ /**
+ *
+ * @param launchpadId
+ * @return
+ */
+ public synchronized boolean isRunConfigurationAvailable(final String launchpadId) {
+ return getRunConfiguration(launchpadId) == null && !lockedIds.containsKey(launchpadId);
+ }
+
+ public synchronized void addRunConfiguration(ProcessDescription cfg, final String unlockKey) throws Exception {
+ String id = cfg.getId() == null ? DEFAULT_KEY : cfg.getId();
+ if (!lockedIds.containsKey(id) || !lockedIds.get(id).equals(unlockKey)) {
+ throw new Exception("Cannot add configuration. Id " + id + " doesn't exist");
+ }
+ lockedIds.remove(cfg.getId());
+ configs.put(cfg.getId(), cfg);
+ }
+
+ public synchronized void removeRunConfiguration(final String launchpadId) {
+ final String id = (launchpadId == null ? DEFAULT_KEY : launchpadId);
+ configs.remove(id);
+ }
+
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ServerConfiguration.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ServerConfiguration.java
new file mode 100644
index 0000000..1a5051f
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ServerConfiguration.java
@@ -0,0 +1,219 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * A server configuration
+ */
+public class ServerConfiguration implements Serializable {
+
+ private static final long serialVersionUID = 1922175510880318125L;
+
+ private static final String DEFAULT_VM_OPTS = "-Xmx1024m -XX:MaxPermSize=256m -Djava.awt.headless=true";
+
+ // http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation
+ private static final String DEFAULT_VM_DEBUG_OPTS = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000";
+
+ /** The unique id. */
+ private String id;
+
+ /** The run mode string. */
+ private String runmode;
+
+ /** The port to use. */
+ private String port;
+
+ /** The control port to use. */
+ private String controlPort;
+
+ /** The context path. */
+ private String contextPath;
+
+ /** The vm options. */
+ private String vmOpts = DEFAULT_VM_OPTS;
+
+ /**
+ * If set to {@code "true"}, the process will allow a debugger to connect on port 8000.
+ * If set to some other string, that string will be appended to this server's {@code vmOpts}, allowing you to configure arbitrary debugging options.
+ * If the global configuration property {@link StartMojo#debug} is set on the mojo itself, it will be used instead.
+ */
+ private String debug;
+
+ /** Additional application options. */
+ private String opts;
+
+ /** Number of instances. */
+ private int instances = 1;
+
+ /** The folder to use. */
+ private File folder;
+
+ /**
+ * The relative filename of the file which receives both the standard output (stdout) and standard error (stderr) of the server processes.
+ * If null or empty string the server process inherits stdout from the parent process (i.e. the Maven process).
+ * The given filename must be relative to the working directory of the according server.
+ */
+ private String stdOutFile;
+
+ /**
+ * Get the instance id
+ * @return The instance id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Set the instance id
+ * @param id New instance id
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getRunmode() {
+ return runmode;
+ }
+
+ public void setRunmode(final String runmode) {
+ this.runmode = runmode;
+ }
+
+ public String getPort() {
+ return port;
+ }
+
+ public void setPort(final String port) {
+ this.port = port;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public void setContextPath(final String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ public String getVmOpts() {
+ return vmOpts;
+ }
+
+ public void setVmOpts(final String vmOpts) {
+ this.vmOpts = vmOpts;
+ }
+
+ /**
+ * Returns the debugging options derived from the passed globalDebug parameter and the debug field (where the globalDebug parameter has precedence over the local field)
+ * @param globalDebug the global debug options (may be {@code null}).
+ * @return the debugging options to use or {@code null}. Should be appended to the ones being returned by {@link #getVmOpts()}.
+ * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation">JPDA Sun VM Invocation Options</a>
+ */
+ public String getVmDebugOpts(String globalDebug) {
+ if (globalDebug != null) {
+ if (Boolean.valueOf(globalDebug).equals(Boolean.TRUE)) {
+ return DEFAULT_VM_DEBUG_OPTS;
+ }
+ return globalDebug;
+ }
+ if (Boolean.valueOf(debug).equals(Boolean.TRUE)) {
+ return DEFAULT_VM_DEBUG_OPTS;
+ }
+ return debug;
+ }
+
+ public void setDebug(final String debug) {
+ this.debug = debug;
+ }
+
+ public String getOpts() {
+ return opts;
+ }
+
+ public void setOpts(final String opts) {
+ this.opts = opts;
+ }
+
+ public int getInstances() {
+ return this.instances;
+ }
+
+ public void setInstances(final int value) {
+ this.instances = value;
+ }
+
+ public File getFolder() {
+ return folder;
+ }
+
+ public void setFolder(final File folder) {
+ this.folder = folder.getAbsoluteFile();
+ }
+
+ public String getControlPort() {
+ return controlPort;
+ }
+
+ public void setControlPort(String controlPort) {
+ this.controlPort = controlPort;
+ }
+
+ public String getStdOutFile() {
+ return stdOutFile;
+ }
+
+ public void setStdOutFile(String stdOutFile) {
+ this.stdOutFile = stdOutFile;
+ }
+
+ /**
+ * Get the server
+ * @return The server
+ */
+ public String getServer() {
+ // hard coded for now
+ return "localhost";
+ }
+
+ public ServerConfiguration copy() {
+ final ServerConfiguration copy = new ServerConfiguration();
+ // we do not copy the id
+ copy.setRunmode(this.getRunmode());
+ copy.setPort(this.getPort());
+ copy.setContextPath(this.getContextPath());
+ copy.setVmOpts(this.getVmOpts());
+ copy.setDebug(this.debug);
+ copy.setOpts(this.getOpts());
+ copy.setInstances(1);
+ copy.setFolder(this.getFolder());
+ copy.setControlPort(this.getControlPort());
+ copy.setStdOutFile(this.stdOutFile);
+ return copy;
+ }
+
+ @Override
+ public String toString() {
+ return "LaunchpadConfiguration [id=" + id + ", runmode=" + runmode
+ + ", port=" + port + ", controlPort=" + controlPort
+ + ", contextPath=" + contextPath
+ + ", vmOpts=" + vmOpts + ", vmDebugOpts=" + getVmDebugOpts(null) + ", opts=" + opts + ", instances="
+ + instances + ", folder=" + folder + ", stdout=" + stdOutFile + "]";
+ }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StartMojo.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StartMojo.java
new file mode 100644
index 0000000..1915303
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StartMojo.java
@@ -0,0 +1,461 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.sling.maven.slingstart.feature.BuildConstants;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Start one or multiple launchpad instance(s).
+ */
+@Mojo(
+ name = "start",
+ defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST,
+ threadSafe = true
+ )
+public class StartMojo extends AbstractStartStopMojo {
+
+ /**
+ * Overwrites debug parameter of all server configurations (if set).
+ * Attaches a debugger to the forked JVM. If set to {@code "true"}, the process will allow a debugger to connect on port 8000.
+ * If set to some other string, that string will be appended to the server's {@code vmOpts}, allowing you to configure arbitrary debugging options.
+ */
+ @Parameter(property = "launchpad.debug")
+ protected String debug;
+
+ /**
+ * Ready timeout in seconds. If the launchpad has not been started in this
+ * time, it's assumed that the startup failed.
+ */
+ @Parameter(property = "launchpad.ready.timeout", defaultValue = "600")
+ private int launchpadReadyTimeOutSec;
+
+ /**
+ * The launchpad jar. This option has precedence over "launchpadDependency".
+ */
+ @Parameter(property = "launchpad.jar")
+ private File launchpadJar;
+
+ /**
+ * The launchpad jar as a dependency. This is only used if "launchpadJar" is not
+ * specified.
+ */
+ @Parameter
+ private Dependency launchpadDependency;
+
+ /**
+ * Clean the working directory before start.
+ */
+ @Parameter(property = "launchpad.clean.workdir", defaultValue = "false")
+ private boolean cleanWorkingDirectory;
+
+ /**
+ * Keep the launchpad running.
+ * @deprecated Use {@link AbstractStartStopMojo# blockUntilKeyIsPressed} instead.
+ */
+ @Deprecated
+ @Parameter(property = "launchpad.keep.running", defaultValue = "false")
+ private boolean keepLaunchpadRunning;
+
+ /**
+ * Set the execution of launchpad instances to be run in parallel (threads)
+ */
+ @Parameter(property = "launchpad.parallelExecution", defaultValue = "true")
+ private boolean parallelExecution;
+
+ /**
+ * The Maven project.
+ */
+ @Parameter(property = "project", readonly = true, required = true)
+ private MavenProject project;
+
+ /**
+ * The Maven session.
+ */
+ @Parameter(property = "session", readonly = true, required = true)
+ private MavenSession mavenSession;
+
+ @Component
+ private ArtifactHandlerManager artifactHandlerManager;
+
+ /**
+ * Used to look up Artifacts in the remote repository.
+ *
+ */
+ @Component
+ private ArtifactResolver resolver;
+
+ /**
+ * Get a resolved Artifact from the coordinates provided
+ *
+ * @return the artifact, which has been resolved.
+ * @throws MojoExecutionException
+ */
+ private Artifact getArtifact(final Dependency d)
+ throws MojoExecutionException {
+ final Artifact prjArtifact = new DefaultArtifact(d.getGroupId(),
+ d.getArtifactId(),
+ VersionRange.createFromVersion(d.getVersion()),
+ d.getScope(),
+ d.getType(),
+ d.getClassifier(),
+ this.artifactHandlerManager.getArtifactHandler(d.getType()));
+ try {
+ this.resolver.resolve(prjArtifact, this.project.getRemoteArtifactRepositories(), this.mavenSession.getLocalRepository());
+ } catch (final ArtifactResolutionException e) {
+ throw new MojoExecutionException("Unable to get artifact for " + d, e);
+ } catch (ArtifactNotFoundException e) {
+ throw new MojoExecutionException("Unable to get artifact for " + d, e);
+ }
+
+ return prjArtifact;
+ }
+
+
+ @Override
+ protected void doExecute() throws MojoExecutionException, MojoFailureException {
+ // delete properties
+ if ( systemPropertiesFile != null && systemPropertiesFile.exists() ) {
+ FileUtils.deleteQuietly(this.systemPropertiesFile);
+ }
+
+ // get configurations
+ final Collection<ServerConfiguration> configurations = getLaunchpadConfigurations();
+
+ // create the common environment
+ final LaunchpadEnvironment env = new LaunchpadEnvironment(this.findLaunchpadJar(),
+ this.cleanWorkingDirectory,
+ !this.keepLaunchpadRunning,
+ this.launchpadReadyTimeOutSec,
+ this.debug);
+
+ // create callables
+ final Collection<LauncherCallable> tasks = new LinkedList<LauncherCallable>();
+
+ for (final ServerConfiguration launchpadConfiguration : configurations) {
+ validateConfiguration(launchpadConfiguration);
+
+ tasks.add(createTask(launchpadConfiguration, env));
+ }
+
+ // create the launchpad runner properties
+ this.createLaunchpadRunnerProperties(configurations);
+
+ if (parallelExecution) {
+ // ExecutorService for starting launchpad instances in parallel
+ final ExecutorService executor = Executors.newCachedThreadPool();
+ try {
+ final List<Future<ProcessDescription>> resultsCollector = executor.invokeAll(tasks);
+ for (final Future<ProcessDescription> future : resultsCollector) {
+ try {
+ if (null == future.get()) {
+ throw new MojoExecutionException("Cannot start all the instances");
+ }
+ } catch (final ExecutionException e) {
+ throw new MojoExecutionException(e.getLocalizedMessage(), e);
+ }
+ }
+ } catch ( final InterruptedException e) {
+ throw new MojoExecutionException(e.getLocalizedMessage(), e);
+ }
+ } else {
+ for (final LauncherCallable task : tasks) {
+ try {
+ if (null == task.call()) {
+ throw new MojoExecutionException("Cannot start all the instances");
+ }
+ } catch (final Exception e) {
+ throw new MojoExecutionException(e.getLocalizedMessage(), e);
+ }
+ }
+ }
+ if (this.keepLaunchpadRunning) {
+ getLog().info("Press CTRL-C to stop launchpad instance(s)...");
+ while ( true && this.isRunning(tasks)) {
+ try {
+ Thread.sleep(5000);
+ } catch (final InterruptedException ie) {
+ break;
+ }
+ }
+ }
+ blockIfNecessary();
+ }
+
+ /**
+ * Are all launchpads still running?
+ */
+ private boolean isRunning(final Collection<LauncherCallable> tasks) {
+ for(final LauncherCallable task : tasks) {
+ if ( !task.isRunning() ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void createLaunchpadRunnerProperties(final Collection<ServerConfiguration> configurations)
+ throws MojoExecutionException {
+ // create properties
+ OutputStream writer = null;
+ final Properties props = new Properties();
+ try {
+ writer = new FileOutputStream(this.systemPropertiesFile);
+
+ // disable sling startup check
+ props.put("launchpad.skip.startupcheck", "true");
+
+ // write out all instances
+ int index = 0;
+ for (final ServerConfiguration launchpadConfiguration : configurations) {
+ index++;
+ props.put("launchpad.instance.id." + String.valueOf(index), launchpadConfiguration.getId());
+ String runMode = launchpadConfiguration.getRunmode();
+ if ( runMode == null ) {
+ runMode = "";
+ }
+ props.put("launchpad.instance.runmode." + String.valueOf(index), runMode);
+ props.put("launchpad.instance.server." + String.valueOf(index), launchpadConfiguration.getServer());
+ props.put("launchpad.instance.port." + String.valueOf(index), launchpadConfiguration.getPort());
+ props.put("launchpad.instance.contextPath." + String.valueOf(index), launchpadConfiguration.getContextPath());
+ final String url = createServerUrl(launchpadConfiguration);
+ props.put("launchpad.instance.url." + String.valueOf(index), url);
+ }
+ props.put("launchpad.instances", String.valueOf(index));
+
+ props.store(writer, null);
+ } catch (final IOException e) {
+ throw new MojoExecutionException(e.getLocalizedMessage(), e);
+ } finally {
+ IOUtils.closeQuietly(writer);
+ }
+ }
+
+ private static String createServerUrl(final ServerConfiguration qc) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("http://");
+ sb.append(qc.getServer());
+ if ( !qc.getPort().equals("80") ) {
+ sb.append(':');
+ sb.append(qc.getPort());
+ }
+ final String contextPath = qc.getContextPath();
+ if ( contextPath != null && contextPath.trim().length() > 0 && !contextPath.equals("/") ) {
+ if ( !contextPath.startsWith("/") ) {
+ sb.append('/');
+ }
+ if ( contextPath.endsWith("/") ) {
+ sb.append(contextPath, 0, contextPath.length()-1);
+ } else {
+ sb.append(contextPath);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * @param launchpadConfiguration
+ */
+ private LauncherCallable createTask(final ServerConfiguration launchpadConfiguration,
+ final LaunchpadEnvironment env)
+ throws MojoExecutionException, MojoFailureException {
+ final String id = launchpadConfiguration.getId();
+ getLog().debug(new StringBuilder("Starting ").append(id).
+ append(" with runmode ").append(launchpadConfiguration.getRunmode()).
+ append(" on port ").append(launchpadConfiguration.getPort()).
+ append(" in folder ").append(launchpadConfiguration.getFolder().getAbsolutePath()).toString());
+
+ // create task
+ return new LauncherCallable(this.getLog(), launchpadConfiguration, env);
+
+ }
+
+ /**
+ * Validate a configuration
+ * @param launchpadConfiguration The launchpad configuration
+ * @throws MojoExecutionException
+ */
+ private void validateConfiguration(final ServerConfiguration launchpadConfiguration)
+ throws MojoExecutionException {
+ if ( launchpadConfiguration.getPort() == null ) {
+ launchpadConfiguration.setPort(String.valueOf(PortHelper.getNextAvailablePort()));
+ }
+
+ if ( launchpadConfiguration.getControlPort() == null ) {
+ launchpadConfiguration.setControlPort(String.valueOf(PortHelper.getNextAvailablePort()));
+ }
+
+ // set the id of the launchpad
+ if ( launchpadConfiguration.getId() == null || launchpadConfiguration.getId().trim().length() == 0 ) {
+ String runMode = launchpadConfiguration.getRunmode();
+ if ( runMode == null ) {
+ runMode = "_";
+ }
+ final String id = new StringBuilder(runMode.replace(',', '_')).append('-').append(launchpadConfiguration.getPort()).toString();
+ launchpadConfiguration.setId(id);
+ }
+
+ // populate folder if not set
+ if (launchpadConfiguration.getFolder() == null) {
+ final File folder = new File(new StringBuilder(this.project.getBuild().getDirectory()).append('/').append(launchpadConfiguration.getId()).toString());
+ launchpadConfiguration.setFolder(folder);
+ }
+ // context path should not be null
+ if ( launchpadConfiguration.getContextPath() == null ) {
+ launchpadConfiguration.setContextPath("");
+ }
+
+ if ( launchpadConfiguration.getInstances() < 0 ) {
+ launchpadConfiguration.setInstances(1);
+ }
+ }
+
+ /**
+ * Finds the launchpad.jar artifact of the project being built.
+ *
+ * @return the launchpad.jar artifact
+ * @throws MojoFailureException if a launchpad.jar artifact was not found
+ */
+ private File findLaunchpadJar() throws MojoFailureException, MojoExecutionException {
+
+ // If a launchpad JAR is specified, use it
+ if (launchpadJar != null) {
+ getLog().info("Using launchpad jar from '" + launchpadJar + "' given as configuration parameter!");
+ return launchpadJar;
+ }
+
+ // If a launchpad dependency is configured, resolve it
+ if (launchpadDependency != null) {
+ getLog().info("Using launchpad dependency '" + launchpadDependency + "' given as configuration parameter!");
+ return getArtifact(launchpadDependency).getFile();
+ }
+
+ // If the current project is a slingstart project, use its JAR artifact
+ if (this.project.getPackaging().equals(BuildConstants.PACKAGING_SLINGSTART)) {
+ File jarFile = project.getArtifact().getFile();
+ if (jarFile != null && jarFile.exists()) {
+ getLog().info("Using launchpad jar being generated as this project's primary artifact: '" + jarFile + "'!");
+ return jarFile;
+ }
+ else {
+ jarFile = new File(project.getBuild().getDirectory(), project.getBuild().getFinalName() + ".jar");
+ if (jarFile.exists()) {
+ getLog().info("Using launchpad jar being generated as this project's primary artifact: '" + jarFile + "'!");
+ return jarFile;
+ }
+ }
+ }
+
+ // In case there was a provisioning model found but this is not a slingstart project, the JAR might be attached already through goal "package"
+ for (Artifact attachedArtifact : project.getAttachedArtifacts()) {
+ // find the attached artifact with classifier "standalone"
+ if (BuildConstants.TYPE_JAR.equals(attachedArtifact.getType()) && BuildConstants.CLASSIFIER_APP.equals(attachedArtifact.getClassifier())) {
+ getLog().info("Using launchpad jar being attached as additional project artifact: '" + attachedArtifact.getFile() + "'!");
+ return attachedArtifact.getFile();
+ }
+ }
+
+ // also check for jars in known target folders (in case the jar has been created in this project's target folder but not attached to the Maven project)
+//AS TODO: Is Package Mojo still needed / supported ?
+// File localJarFile = PackageMojo.getNonPrimaryBuildFile(project, ".jar");
+// if (localJarFile.exists()) {
+// getLog().info("Using local launchpad jar being created in predefined directory: '" + localJarFile + "'!");
+// return localJarFile;
+// }
+
+ // Last chance: use the first declared dependency with type "slingstart"
+ final Set<Artifact> dependencies = this.project.getDependencyArtifacts();
+ for (final Artifact dep : dependencies) {
+ if (BuildConstants.PACKAGING_SLINGSTART.equals(dep.getType())) {
+ final Dependency d = new Dependency();
+ d.setGroupId(dep.getGroupId());
+ d.setArtifactId(dep.getArtifactId());
+ d.setVersion(dep.getVersion());
+ d.setScope(Artifact.SCOPE_RUNTIME);
+ d.setType(BuildConstants.TYPE_JAR);
+ getLog().info("Using launchpad jar from first dependency of type 'slingstart': '"+ d +"'!");
+ return getArtifact(d).getFile();
+ }
+ }
+
+ // Launchpad has not been found, throw an exception
+ throw new MojoFailureException("Could not find the launchpad jar. " +
+ "Either specify the 'launchpadJar' configuration or use this inside a slingstart project.");
+ }
+
+ /**
+ * Get all configurations
+ * @return Collection of configurations.
+ */
+ private Collection<ServerConfiguration> getLaunchpadConfigurations() {
+ final List<ServerConfiguration> configs = new ArrayList<ServerConfiguration>();
+ if ( this.servers != null && !this.servers.isEmpty() ) {
+ for(final ServerConfiguration config : this.servers) {
+ // if instances is set to 0, no instance is added
+ if ( config.getInstances() != 0 ) {
+ configs.add(config);
+ for(int i=2; i<=config.getInstances();i++) {
+ final ServerConfiguration replicaConfig = config.copy();
+ replicaConfig.setPort(null);
+ final File folder = replicaConfig.getFolder();
+ if ( folder != null ) {
+ replicaConfig.setFolder(new File(folder.getParentFile(), folder.getName() + '-' + String.valueOf(i)));
+ }
+ configs.add(replicaConfig);
+ }
+ config.setInstances(1);
+ }
+ }
+ } else {
+ // use single default instance
+ configs.add(new ServerConfiguration());
+ }
+ return configs;
+ }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StopMojo.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StopMojo.java
new file mode 100644
index 0000000..213c729
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StopMojo.java
@@ -0,0 +1,88 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Stop one or multiple running launchpad instance(s).
+ *
+ */
+@Mojo(
+ name = "stop",
+ defaultPhase = LifecyclePhase.POST_INTEGRATION_TEST,
+ threadSafe = true
+)
+public class StopMojo extends AbstractStartStopMojo {
+
+ @Override
+ protected void doExecute() throws MojoExecutionException, MojoFailureException {
+
+ // read configurations
+ final Properties launchpadConfigProps = new Properties();
+ Reader reader = null;
+ try {
+ reader = new FileReader(this.systemPropertiesFile);
+ launchpadConfigProps.load(reader);
+ } catch ( final IOException ioe) {
+ throw new MojoExecutionException("Unable to read launchpad runner configuration properties.", ioe);
+ } finally {
+ IOUtils.closeQuietly(reader);
+ }
+
+ final int instances = Integer.valueOf(launchpadConfigProps.getProperty("launchpad.instances"));
+ final List<ProcessDescription> configurations = new ArrayList<ProcessDescription>();
+ for(int i=1;i<=instances;i++) {
+ final String id = launchpadConfigProps.getProperty("launchpad.instance.id." + String.valueOf(i));
+
+ final ProcessDescription config = ProcessDescriptionProvider.getInstance().getRunConfiguration(id);
+ if ( config == null ) {
+ getLog().warn("No launchpad configuration found for instance " + id);
+ } else {
+ configurations.add(config);
+ }
+ }
+
+ blockIfNecessary();
+ if (configurations.size() > 0) {
+ getLog().info(new StringBuilder("Stopping ").append(configurations.size()).append(" Launchpad instances").toString());
+
+ for (final ProcessDescription cfg : configurations) {
+
+ try {
+ LauncherCallable.stop(this.getLog(), cfg);
+ ProcessDescriptionProvider.getInstance().removeRunConfiguration(cfg.getId());
+ } catch (Exception e) {
+ throw new MojoExecutionException("Could not stop launchpad " + cfg.getId(), e);
+ }
+ }
+ } else {
+ getLog().warn("No stored configuration file was found at " + this.systemPropertiesFile + " - no Launchapd will be stopped");
+ }
+ }
+}