You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2019/07/30 11:47:19 UTC

[sling-slingfeature-maven-plugin] branch issues/SLING-8541 updated: SLING-8541 : slingfeature-maven-plugin should allow for generated feature model files

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

cziegeler pushed a commit to branch issues/SLING-8541
in repository https://gitbox.apache.org/repos/asf/sling-slingfeature-maven-plugin.git


The following commit(s) were added to refs/heads/issues/SLING-8541 by this push:
     new 8dc4e03  SLING-8541 : slingfeature-maven-plugin should allow for generated feature model files
8dc4e03 is described below

commit 8dc4e03475eb85367e2851d1d27f1c4564fa0bc9
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Jul 30 13:47:10 2019 +0200

    SLING-8541 : slingfeature-maven-plugin should allow for generated feature model files
---
 .../apache/sling/feature/maven/Preprocessor.java   | 130 +++--------------
 .../apache/sling/feature/maven/ProjectHelper.java  | 126 +++++++++++++++-
 .../feature/maven/mojos/AbstractFeatureMojo.java   | 159 ++++++++++++++++++++-
 .../maven/mojos/AbstractIncludingFeatureMojo.java  |   9 --
 .../feature/maven/mojos/AggregateFeaturesMojo.java |   2 +-
 .../feature/maven/mojos/AnalyseFeaturesMojo.java   |   2 +-
 .../sling/feature/maven/mojos/ApisJarMojo.java     |   2 +-
 .../feature/maven/mojos/AttachFeaturesMojo.java    |   2 +-
 .../feature/maven/mojos/EmbedFeaturesMojo.java     |   3 +-
 .../sling/feature/maven/mojos/ReportingMojo.java   |   3 +-
 .../sling/feature/maven/mojos/RepositoryMojo.java  |   3 +-
 .../feature/maven/mojos/UpdateVersionsMojo.java    |   2 +-
 12 files changed, 305 insertions(+), 138 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/maven/Preprocessor.java b/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
index 02ca00e..6658a68 100644
--- a/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
+++ b/src/main/java/org/apache/sling/feature/maven/Preprocessor.java
@@ -21,8 +21,6 @@ import java.io.FileReader;
 import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Formatter;
 import java.util.HashMap;
@@ -32,17 +30,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonValue;
-import javax.json.stream.JsonGenerator;
-
-import org.apache.felix.configurator.impl.json.JSMin;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Exclusion;
 import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.utils.io.DirectoryScanner;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Extension;
@@ -248,21 +238,6 @@ public class Preprocessor {
         }
     }
 
