You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2025/11/24 15:32:47 UTC

(sling-feature-launcher-maven-plugin) branch feature/SLING-13009-parent-62 created (now 6c452a9)

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

sseifert pushed a change to branch feature/SLING-13009-parent-62
in repository https://gitbox.apache.org/repos/asf/sling-feature-launcher-maven-plugin.git


      at 6c452a9  SLING-13009 apply spotless formatting

This branch includes the following new commits:

     new b1a0737  SLING-13009 Update to Parent 62
     new 6c452a9  SLING-13009 apply spotless formatting

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



(sling-feature-launcher-maven-plugin) 01/02: SLING-13009 Update to Parent 62

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

sseifert pushed a commit to branch feature/SLING-13009-parent-62
in repository https://gitbox.apache.org/repos/asf/sling-feature-launcher-maven-plugin.git

commit b1a0737eafad78fb96cc5d4e63b64d83bdae79b1
Author: Stefan Seifert <st...@users.noreply.github.com>
AuthorDate: Mon Nov 24 16:32:04 2025 +0100

    SLING-13009 Update to Parent 62
---
 .sling-module.json | 5 +++++
 pom.xml            | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/.sling-module.json b/.sling-module.json
new file mode 100644
index 0000000..cfad4d2
--- /dev/null
+++ b/.sling-module.json
@@ -0,0 +1,5 @@
+{
+  "jenkins": {
+    "jdks": [17, 21]
+  }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index f690130..17c75ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>49</version>
+        <version>62</version>
         <relativePath />
     </parent>
 


(sling-feature-launcher-maven-plugin) 02/02: SLING-13009 apply spotless formatting

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

sseifert pushed a commit to branch feature/SLING-13009-parent-62
in repository https://gitbox.apache.org/repos/asf/sling-feature-launcher-maven-plugin.git

commit 6c452a9e5b10b536e093b718bdb04039832a3669
Author: Stefan Seifert <st...@users.noreply.github.com>
AuthorDate: Mon Nov 24 16:32:33 2025 +0100

    SLING-13009 apply spotless formatting
---
 pom.xml                                            |  22 ++--
 .../sling/maven/feature/launcher/Launch.java       |  53 ++++-----
 .../maven/feature/launcher/LauncherArguments.java  |   4 +-
 .../maven/feature/launcher/ProcessTracker.java     |  26 ++--
 .../sling/maven/feature/launcher/StartMojo.java    | 131 ++++++++++++---------
 .../sling/maven/feature/launcher/StopMojo.java     |  15 ++-
 .../sling/maven/feature/launcher/LaunchTest.java   |  24 ++--
 7 files changed, 145 insertions(+), 130 deletions(-)

diff --git a/pom.xml b/pom.xml
index 17c75ce..1e17966 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,24 +32,24 @@
 
     <name>Apache Sling Feature Launcher Maven Plugin</name>
 
+    <prerequisites>
+        <maven>${maven.version}</maven>
+    </prerequisites>
+
     <scm>
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-feature-launcher-maven-plugin.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-feature-launcher-maven-plugin.git</developerConnection>
-        <url>https://github.com/apache/sling-feature-launcher-maven-plugin</url>
         <tag>HEAD</tag>
+        <url>https://github.com/apache/sling-feature-launcher-maven-plugin</url>
     </scm>
 
-
-    <prerequisites>
-        <maven>${maven.version}</maven>
-    </prerequisites>
-
     <properties>
         <sling.java.version>11</sling.java.version>
         <maven.version>3.8.1</maven.version>
         <project.build.outputTimestamp>1757086693</project.build.outputTimestamp>
         <github.project.id>apache/sling-feature-launcher-maven-plugin</github.project.id>
-        <maven.compiler.target>${sling.java.version}</maven.compiler.target><!-- also set target next to release due to https://issues.apache.org/jira/browse/MPLUGIN-404 -->
+        <maven.compiler.target>${sling.java.version}</maven.compiler.target>
+        <!-- also set target next to release due to https://issues.apache.org/jira/browse/MPLUGIN-404 -->
     </properties>
 
     <dependencies>
@@ -176,7 +176,7 @@
             </plugin>
         </plugins>
     </build>
-    
+
     <reporting>
         <plugins>
             <plugin>
@@ -187,10 +187,8 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <configuration>
-                  <!-- No javadocs -->
-                    <excludePackageNames>
-                        org.apache.sling
-                    </excludePackageNames>
+                    <!-- No javadocs -->
+                    <excludePackageNames>org.apache.sling</excludePackageNames>
                 </configuration>
             </plugin>
         </plugins>
diff --git a/src/main/java/org/apache/sling/maven/feature/launcher/Launch.java b/src/main/java/org/apache/sling/maven/feature/launcher/Launch.java
index 0e4b3ff..b797316 100644
--- a/src/main/java/org/apache/sling/maven/feature/launcher/Launch.java
+++ b/src/main/java/org/apache/sling/maven/feature/launcher/Launch.java
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
 import org.apache.maven.model.Dependency;
 
 public class Launch {
-    
+
     private static final Pattern ID_PATTERN = Pattern.compile("[a-zA-Z0-9_\\-\\.]+");
 
     private String id;
@@ -39,7 +39,7 @@ public class Launch {
     private LauncherArguments launcherArguments = new LauncherArguments();
     private int startTimeoutSeconds = 30;
     private boolean skip = false;
-    private Map<String,String> environmentVariables = new HashMap<>();
+    private Map<String, String> environmentVariables = new HashMap<>();
     private List<String> repositoryUrls = new ArrayList<>();
 
     public String getId() {
@@ -57,11 +57,11 @@ public class Launch {
     public void setFeature(Dependency feature) {
         this.feature = feature;
     }
-    
+
     public Optional<File> getFeatureFile() {
         return Optional.ofNullable(featureFile).map(File::new);
     }
-    
+
     public void setFeatureFile(String featureFile) {
         this.featureFile = featureFile;
     }
@@ -73,11 +73,11 @@ public class Launch {
     public void setLauncherArguments(LauncherArguments launcherArguments) {
         this.launcherArguments = launcherArguments;
     }
-    
+
     public int getStartTimeoutSeconds() {
         return startTimeoutSeconds;
     }
-    
+
     public void setStartTimeoutSeconds(int startTimeoutSeconds) {
         this.startTimeoutSeconds = startTimeoutSeconds;
     }
@@ -91,8 +91,7 @@ public class Launch {
     }
 
     public Map<String, String> getEnvironmentVariables() {
-        if ( environmentVariables == null )
-            return Collections.emptyMap();
+        if (environmentVariables == null) return Collections.emptyMap();
         return environmentVariables;
     }
 
@@ -109,31 +108,29 @@ public class Launch {
     }
 
     public void validate() {
-        if ( id == null || id.trim().isEmpty() ) 
-            throw new IllegalArgumentException("Missing id");
-        
-        if ( !ID_PATTERN.matcher(id).matches() )
-            throw new IllegalArgumentException("Invalid id '" + id + "'. Allowed characters are digits, numbers, '-','_' and '.'.");
-        
-        if ( startTimeoutSeconds < 0 )
-            throwInvalid("startTimeout value '" + startTimeoutSeconds + "' is negative" );
-        
+        if (id == null || id.trim().isEmpty()) throw new IllegalArgumentException("Missing id");
+
+        if (!ID_PATTERN.matcher(id).matches())
+            throw new IllegalArgumentException(
+                    "Invalid id '" + id + "'. Allowed characters are digits, numbers, '-','_' and '.'.");
+
+        if (startTimeoutSeconds < 0) throwInvalid("startTimeout value '" + startTimeoutSeconds + "' is negative");
+
         boolean hasFeature = feature != null;
         boolean hasFeatureFile = featureFile != null && !featureFile.trim().isEmpty();
-        
-        if ( hasFeature && hasFeatureFile )
+
+        if (hasFeature && hasFeatureFile)
             throwInvalid("Only one of 'feature' and 'featureFile' is allowed, but both are set");
-        
-        if ( !hasFeature && !hasFeatureFile )
-            throwInvalid("Neither 'feature' nor 'featureFile' are set");
-        
-        if ( hasFeatureFile && ! new File(featureFile).exists() )
+
+        if (!hasFeature && !hasFeatureFile) throwInvalid("Neither 'feature' nor 'featureFile' are set");
+
+        if (hasFeatureFile && !new File(featureFile).exists())
             throwInvalid("Feature file '" + featureFile + "' does not exist");
-        
-        if ( hasFeature && ! "slingosgifeature".equals(feature.getType()) )
-            throwInvalid("type must be 'slingosgifeature' but is '" + feature.getType()+"'");
+
+        if (hasFeature && !"slingosgifeature".equals(feature.getType()))
+            throwInvalid("type must be 'slingosgifeature' but is '" + feature.getType() + "'");
     }
-    
+
     private void throwInvalid(String reason) {
         throw new IllegalArgumentException("Invalid launch '" + id + "': " + reason);
     }
diff --git a/src/main/java/org/apache/sling/maven/feature/launcher/LauncherArguments.java b/src/main/java/org/apache/sling/maven/feature/launcher/LauncherArguments.java
index 3693172..e70c68f 100644
--- a/src/main/java/org/apache/sling/maven/feature/launcher/LauncherArguments.java
+++ b/src/main/java/org/apache/sling/maven/feature/launcher/LauncherArguments.java
@@ -26,7 +26,7 @@ public class LauncherArguments {
     private String[] vmOptions = new String[0];
     private Map<String, String> frameworkProperties = new HashMap<>();
     private Map<String, String> variables = new HashMap<>();
-    
+
     public String[] getVmOptions() {
         return vmOptions;
     }
@@ -38,7 +38,7 @@ public class LauncherArguments {
     public Map<String, String> getFrameworkProperties() {
         return frameworkProperties;
     }
-    
+
     public void setFrameworkProperties(Map<String, String> frameworkProperties) {
         this.frameworkProperties = frameworkProperties;
     }
diff --git a/src/main/java/org/apache/sling/maven/feature/launcher/ProcessTracker.java b/src/main/java/org/apache/sling/maven/feature/launcher/ProcessTracker.java
index 72e33ae..63fda7d 100644
--- a/src/main/java/org/apache/sling/maven/feature/launcher/ProcessTracker.java
+++ b/src/main/java/org/apache/sling/maven/feature/launcher/ProcessTracker.java
@@ -18,13 +18,13 @@
  */
 package org.apache.sling.maven.feature.launcher;
 
+import javax.inject.Named;
+import javax.inject.Singleton;
+
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
-import javax.inject.Named;
-import javax.inject.Singleton;
-
 import org.apache.maven.shared.utils.Os;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,7 +39,7 @@ public class ProcessTracker {
         LOG.debug("Destroy process: {}", process);
         process.destroy();
         boolean stopped = process.waitFor(30, TimeUnit.SECONDS);
-        if ( !stopped ) {
+        if (!stopped) {
             LOG.debug("Forcibly destroy process after 30sec: {}", process);
             process.destroyForcibly();
         }
@@ -65,7 +65,7 @@ public class ProcessTracker {
             childProcess.destroy();
             try {
                 boolean stopped = childProcess.onExit().get(30, TimeUnit.SECONDS) != null;
-                if ( !stopped ) {
+                if (!stopped) {
                     LOG.debug("Forcibly destroy child process after 30sec: {}", childProcess);
                     childProcess.destroyForcibly();
                 }
@@ -85,21 +85,22 @@ public class ProcessTracker {
 
     public void startTracking(String launchId, Process process) {
         synchronized (sync) {
-            if ( processes.containsKey(launchId) )
+            if (processes.containsKey(launchId))
                 throw new IllegalArgumentException("Launch id " + launchId + " already associated with a process");
             LOG.debug("Start tracking process for launch {}: {}", launchId, process);
             processes.put(launchId, process);
-            if ( ! hookAdded ) {
+            if (!hookAdded) {
                 Runtime.getRuntime().addShutdownHook(new Thread("process-tracker-shutdown") {
                     @Override
                     public void run() {
                         LOG.debug("Shutdown hook  is running for launch {}: {}", launchId, process);
-                        for ( Map.Entry<String, Process> entry : processes.entrySet() ) {
-                            LOG.error("Launch {} was not shut down! Destroying forcibly from shutdown hook.", entry.getKey());
+                        for (Map.Entry<String, Process> entry : processes.entrySet()) {
+                            LOG.error(
+                                    "Launch {} was not shut down! Destroying forcibly from shutdown hook.",
+                                    entry.getKey());
                             process.destroyForcibly();
                         }
                     }
-
                 });
                 hookAdded = true;
             }
@@ -111,15 +112,14 @@ public class ProcessTracker {
         synchronized (sync) {
             process = processes.remove(id);
         }
-        if ( process == null ) {
+        if (process == null) {
             LOG.warn("Process not found in process list, skip stopping: {}", id);
             return;
         }
 
         if (Os.isFamily(Os.FAMILY_WINDOWS)) {
             stopWithDescendants(process);
-        }
-        else {
+        } else {
             stop(process);
         }
     }
diff --git a/src/main/java/org/apache/sling/maven/feature/launcher/StartMojo.java b/src/main/java/org/apache/sling/maven/feature/launcher/StartMojo.java
index 7c8dba5..a678c72 100644
--- a/src/main/java/org/apache/sling/maven/feature/launcher/StartMojo.java
+++ b/src/main/java/org/apache/sling/maven/feature/launcher/StartMojo.java
@@ -18,7 +18,6 @@
  */
 package org.apache.sling.maven.feature.launcher;
 
-
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
@@ -64,7 +63,7 @@ import org.eclipse.aether.resolution.ArtifactResult;
 /**
  * Start one or multiple <a href="https://sling.apache.org/documentation/development/feature-model.html">Sling Feature(s)</a>.
  */
-@Mojo( name = "start", defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST )
+@Mojo(name = "start", defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST)
 public class StartMojo extends AbstractMojo {
 
     private static final String JAVA_HOME = "JAVA_HOME";
@@ -73,15 +72,15 @@ public class StartMojo extends AbstractMojo {
     /**
      * The directory in which the features are launched (below its child directory {@code launchers/<launch-id>}).
      */
-    @Parameter( defaultValue = "${project.build.directory}", property = "outputDir", required = true )
+    @Parameter(defaultValue = "${project.build.directory}", property = "outputDir", required = true)
     private File outputDirectory;
 
     /**
      * The version of the <a href="https://github.com/apache/sling-org-apache-sling-feature-launcher">Sling Feature Launcher</a> to use.
      */
-    @Parameter( required = true, defaultValue = "1.3.4")
+    @Parameter(required = true, defaultValue = "1.3.4")
     private String featureLauncherVersion;
-    
+
     // TODO: extract this field into common parent class
     /**
      * List of {@link Launch} objects to start. Each is having the following format:
@@ -103,7 +102,7 @@ public class StartMojo extends AbstractMojo {
      *  <JAVA_HOME>...</JAVA_HOME>
      * </environmentVariables>}
      * </pre>
-     * 
+     *
      * <p>If no repository URLs are configured the following defaults are used, in order:
      * <ul>
      *   <li>The local Maven repository</li>
@@ -117,7 +116,7 @@ public class StartMojo extends AbstractMojo {
 
     @Component
     private ArtifactResolver resolver;
-    
+
     @Parameter(defaultValue = "${localRepository}", readonly = true)
     private ArtifactRepository localRepository;
 
@@ -129,7 +128,7 @@ public class StartMojo extends AbstractMojo {
 
     @Parameter(property = "session", readonly = true, required = true)
     protected MavenSession mavenSession;
-    
+
     @Component
     private ProcessTracker processes;
 
@@ -146,7 +145,8 @@ public class StartMojo extends AbstractMojo {
             // the feature launcher before version 1.1.28 used a single jar, while versions
             //  after that provide an assembly per SLING-10956
             VersionRange beforeAssemblyRange = VersionRange.createFromVersionSpec("(,1.1.26]");
-            boolean useAssembly = !beforeAssemblyRange.containsVersion(new DefaultArtifactVersion(featureLauncherVersion));
+            boolean useAssembly =
+                    !beforeAssemblyRange.containsVersion(new DefaultArtifactVersion(featureLauncherVersion));
 
             RepositorySystemSession repositorySession = mavenSession.getRepositorySession();
             File workDir = new File(outputDirectory, "launchers");
@@ -155,20 +155,22 @@ public class StartMojo extends AbstractMojo {
             File launcher;
             if (useAssembly) {
                 // fetch the assembly artifact
-                Artifact launcherAssemblyArtifact = new DefaultArtifact("org.apache.sling:org.apache.sling.feature.launcher:tar.gz:" + featureLauncherVersion);
-                File assemblyArchive = resolver
-                        .resolveArtifact(repositorySession, new ArtifactRequest(launcherAssemblyArtifact, remoteRepos, null))
+                Artifact launcherAssemblyArtifact = new DefaultArtifact(
+                        "org.apache.sling:org.apache.sling.feature.launcher:tar.gz:" + featureLauncherVersion);
+                File assemblyArchive = resolver.resolveArtifact(
+                                repositorySession, new ArtifactRequest(launcherAssemblyArtifact, remoteRepos, null))
                         .getArtifact()
                         .getFile();
 
                 // unpack the file
-                UnArchiver unArchiver = archiverManager.getUnArchiver( assemblyArchive );
+                UnArchiver unArchiver = archiverManager.getUnArchiver(assemblyArchive);
                 unArchiver.setSourceFile(assemblyArchive);
                 unArchiver.setDestFile(workDir);
                 unArchiver.extract();
 
                 // system property
-                Path relPath = Paths.get(launcherAssemblyArtifact.getArtifactId() + "-" + launcherAssemblyArtifact.getVersion(), "bin");
+                Path relPath = Paths.get(
+                        launcherAssemblyArtifact.getArtifactId() + "-" + launcherAssemblyArtifact.getVersion(), "bin");
                 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                     relPath = relPath.resolve("launcher.bat");
                 } else {
@@ -176,31 +178,34 @@ public class StartMojo extends AbstractMojo {
                 }
                 launcher = workDir.toPath().resolve(relPath).toFile();
             } else {
-                Artifact launcherArtifact = new DefaultArtifact("org.apache.sling:org.apache.sling.feature.launcher:" + featureLauncherVersion);
-                launcher = resolver
-                        .resolveArtifact(repositorySession, new ArtifactRequest(launcherArtifact, remoteRepos, null))
+                Artifact launcherArtifact = new DefaultArtifact(
+                        "org.apache.sling:org.apache.sling.feature.launcher:" + featureLauncherVersion);
+                launcher = resolver.resolveArtifact(
+                                repositorySession, new ArtifactRequest(launcherArtifact, remoteRepos, null))
                         .getArtifact()
                         .getFile();
             }
-            
-            for ( Launch launch : launches ) {
+
+            for (Launch launch : launches) {
                 if (launch.isSkip()) {
                     getLog().info("Skipping starting launch with id " + launch.getId());
                     continue; // skip it
                 }
 
                 launch.validate();
-                
-                File featureFile = launch.getFeature().
-                    map( this::toArtifact )
-                   .map( a -> uncheckedResolveArtifact(repositorySession, a) )
-                   .map( r -> r.getArtifact().getFile())
-                   .orElseGet( () -> launch.getFeatureFile().get() ); // the Launch is guaranteed to either have a feature or a featureFile set
-                
+
+                File featureFile = launch.getFeature()
+                        .map(this::toArtifact)
+                        .map(a -> uncheckedResolveArtifact(repositorySession, a))
+                        .map(r -> r.getArtifact().getFile())
+                        .orElseGet(() -> launch.getFeatureFile()
+                                .get()); // the Launch is guaranteed to either have a feature or a featureFile set
+
                 String javahome = System.getenv(JAVA_HOME);
                 if (javahome == null || javahome.isEmpty()) {
                     // SLING-9843 fallback to java.home system property if JAVA_HOME env variable is not set
-                    getLog().warn("The JAVA_HOME env variable was not set, falling back to the java.home system property");
+                    getLog().warn(
+                                    "The JAVA_HOME env variable was not set, falling back to the java.home system property");
                     javahome = System.getProperty("java.home");
                 }
                 List<String> args = new ArrayList<>();
@@ -249,10 +254,11 @@ public class StartMojo extends AbstractMojo {
                     args.add("-jar");
                     args.add(launcher.getAbsolutePath());
                 }
-                
+
                 List<String> repositoryUrls;
-                
-                if ( launch.getRepositoryUrls() != null && !launch.getRepositoryUrls().isEmpty() ) {
+
+                if (launch.getRepositoryUrls() != null
+                        && !launch.getRepositoryUrls().isEmpty()) {
                     repositoryUrls = launch.getRepositoryUrls();
                 } else {
                     // replicate the behaviour from org.apache.sling.feature.io.artifacts.ArtifactManager
@@ -260,29 +266,32 @@ public class StartMojo extends AbstractMojo {
                     // configuration file $HOME/.m2/settings.xml but cannot find out if the Maven process was invoked
                     // with a maven.repo.local argument
                     repositoryUrls = new ArrayList<>();
-                    repositoryUrls.add(new File(localRepository.getBasedir()).toURI().toString());
+                    repositoryUrls.add(
+                            new File(localRepository.getBasedir()).toURI().toString());
                     repositoryUrls.add("https://repo1.maven.org/maven2");
                     repositoryUrls.add("https://repository.apache.org/content/group/snapshots");
                 }
-                
+
                 args.add("-u");
                 StringJoiner joiner = new StringJoiner(",");
-                repositoryUrls.forEach( joiner::add );
+                repositoryUrls.forEach(joiner::add);
                 args.add(joiner.toString());
-                
+
                 args.add("-f");
                 args.add(featureFile.getAbsolutePath());
                 args.add("-p");
                 args.add(launch.getId());
-                
-                for ( Map.Entry<String, String> frameworkProperty : launch.getLauncherArguments().getFrameworkProperties().entrySet() ) {
+
+                for (Map.Entry<String, String> frameworkProperty :
+                        launch.getLauncherArguments().getFrameworkProperties().entrySet()) {
                     args.add("-D");
-                    args.add(frameworkProperty.getKey()+"="+frameworkProperty.getValue());
+                    args.add(frameworkProperty.getKey() + "=" + frameworkProperty.getValue());
                 }
-                
-                for ( Map.Entry<String, String> variable : launch.getLauncherArguments().getVariables().entrySet() ) {
+
+                for (Map.Entry<String, String> variable :
+                        launch.getLauncherArguments().getVariables().entrySet()) {
                     args.add("-V");
-                    args.add(variable.getKey()+"="+variable.getValue());
+                    args.add(variable.getKey() + "=" + variable.getValue());
                 }
 
                 // TODO - add support for all arguments supported by the feature launcher
@@ -290,27 +299,26 @@ public class StartMojo extends AbstractMojo {
                 pb.redirectOutput(Redirect.INHERIT);
                 pb.redirectInput(Redirect.INHERIT);
                 pb.directory(workDir);
-                launch.getEnvironmentVariables().entrySet()
-                    .forEach( e -> {
-                            getLog().info("Setting environment variable '" + e.getKey() + "' to '" + e.getValue() + "'");
-                            pb.environment().put(e.getKey(), e.getValue());
-                        } );
-                
+                launch.getEnvironmentVariables().entrySet().forEach(e -> {
+                    getLog().info("Setting environment variable '" + e.getKey() + "' to '" + e.getValue() + "'");
+                    pb.environment().put(e.getKey(), e.getValue());
+                });
+
                 getLog().info("Starting launch with id '" + launch.getId() + "', args=" + args);
-                
+
                 CountDownLatch latch = new CountDownLatch(1);
-                
+
                 Process process = pb.start();
-                
+
                 Thread monitor = new Thread("launch-monitor-" + launch.getId()) {
                     @Override
                     public void run() {
                         BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                         String line;
                         try {
-                            while ( (line = reader.readLine()) != null ) {
+                            while ((line = reader.readLine()) != null) {
                                 System.out.println(line); // NOSONAR - we pass through the subprocess stderr
-                                if ( line.contains("Framework started")) {
+                                if (line.contains("Framework started")) {
                                     latch.countDown();
                                     break;
                                 }
@@ -323,17 +331,21 @@ public class StartMojo extends AbstractMojo {
                 monitor.start();
                 getLog().info("Waiting for " + launch.getId() + " to start");
                 boolean started = latch.await(launch.getStartTimeoutSeconds(), TimeUnit.SECONDS);
-                if ( !started ) {
+                if (!started) {
                     ProcessTracker.stop(process);
-                    throw new MojoExecutionException("Launch " + launch.getId() + " failed to start in " + launch.getStartTimeoutSeconds() + " seconds.");
+                    throw new MojoExecutionException("Launch " + launch.getId() + " failed to start in "
+                            + launch.getStartTimeoutSeconds() + " seconds.");
                 }
-                
+
                 processes.startTracking(launch.getId(), process);
             }
 
-        } catch (NoSuchArchiverException | InvalidVersionSpecificationException | ArtifactResolutionException | IOException e) {
+        } catch (NoSuchArchiverException
+                | InvalidVersionSpecificationException
+                | ArtifactResolutionException
+                | IOException e) {
             throw new MojoExecutionException(e.getMessage(), e);
-        } catch ( InterruptedException e ) {
+        } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new MojoExecutionException("Execution interrupted", e);
         }
@@ -348,6 +360,11 @@ public class StartMojo extends AbstractMojo {
     }
 
     private Artifact toArtifact(Dependency dependency) {
-        return new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), dependency.getType(), dependency.getVersion());
+        return new DefaultArtifact(
+                dependency.getGroupId(),
+                dependency.getArtifactId(),
+                dependency.getClassifier(),
+                dependency.getType(),
+                dependency.getVersion());
     }
 }
diff --git a/src/main/java/org/apache/sling/maven/feature/launcher/StopMojo.java b/src/main/java/org/apache/sling/maven/feature/launcher/StopMojo.java
index b84a59a..2b3c46d 100644
--- a/src/main/java/org/apache/sling/maven/feature/launcher/StopMojo.java
+++ b/src/main/java/org/apache/sling/maven/feature/launcher/StopMojo.java
@@ -35,7 +35,7 @@ import org.codehaus.plexus.components.interactivity.PrompterException;
 /**
  * Stop one or multiple <a href="https://sling.apache.org/documentation/development/feature-model.html">Sling Feature(s)</a>.
  */
-@Mojo( name = "stop", defaultPhase = LifecyclePhase.POST_INTEGRATION_TEST)
+@Mojo(name = "stop", defaultPhase = LifecyclePhase.POST_INTEGRATION_TEST)
 public class StopMojo extends AbstractMojo {
 
     // TODO: extract this field into common parent class
@@ -57,10 +57,10 @@ public class StopMojo extends AbstractMojo {
      */
     @Parameter(required = true)
     private List<Launch> launches;
-    
+
     @Component
     private ProcessTracker processes;
-    
+
     /**
      * If {@code true} stopping the server is deferred until you press the Enter key on the terminal on which Maven is executed.
      */
@@ -83,7 +83,7 @@ public class StopMojo extends AbstractMojo {
             }
         }
         try {
-            for ( Launch launch : launches ) {
+            for (Launch launch : launches) {
                 if (launch.isSkip()) {
                     getLog().info("Skipping stopping launch with id " + launch.getId());
                     continue; // skip it
@@ -100,11 +100,14 @@ public class StopMojo extends AbstractMojo {
     protected void waitForUserInput() throws MojoFailureException {
         // http://stackoverflow.com/a/21977269/5155923
         try {
-            String message = MessageUtils.buffer().warning("Waiting for user input before build continues...").toString();
+            String message = MessageUtils.buffer()
+                    .warning("Waiting for user input before build continues...")
+                    .toString();
             getLog().warn(message);
             prompter.prompt("Press Enter to continue");
         } catch (PrompterException e) {
-            throw new MojoFailureException("Could not prompt for user input. Do not use parameter 'waitForInput' in that case", e);
+            throw new MojoFailureException(
+                    "Could not prompt for user input. Do not use parameter 'waitForInput' in that case", e);
         }
     }
 }
diff --git a/src/test/java/org/apache/sling/maven/feature/launcher/LaunchTest.java b/src/test/java/org/apache/sling/maven/feature/launcher/LaunchTest.java
index 1218f5c..a41dac3 100644
--- a/src/test/java/org/apache/sling/maven/feature/launcher/LaunchTest.java
+++ b/src/test/java/org/apache/sling/maven/feature/launcher/LaunchTest.java
@@ -31,25 +31,25 @@ public class LaunchTest {
 
     @Rule
     public TemporaryFolder tmp = new TemporaryFolder();
-    
+
     private Dependency validDep;
     private File validFeatureFile;
 
     @Before
     public void prepare() throws IOException {
-        validDep  = new Dependency();
+        validDep = new Dependency();
         validDep.setGroupId("org.apache.sling");
         validDep.setArtifactId("org.apache.sling.starter");
         validDep.setVersion("12");
         validDep.setClassifier("oak_tar");
         validDep.setType("slingosgifeature");
-        
+
         validFeatureFile = tmp.newFile("feature.json");
     }
 
     @Test
     public void validLaunch_withFeature() {
-        
+
         Launch launch = new Launch();
         launch.setFeature(validDep);
         launch.setId("oak_TAR-12.1"); // covers all allowed character classes
@@ -58,7 +58,7 @@ public class LaunchTest {
 
     @Test
     public void validLaunch_withFeatureFile() {
-        
+
         Launch launch = new Launch();
         launch.setFeatureFile(validFeatureFile.getAbsolutePath());
         launch.setId("feature");
@@ -67,7 +67,7 @@ public class LaunchTest {
 
     @Test(expected = IllegalArgumentException.class)
     public void invalidLaunch_noId() {
-        
+
         Launch launch = new Launch();
         launch.setFeature(validDep);
         launch.validate();
@@ -75,10 +75,10 @@ public class LaunchTest {
 
     @Test(expected = IllegalArgumentException.class)
     public void invalidLaunch_unsupportedType() {
-        
+
         Dependency invalidDep = validDep.clone();
         invalidDep.setType("jar");
-        
+
         Launch launch = new Launch();
         launch.setFeature(invalidDep);
         launch.setId("oak_tar");
@@ -87,7 +87,7 @@ public class LaunchTest {
 
     @Test(expected = IllegalArgumentException.class)
     public void invalidLaunch_noFeature() {
-        
+
         Launch launch = new Launch();
         launch.setId("no_feature");
         launch.validate();
@@ -95,7 +95,7 @@ public class LaunchTest {
 
     @Test(expected = IllegalArgumentException.class)
     public void invalidLaunch_badId() {
-        
+
         Launch launch = new Launch();
         launch.setId("/feature");
         launch.setFeature(validDep);
@@ -104,14 +104,14 @@ public class LaunchTest {
 
     @Test(expected = IllegalArgumentException.class)
     public void invalidLaunch_negativeTimeout() {
-        
+
         Launch launch = new Launch();
         launch.setId("feature");
         launch.setFeature(validDep);
         launch.setStartTimeoutSeconds(-10);
         launch.validate();
     }
-    
+
     @Test(expected = IllegalArgumentException.class)
     public void invalidLaunch_bothFeatureAndFeatureFile() {