-    private void scan(final List<File> files, final File dir, final String includes, final String excludes) {
-        final DirectoryScanner scanner = new DirectoryScanner();
-        scanner.setBasedir(dir);
-        if ( includes != null ) {
-            scanner.setIncludes(includes.split(","));
-        }
-        if ( excludes != null ) {
-            scanner.setExcludes(excludes.split(","));
-        }
-        scanner.scan();
-        for(final String f : scanner.getIncludedFiles()) {
-            files.add(new File(dir, f));
-        }
-    }
-
     /**
      * Add all dependencies from the feature
      * @param env The environment
@@ -304,28 +279,34 @@ public class Preprocessor {
         final File dir = new File(info.project.getBasedir(), config.getFeaturesDir());
         if ( dir.exists() ) {
             final List<File> files = new ArrayList<>();
-            scan(files, dir, config.getIncludes(), config.getExcludes());
+            ProjectHelper.scan(files, dir, config.getIncludes(), config.getExcludes());
 
             for(final File file : files) {
             	logger.debug("Reading feature file " + file + " in project " + info.project.getId());
-                final StringBuilder sb = new StringBuilder();
-                try (final Reader reader = new FileReader(file)) {
-                    final char[] buf = new char[4096];
-                    int l = 0;
-
-                    while (( l = reader.read(buf)) > 0 ) {
-                        sb.append(buf, 0, l);
-                    }
-                } catch ( final IOException io) {
-                    throw new RuntimeException("Unable to read feature " + file.getAbsolutePath(), io);
+
+                // if the feature is in the root of the configured directory
+                // and the feature is named "feature.json"
+                // and the feature is not a test feature, this is the main feature
+                // which does not get a classifier
+                final String suggestedClassifier;
+                if (config.isTestConfig() || !file.getName().equals("feature.json")
+                        || !file.getParentFile().getAbsolutePath().equals(
+                                new File(info.project.getBasedir(), config.getFeaturesDir()).getAbsolutePath())) {
+                    final int lastDot = file.getName().lastIndexOf('.');
+                    suggestedClassifier = file.getName().substring(0, lastDot);
+                } else {
+                    suggestedClassifier = null;
                 }
 
-                final String json = preprocessFeature(logger, info, config, file, sb.toString());
+                final String readJson = ProjectHelper.readFeatureFile(info.project, file, suggestedClassifier);
+
+                final String json = preprocessFeature(info.project, config.isValidate(),
+                        file, readJson);
 
                 try (final Reader reader = new StringReader(json)) {
                     final Feature feature = FeatureJSONReader.read(reader, file.getAbsolutePath());
 
-                    this.checkFeatureId(info.project, feature);
+                    ProjectHelper.checkFeatureId(info.project, feature);
 
                     ProjectHelper.setFeatureInfo(info.project, feature);
                     this.postProcessReadFeature(feature);
@@ -340,84 +321,19 @@ public class Preprocessor {
         }
     }
 
-	protected String preprocessFeature(final Logger logger, final FeatureProjectInfo info,
-			final FeatureProjectConfig config, final File file, final String readJson) {
-        // minify JSON (remove comments)
-        String json;
-        try (final Writer out = new StringWriter(); final Reader in = new StringReader(readJson)) {
-            final JSMin min = new JSMin(in, out);
-            min.jsmin();
-            json = out.toString();
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to read feature file " + file.getAbsolutePath(), e);
-        }
-
-		// check if "id" is set
-		try (final JsonReader reader = Json.createReader(new StringReader(json)) ) {
-			final JsonObject obj = reader.readObject();
-			if ( !obj.containsKey("id") ) {
-				final StringBuilder isb = new StringBuilder();
-				isb.append(info.project.getGroupId());
-				isb.append(':');
-				isb.append(info.project.getArtifactId());
-				isb.append(':');
-				isb.append(FeatureConstants.PACKAGING_FEATURE);
-				// if the feature is in the root of the configured directory
-				// and the feature is named "feature.json"
-				// and the feature is not a test feature, this is the main feature
-				// which does not get a classifier
-				if ( config.isTestConfig()
-					 || !file.getName().equals("feature.json")
-					 || !file.getParentFile().getAbsolutePath().equals(new File(info.project.getBasedir(), config.getFeaturesDir()).getAbsolutePath())) {
-		    		isb.append(':');
-			    	final int lastDot = file.getName().lastIndexOf('.');
-				    isb.append(file.getName().substring(0, lastDot));
-				}
-			    isb.append(':');
-		   		isb.append(info.project.getVersion());
-
-		        final StringWriter writer = new StringWriter();
-
-		        logger.debug("Generating id " + isb.toString() + " for feature file " + file);
-		        try ( final JsonGenerator generator = Json.createGenerator(writer) ) {
-		        	generator.writeStartObject();
-
-		        	generator.write("id", isb.toString());
-
-		        	for(final Map.Entry<String, JsonValue> entry : obj.entrySet()) {
-		                generator.write(entry.getKey(), entry.getValue());
-		        	}
-		        	generator.writeEnd();
-		        }
-
-		        json = writer.toString();
-		   	}
-		}
+    protected String preprocessFeature(final MavenProject project, boolean validate, final File file, String json) {
 
         // validate
-        if (config.isValidate()) {
+        if (validate) {
             checkFeatureFileValidation(file, json);
         }
 
-        // replace variables
-        return Substitution.replaceMavenVars(info.project, json);
+        return json;
 	}
 
-    private void checkFeatureId(final MavenProject project, final Feature feature) {
-        // check feature id
-        if ( !project.getGroupId().equals(feature.getId().getGroupId()) ) {
-            throw new RuntimeException("Wrong group id for feature. It should be " + project.getGroupId() + " but is " + feature.getId().getGroupId());
-        }
-        if ( !project.getArtifactId().equals(feature.getId().getArtifactId()) ) {
-            throw new RuntimeException("Wrong artifact id for feature. It should be " + project.getArtifactId() + " but is " + feature.getId().getArtifactId());
-        }
-        if ( !project.getVersion().equals(feature.getId().getVersion()) ) {
-            throw new RuntimeException("Wrong version for feature. It should be " + project.getVersion() + " but is " + feature.getId().getVersion());
-        }
-    }
-
     /**
      * Hook to post process the local feature
+     *
      * @param result The read feature
      * @return The post processed feature
      */
diff --git a/src/main/java/org/apache/sling/feature/maven/ProjectHelper.java b/src/main/java/org/apache/sling/feature/maven/ProjectHelper.java
index bc2d28c..50b141b 100644
--- a/src/main/java/org/apache/sling/feature/maven/ProjectHelper.java
+++ b/src/main/java/org/apache/sling/feature/maven/ProjectHelper.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -33,6 +34,13 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
 
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonValue;
+import javax.json.stream.JsonGenerator;
+
+import org.apache.felix.configurator.impl.json.JSMin;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
@@ -45,6 +53,7 @@ import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginExecution;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.utils.io.DirectoryScanner;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
@@ -137,14 +146,21 @@ public abstract class ProjectHelper {
         info.project.setContextValue(Preprocessor.class.getName(), Boolean.TRUE);
     }
 
-    public static void checkPreprocessorRun(final MavenProject project) {
+    /**
+     * Check that the preprocessor has been run
+     *
+     * @param project The maven project
+     * @return {@code null} if the preprocessor ran, an error string if not
+     */
+    public static String checkPreprocessorRun(final MavenProject project) {
         if (project.getContextValue(Preprocessor.class.getName()) == null) {
-            throw new RuntimeException("The slingfeature preprocessor did not run. "
-                    + "Please make sure to set <extensions>true</extensions> for the slingfeature plugin in your pom.");
+            return "The slingfeature preprocessor did not run. "
+                    + "Please make sure to set <extensions>true</extensions> for the slingfeature plugin in your pom.";
         }
         if (FeatureConstants.PACKAGING_FEATURE.equals(project.getPackaging()) && getFeatures(project).isEmpty()) {
-            throw new RuntimeException("Feature project has no features defined");
+            return "Feature project has no features defined";
         }
+        return null;
     }
 
     /**
@@ -455,4 +471,106 @@ public abstract class ProjectHelper {
         Map m = value;
         return m;
     }
+
+    public static void scan(final List<File> files, final File dir, final String includes, final String excludes) {
+        final DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir(dir);
+        if (includes != null) {
+            scanner.setIncludes(includes.split(","));
+        }
+        if (excludes != null) {
+            scanner.setExcludes(excludes.split(","));
+        }
+        scanner.scan();
+        for (final String f : scanner.getIncludedFiles()) {
+            files.add(new File(dir, f));
+        }
+    }
+
+    /**
+     * Read the json file, minify it, add id if missing and replace variables
+     *
+     * @param file The json file
+     * @return The read and minified JSON
+     */
+    public static String readFeatureFile(final MavenProject project, final File file,
+            final String suggestedClassifier) {
+        final StringBuilder sb = new StringBuilder();
+        try (final Reader reader = new FileReader(file)) {
+            final char[] buf = new char[4096];
+            int l = 0;
+
+            while ((l = reader.read(buf)) > 0) {
+                sb.append(buf, 0, l);
+            }
+        } catch (final IOException io) {
+            throw new RuntimeException("Unable to read feature " + file.getAbsolutePath(), io);
+        }
+        final String readJson = sb.toString();
+
+        // minify JSON (remove comments)
+        String json;
+        try (final Writer out = new StringWriter(); final Reader in = new StringReader(readJson)) {
+            final JSMin min = new JSMin(in, out);
+            min.jsmin();
+            json = out.toString();
+        } catch (final IOException e) {
+            throw new RuntimeException("Unable to read feature file " + file.getAbsolutePath(), e);
+        }
+
+        // check if "id" is set
+        try (final JsonReader reader = Json.createReader(new StringReader(json))) {
+            final JsonObject obj = reader.readObject();
+            if (!obj.containsKey("id")) {
+                final StringBuilder isb = new StringBuilder();
+                isb.append(project.getGroupId());
+                isb.append(':');
+                isb.append(project.getArtifactId());
+                isb.append(':');
+                isb.append(FeatureConstants.PACKAGING_FEATURE);
+
+                if (suggestedClassifier != null) {
+                    isb.append(':');
+                    isb.append(suggestedClassifier);
+                }
+                isb.append(':');
+                isb.append(project.getVersion());
+
+                final StringWriter writer = new StringWriter();
+
+                try (final JsonGenerator generator = Json.createGenerator(writer)) {
+                    generator.writeStartObject();
+
+                    generator.write("id", isb.toString());
+
+                    for (final Map.Entry<String, JsonValue> entry : obj.entrySet()) {
+                        generator.write(entry.getKey(), entry.getValue());
+                    }
+                    generator.writeEnd();
+                }
+
+                json = writer.toString();
+            }
+        }
+
+        // replace variables
+        return Substitution.replaceMavenVars(project, json);
+    }
+
+    public static void checkFeatureId(final MavenProject project, final Feature feature) {
+        // check feature id
+        if (!project.getGroupId().equals(feature.getId().getGroupId())) {
+            throw new RuntimeException("Wrong group id for feature. It should be " + project.getGroupId() + " but is "
+                    + feature.getId().getGroupId());
+        }
+        if (!project.getArtifactId().equals(feature.getId().getArtifactId())) {
+            throw new RuntimeException("Wrong artifact id for feature. It should be " + project.getArtifactId()
+                    + " but is " + feature.getId().getArtifactId());
+        }
+        if (!project.getVersion().equals(feature.getId().getVersion())) {
+            throw new RuntimeException("Wrong version for feature. It should be " + project.getVersion() + " but is "
+                    + feature.getId().getVersion());
+        }
+    }
+
 }
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/AbstractFeatureMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/AbstractFeatureMojo.java
index beb77c0..13dbb40 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/AbstractFeatureMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/AbstractFeatureMojo.java
@@ -17,27 +17,45 @@
 package org.apache.sling.feature.maven.mojos;
 
 import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugins.annotations.Component;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.MavenProjectHelper;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.builder.ArtifactProvider;
+import org.apache.sling.feature.builder.BuilderContext;
+import org.apache.sling.feature.builder.FeatureBuilder;
+import org.apache.sling.feature.builder.FeatureProvider;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
 import org.apache.sling.feature.maven.FeatureProjectConfig;
+import org.apache.sling.feature.maven.ProjectHelper;
 
 /**
  * Base class for all mojos.
  */
 public abstract class AbstractFeatureMojo extends AbstractMojo {
 
-	/**
-	 * All of the below configurations are handled by the Preprocessor.
-	 * Mojos should only use them for informational purposes but not
-	 * for processing!
-	 * The read features and test features are available through the
-	 * ProjectHelper.
-	 */
+    private static final String PROPERTY_HANDLED_GENERATED_FEATURES = Feature.class.getName() + "/generated";
+
+    /**
+     * All of the below configurations are handled by the Preprocessor. Mojos should
+     * only use them for informational purposes but not for processing! The read
+     * features and test features are available through the ProjectHelper.
+     */
 
     /**
      * Directory containing feature files
@@ -121,6 +139,12 @@ public abstract class AbstractFeatureMojo extends AbstractMojo {
     private boolean skipAddJarToTestFeature;
 
     /**
+     * Directory containing generated feature files
+     */
+    @Parameter
+    protected File generatedFeatures;
+
+    /**
      * The start level for the attached jar/bundle.
      */
     @Parameter(name=FeatureProjectConfig.CFG_JAR_START_ORDER)
@@ -135,9 +159,130 @@ public abstract class AbstractFeatureMojo extends AbstractMojo {
     @Component
     protected MavenProjectHelper projectHelper;
 
+    @Component
+    ArtifactHandlerManager artifactHandlerManager;
+
+    @Component
+    ArtifactResolver artifactResolver;
+
     protected File getTmpDir() {
         final File dir = new File(this.project.getBuild().getDirectory(), "slingfeature-tmp");
         dir.mkdirs();
         return dir;
     }
+
+    /**
+     * This method needs to be invoked by each mojo that deals with features
+     *
+     * @throws MojoExecutionException
+     */
+    protected void checkPreconditions() throws MojoExecutionException {
+        final String errorMessage = ProjectHelper.checkPreprocessorRun(this.project);
+        if (errorMessage != null) {
+            throw new MojoExecutionException(errorMessage);
+        }
+
+        // make sure to check for generated features only once
+        if (this.project.getContextValue(PROPERTY_HANDLED_GENERATED_FEATURES) == null) {
+
+            this.handleGeneratedFeatures();
+
+            this.project.setContextValue(PROPERTY_HANDLED_GENERATED_FEATURES, Boolean.TRUE);
+        }
+    }
+
+    private void handleGeneratedFeatures() throws MojoExecutionException {
+        if (this.generatedFeatures != null) {
+            if (!this.generatedFeatures.exists()) {
+                throw new MojoExecutionException("Directory does not exists: " + this.generatedFeatures);
+            }
+            if (!this.generatedFeatures.isDirectory()) {
+                throw new MojoExecutionException(
+                        "Generated features configuration is not a directory: " + this.generatedFeatures);
+            }
+
+            final List<File> files = new ArrayList<>();
+            ProjectHelper.scan(files, this.generatedFeatures, null, null);
+
+            for (final File file : files) {
+                getLog().debug("Reading feature file " + file);
+                try {
+                    final String json = ProjectHelper.readFeatureFile(project, file, null);
+
+                    try (final Reader reader = new StringReader(json)) {
+                        final Feature feature = FeatureJSONReader.read(reader, file.getAbsolutePath());
+
+                        ProjectHelper.checkFeatureId(project, feature);
+
+                        ProjectHelper.setFeatureInfo(project, feature);
+
+                        // Add feature to map of features
+                        final String key = file.toPath().normalize().toFile().getAbsolutePath();
+                        ProjectHelper.getFeatures(this.project).put(key, feature);
+
+                        // assemble feature and add
+                        final Feature assembledFeature = FeatureBuilder.assemble(feature, getBuilderContext());
+                        ProjectHelper.getAssembledFeatures(project).put(key, assembledFeature);
+
+                        // finally validate classifier
+                        ProjectHelper.validateFeatureClassifiers(project);
+                    } catch (final IOException io) {
+                        throw new MojoExecutionException("Unable to read feature " + file.getAbsolutePath(), io);
+                    }
+                } catch (final RuntimeException re) {
+                    // this is a bit unusual, but as ProjectHelper can only throw RuntimeException
+                    // it's
+                    // more user friendly to catch it and rethrow a mojo friendly exception
+                    throw new MojoExecutionException(re.getMessage(), re.getCause());
+                }
+            }
+        }
+    }
+
+    private BuilderContext getBuilderContext() {
+        final BuilderContext builderContext = new BuilderContext(new FeatureProvider() {
+            @Override
+            public Feature provide(ArtifactId id) {
+                // Check for the feature in the local context
+                for (final Feature feat : ProjectHelper.getAssembledFeatures(project).values()) {
+                    if (feat.getId().equals(id)) {
+                        return feat;
+                    }
+                }
+
+                if (ProjectHelper.isLocalProjectArtifact(project, id)) {
+                    throw new RuntimeException("Unable to resolve local artifact " + id.toMvnId());
+                }
+
+                // Finally, look the feature up via Maven's dependency mechanism
+                return ProjectHelper.getOrResolveFeature(project, mavenSession, artifactHandlerManager,
+                        artifactResolver, id);
+            }
+        }).setArtifactProvider(new ArtifactProvider() {
+
+            @Override
+            public URL provide(final ArtifactId id) {
+                if (ProjectHelper.isLocalProjectArtifact(project, id)) {
+                    for (final Map.Entry<String, Feature> entry : ProjectHelper.getAssembledFeatures(project)
+                            .entrySet()) {
+                        if (entry.getValue().getId().equals(id)) {
+                            // TODO - we might need to create a file to return it here
+                            throw new RuntimeException(
+                                    "Unable to get file for project feature " + entry.getValue().getId().toMvnId());
+                        }
+                    }
+                }
+                try {
+                    return ProjectHelper
+                            .getOrResolveArtifact(project, mavenSession, artifactHandlerManager, artifactResolver, id)
+                            .getFile().toURI().toURL();
+                } catch (Exception e) {
+                    getLog().error(e);
+                    return null;
+                }
+            }
+        });
+
+        return builderContext;
+    }
 }
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/AbstractIncludingFeatureMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/AbstractIncludingFeatureMojo.java
index 18206ae..90d8968 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/AbstractIncludingFeatureMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/AbstractIncludingFeatureMojo.java
@@ -24,10 +24,7 @@ import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.TreeMap;
 
-import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
-import org.apache.maven.artifact.resolver.ArtifactResolver;
 import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.annotations.Component;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.maven.ProjectHelper;
@@ -35,12 +32,6 @@ import org.codehaus.plexus.util.AbstractScanner;
 
 public abstract class AbstractIncludingFeatureMojo extends AbstractFeatureMojo {
 
-    @Component
-    ArtifactHandlerManager artifactHandlerManager;
-
-    @Component
-    ArtifactResolver artifactResolver;
-
     protected Map<String, Feature> getSelectedFeatures(final FeatureSelectionConfig config)
             throws MojoExecutionException {
         final Map<String, Feature> result = new LinkedHashMap<>();
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/AggregateFeaturesMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/AggregateFeaturesMojo.java
index e6f83e0..cfe8ce3 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/AggregateFeaturesMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/AggregateFeaturesMojo.java
@@ -68,7 +68,7 @@ public class AggregateFeaturesMojo extends AbstractIncludingFeatureMojo {
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        ProjectHelper.checkPreprocessorRun(this.project);
+        checkPreconditions();
         for (final Aggregate aggregate : aggregates) {
             // check classifier
             ProjectHelper.validateFeatureClassifiers(this.project, aggregate.classifier, aggregate.attach);
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/AnalyseFeaturesMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/AnalyseFeaturesMojo.java
index 2ab0815..1bb74d5 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/AnalyseFeaturesMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/AnalyseFeaturesMojo.java
@@ -63,7 +63,7 @@ public class AnalyseFeaturesMojo extends AbstractIncludingFeatureMojo {
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        ProjectHelper.checkPreprocessorRun(this.project);
+        checkPreconditions();
         List<Scan> list = scans;
         if (list == null || list.isEmpty()) {
             // use default configuration
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
index 49cdbb4..bfb45bb 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
@@ -165,7 +165,7 @@ public class ApisJarMojo extends AbstractIncludingFeatureMojo implements Artifac
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        ProjectHelper.checkPreprocessorRun(this.project);
+        checkPreconditions();
 
         artifactProvider = new ArtifactProvider() {
 
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/AttachFeaturesMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/AttachFeaturesMojo.java
index 85040a0..b1a2e30 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/AttachFeaturesMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/AttachFeaturesMojo.java
@@ -96,7 +96,7 @@ public class AttachFeaturesMojo extends AbstractFeatureMojo {
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        ProjectHelper.checkPreprocessorRun(this.project);
+        checkPreconditions();
         final List<String> featureUrls = new ArrayList<>();
         this.attachClassifierFeatures(ProjectHelper.getFeatures(this.project), featureUrls, this.attachMainFeatures);
         this.attachClassifierFeatures(ProjectHelper.getTestFeatures(this.project), featureUrls,
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/EmbedFeaturesMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/EmbedFeaturesMojo.java
index 8a12a42..fa5448b 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/EmbedFeaturesMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/EmbedFeaturesMojo.java
@@ -30,7 +30,6 @@ import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.io.json.FeatureJSONWriter;
-import org.apache.sling.feature.maven.ProjectHelper;
 
 /**
  * Embed the features in the resources
@@ -75,7 +74,7 @@ public class EmbedFeaturesMojo extends AbstractIncludingFeatureMojo {
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        ProjectHelper.checkPreprocessorRun(this.project);
+        checkPreconditions();
 
         final Map<String, Feature> features = embed == null ? this.selectAllFeatureFilesAndAggregates()
                 : this.getSelectedFeatures(embed);
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/ReportingMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/ReportingMojo.java
index 2f60074..e4f1f3f 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/ReportingMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/ReportingMojo.java
@@ -28,7 +28,6 @@ import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.maven.ProjectHelper;
 
 import edu.emory.mathcs.backport.java.util.Collections;
 
@@ -43,7 +42,7 @@ public class ReportingMojo extends AbstractIncludingFeatureMojo {
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        ProjectHelper.checkPreprocessorRun(this.project);
+        checkPreconditions();
         // get the features
         final Map<String, Feature> features = this.selectAllFeatureFiles();
         if (features.isEmpty()) {
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/RepositoryMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/RepositoryMojo.java
index 7102b50..d087548 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/RepositoryMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/RepositoryMojo.java
@@ -27,7 +27,6 @@ import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.maven.ProjectHelper;
 
 /**
  * Create a Maven repository structure from the referenced artifacts in the features.
@@ -45,7 +44,7 @@ public class RepositoryMojo extends AbstractRepositoryMojo {
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        ProjectHelper.checkPreprocessorRun(this.project);
+        checkPreconditions();
         if (repositories == null || repositories.isEmpty()) {
             final File artifactDir = new File(this.project.getBuild().getDirectory(), this.repositoryDir);
             this.doExecute(artifactDir, this.selectAllFeatureFilesAndAggregates(), null);
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/UpdateVersionsMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/UpdateVersionsMojo.java
index 0e53b86..f8d243c 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/UpdateVersionsMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/UpdateVersionsMojo.java
@@ -163,7 +163,7 @@ public class UpdateVersionsMojo extends AbstractIncludingFeatureMojo {
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
-        ProjectHelper.checkPreprocessorRun(this.project);
+        checkPreconditions();
         // get the features
         final Map<String, Feature> assembledFeatures = this.getFeatures();
         if (assembledFeatures.isEmpty()) {