diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index dcd59b0645..313d590327 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -43,6 +43,8 @@ This is now fixed, but might result in build previously working now fail due to
backports:
- Support for implicit dependencies in target definitions
- Add tycho-baseline:check-dependencies mojo
+- Add tycho-cleancode plugin
+
## 4.0.10
diff --git a/pom.xml b/pom.xml
index ef3300804f..5f7cf98da0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -595,6 +595,7 @@
tycho-repository-plugin
tycho-eclipse-plugin
tycho-wrap-plugin
+ tycho-cleancode-plugin
diff --git a/tycho-cleancode-plugin/.settings/org.eclipse.jdt.core.prefs b/tycho-cleancode-plugin/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..eeac0e762f
--- /dev/null
+++ b/tycho-cleancode-plugin/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
+org.eclipse.jdt.core.compiler.compliance=17
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=17
diff --git a/tycho-cleancode-plugin/pom.xml b/tycho-cleancode-plugin/pom.xml
new file mode 100644
index 0000000000..ed70a6d5f2
--- /dev/null
+++ b/tycho-cleancode-plugin/pom.xml
@@ -0,0 +1,64 @@
+
+ 4.0.0
+
+ org.eclipse.tycho
+ tycho
+ 4.0.11-SNAPSHOT
+
+ tycho-cleancode-plugin
+ Tycho Eclipse Plugin
+ maven-plugin
+
+ ${minimal-maven-version}
+
+ Maven Plugins for performing automatic code clean options
+
+
+ org.apache.maven
+ maven-core
+
+
+ org.apache.maven
+ maven-plugin-api
+
+
+ org.apache.maven.plugin-tools
+ maven-plugin-annotations
+
+
+ org.eclipse.tycho
+ tycho-eclipse-plugin
+ ${project.version}
+
+
+ org.eclipse.jdt
+ org.eclipse.jdt.ui
+ 3.33.200
+
+
+ org.eclipse.jdt
+ org.eclipse.jdt.core.manipulation
+ 1.21.300
+
+
+
+
+
+
+ org.codehaus.plexus
+ plexus-component-metadata
+
+
+ org.apache.maven.plugins
+ maven-plugin-plugin
+
+
+ tycho-cleancode
+
+
+
+
+
\ No newline at end of file
diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUp.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUp.java
new file mode 100644
index 0000000000..6c85f26204
--- /dev/null
+++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUp.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Christoph Läubrich and others.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.cleancode;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.corext.fix.CleanUpPreferenceUtil;
+import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring;
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.fix.MapCleanUpOptions;
+import org.eclipse.jdt.ui.cleanup.CleanUpOptions;
+import org.eclipse.jdt.ui.cleanup.ICleanUp;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.tycho.eclipsebuild.AbstractEclipseBuild;
+
+public class CleanUp extends AbstractEclipseBuild {
+
+ private Map customProfile;
+
+ CleanUp(Path projectDir, boolean debug, Map customProfile) {
+ super(projectDir, debug);
+ this.customProfile = customProfile;
+ }
+
+ @Override
+ protected CleanupResult createResult(IProject project) throws Exception {
+ CleanupResult result = new CleanupResult();
+ CleanUpOptions options = getOptions(project);
+ ICleanUp[] cleanups = getCleanups(result, options);
+ if (cleanups.length > 0) {
+ List units = getCompilationUnits(project);
+ final CleanUpRefactoring refactoring = new CleanUpRefactoring(project.getName());
+ for (ICompilationUnit cu : units) {
+ refactoring.addCompilationUnit(cu);
+ }
+ refactoring.setUseOptionsFromProfile(false);
+ for (ICleanUp cleanUp : cleanups) {
+ refactoring.addCleanUp(cleanUp);
+ }
+ final RefactoringStatus status = refactoring.checkAllConditions(this);
+ if (status.isOK()) {
+ Change change = refactoring.createChange(this);
+ change.initializeValidationData(this);
+ PerformChangeOperation performChangeOperation = new PerformChangeOperation(change);
+ performChangeOperation.run(this);
+ } else if (status.hasError()) {
+ throw new RuntimeException("Refactoring failed: " + status);
+ }
+ }
+ return result;
+ }
+
+ private List getCompilationUnits(IProject project) throws JavaModelException {
+ IJavaProject javaProject = JavaCore.create(project);
+ List units = new ArrayList();
+ IPackageFragmentRoot[] packages = javaProject.getPackageFragmentRoots();
+ for (IPackageFragmentRoot root : packages) {
+ if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
+ for (IJavaElement javaElement : root.getChildren()) {
+ if (javaElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+ IPackageFragment pf = (IPackageFragment) javaElement;
+ ICompilationUnit[] compilationUnits = pf.getCompilationUnits();
+ for (ICompilationUnit compilationUnit : compilationUnits) {
+ units.add(compilationUnit);
+ }
+ }
+ }
+ }
+ }
+ return units;
+ }
+
+ private ICleanUp[] getCleanups(CleanupResult result, CleanUpOptions options) {
+ ICleanUp[] cleanUps = JavaPlugin.getDefault().getCleanUpRegistry().createCleanUps();
+ for (ICleanUp cleanUp : cleanUps) {
+ try {
+ cleanUp.setOptions(options);
+ String[] descriptions = cleanUp.getStepDescriptions();
+ if (descriptions != null) {
+ for (String description : descriptions) {
+ result.addCleanup(description);
+ }
+ }
+ } catch (Exception e) {
+ debug("Ignore cleanup '" + cleanUp + "' because of initialization error.", e);
+ }
+ }
+ return cleanUps;
+ }
+
+ private CleanUpOptions getOptions(IProject project) {
+ Map options;
+ if (customProfile == null || customProfile.isEmpty()) {
+ options = CleanUpPreferenceUtil.loadOptions(new ProjectScope(project));
+ } else {
+ options = customProfile;
+ }
+ debug("Cleanup Profile: " + options.entrySet().stream().map(e -> e.getKey() + " = " + e.getValue())
+ .collect(Collectors.joining(System.lineSeparator())));
+ return new MapCleanUpOptions(options);
+ }
+
+}
diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUpMojo.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUpMojo.java
new file mode 100644
index 0000000000..c76a103bed
--- /dev/null
+++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUpMojo.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2023 Christoph Läubrich and others.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.cleancode;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.maven.plugin.MojoFailureException;
+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.plugins.annotations.ResolutionScope;
+import org.eclipse.tycho.eclipsebuild.AbstractEclipseBuildMojo;
+import org.eclipse.tycho.model.project.EclipseProject;
+
+/**
+ * This mojo allows to perform eclipse cleanup action
+ */
+@Mojo(name = "cleanup", defaultPhase = LifecyclePhase.PROCESS_SOURCES, threadSafe = true, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
+public class CleanUpMojo extends AbstractEclipseBuildMojo {
+
+ @Parameter(defaultValue = "${project.build.directory}/cleanups.md", property = "tycho.cleanup.report")
+ private File reportFileName;
+
+ /**
+ * Defines key value pairs of a cleanup profile, if not defined will use the
+ * project defaults
+ */
+ @Parameter
+ private Map cleanUpProfile;
+
+ @Override
+ protected String[] getRequireBundles() {
+ return new String[] { "org.eclipse.jdt.ui" };
+ }
+
+ @Override
+ protected String getName() {
+ return "Perform Cleanup";
+ }
+
+ @Override
+ protected CleanUp createExecutable() {
+ return new CleanUp(project.getBasedir().toPath(), debug, cleanUpProfile);
+ }
+
+ @Override
+ protected void handleResult(CleanupResult result)
+ throws MojoFailureException {
+ List results = new ArrayList<>();
+ results.add("The following cleanups where applied:");
+ result.cleanups().forEach(cleanup -> {
+ results.add("- " + cleanup);
+ });
+ try {
+ Files.writeString(reportFileName.toPath(),
+ results.stream().collect(Collectors.joining(System.lineSeparator())));
+ } catch (IOException e) {
+ throw new MojoFailureException(e);
+ }
+ }
+
+ @Override
+ protected boolean isValid(EclipseProject eclipseProject) {
+ // Cleanups can only be applied to java projects
+ return eclipseProject.hasNature("org.eclipse.jdt.core.javanature");
+ }
+
+}
diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanupResult.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanupResult.java
new file mode 100644
index 0000000000..11b2d45623
--- /dev/null
+++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanupResult.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Christoph Läubrich and others.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.cleancode;
+
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Stream;
+
+import org.eclipse.tycho.eclipsebuild.EclipseBuildResult;
+
+public class CleanupResult extends EclipseBuildResult {
+
+ private Set cleanups = new TreeSet();
+
+ public void addCleanup(String cleanup) {
+ cleanups.add(cleanup);
+ }
+
+ public Stream cleanups() {
+ return this.cleanups.stream();
+ }
+
+}
diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFix.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFix.java
new file mode 100644
index 0000000000..a76f23c22a
--- /dev/null
+++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFix.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Christoph Läubrich and others.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.cleancode;
+
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.tycho.eclipsebuild.AbstractEclipseBuild;
+import org.eclipse.ui.IMarkerResolution;
+import org.eclipse.ui.IMarkerResolution2;
+import org.eclipse.ui.IMarkerResolutionRelevance;
+import org.eclipse.ui.ide.IDE;
+
+/**
+ * Applies the QuickFix with the highest relevance to a warning, because
+ * QuickFixes are not really optimized to run in a CI build we need to be very
+ * forgiving here and handle errors gracefully.
+ */
+public class QuickFix extends AbstractEclipseBuild {
+
+ QuickFix(Path projectDir, boolean debug) {
+ super(projectDir, debug);
+ }
+
+ @Override
+ protected QuickFixResult createResult(IProject project) throws Exception {
+ QuickFixResult result = new QuickFixResult();
+ IMarker[] markers = project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
+ result.setNumberOfMarker(markers.length);
+ for (IMarker marker : markers) {
+ debug("Marker: " + marker);
+ try {
+ IMarkerResolution[] resolutions = IDE.getMarkerHelpRegistry().getResolutions(marker);
+ debug("Marker has " + resolutions.length + " resolutions");
+ IMarkerResolution resolution = Arrays.stream(resolutions)
+ .max(Comparator.comparingInt(r -> getRelevance(r))).orElse(null);
+ if (resolution != null) {
+ debug("Apply best resolution to marker: " + getInfo(resolution));
+ // must use an own thread to make sure it is not called as a job
+ AtomicReference error = new AtomicReference();
+ Thread thread = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ resolution.run(marker);
+ } catch (Throwable t) {
+ error.set(t);
+ }
+ }
+ });
+ thread.start();
+ thread.join();
+ Throwable t = error.get();
+ if (t == null) {
+ result.addFix(buildFixMessage(marker));
+ } else {
+ debug("Marker could not be applied!", t);
+ }
+ }
+ } catch (Throwable t) {
+ debug("Marker resolutions could not be computed!", t);
+ }
+ }
+ return result;
+ }
+
+ private String buildFixMessage(IMarker marker) {
+ StringBuilder sb = new StringBuilder(marker.getAttribute(IMarker.MESSAGE, "Unknown Problem"));
+ IResource resource = marker.getResource();
+ if (resource != null) {
+ sb.append(" in ");
+ sb.append(resource.getFullPath());
+ int line = marker.getAttribute(IMarker.LINE_NUMBER, -1);
+ if (line > 0) {
+ sb.append(" at line ");
+ sb.append(line);
+ }
+ }
+ return sb.toString();
+ }
+
+ private String getInfo(IMarkerResolution resolution) {
+ if (resolution instanceof IMarkerResolution2 res2) {
+ return resolution.getClass().getName() + ": " + getLabel(resolution) + " // " + getDescription(res2);
+ } else {
+ return resolution.getClass().getName() + ": " + getLabel(resolution);
+ }
+ }
+
+ private int getRelevance(IMarkerResolution resolution) {
+ try {
+ if (resolution instanceof IMarkerResolutionRelevance relevance) {
+ return relevance.getRelevanceForResolution();
+ }
+ } catch (RuntimeException e) {
+ }
+ return -1;
+ }
+
+ private String getDescription(IMarkerResolution2 markerResolution) {
+ try {
+ return markerResolution.getDescription();
+ } catch (RuntimeException e) {
+ return null;
+ }
+ }
+
+ private String getLabel(IMarkerResolution resolution) {
+ try {
+ return resolution.getLabel();
+ } catch (RuntimeException e) {
+ return resolution.getClass().getName();
+ }
+ }
+
+}
diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixMojo.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixMojo.java
new file mode 100644
index 0000000000..5b4f5b96fc
--- /dev/null
+++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixMojo.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Christoph Läubrich and others.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.cleancode;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.maven.plugin.MojoFailureException;
+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.plugins.annotations.ResolutionScope;
+import org.eclipse.tycho.eclipsebuild.AbstractEclipseBuildMojo;
+
+@Mojo(name = "quickfix", defaultPhase = LifecyclePhase.PROCESS_SOURCES, threadSafe = true, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
+public class QuickFixMojo extends AbstractEclipseBuildMojo {
+
+ @Parameter(defaultValue = "${project.build.directory}/quickfix.md", property = "tycho.quickfix.report")
+ private File reportFileName;
+
+ @Override
+ protected void handleResult(QuickFixResult result) throws MojoFailureException {
+ List results = new ArrayList<>();
+ if (result.getMarkers() == 0) {
+ results.add("Project is clean!");
+ } else {
+ List fixes = result.fixes().toList();
+ if (fixes.isEmpty()) {
+ results.add("Nothing has been resolved in this project.");
+ } else {
+ results.add("The following " + (fixes.size() > 0 ? "warnings" : "warning") + " has been resolved:");
+ fixes.forEach(fix -> {
+ results.add("- " + fix);
+ });
+ }
+ }
+ try {
+ Files.writeString(reportFileName.toPath(),
+ results.stream().collect(Collectors.joining(System.lineSeparator())));
+ } catch (IOException e) {
+ throw new MojoFailureException(e);
+ }
+ }
+
+ @Override
+ protected String[] getRequireBundles() {
+ return new String[] { "org.eclipse.ui.ide", "org.eclipse.jdt.ui" };
+ }
+
+ @Override
+ protected QuickFix createExecutable() {
+ return new QuickFix(project.getBasedir().toPath(), debug);
+ }
+
+ @Override
+ protected String getName() {
+ return "Quick Fix";
+ }
+
+}
diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixResult.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixResult.java
new file mode 100644
index 0000000000..8bacea8902
--- /dev/null
+++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixResult.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Christoph Läubrich and others.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.cleancode;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.eclipse.tycho.eclipsebuild.EclipseBuildResult;
+
+public class QuickFixResult extends EclipseBuildResult {
+
+ private List fixed = new ArrayList<>();
+ private int markers;
+
+ public Stream fixes() {
+ return fixed.stream();
+ }
+
+ public void addFix(String fix) {
+ fixed.add(fix);
+ }
+
+ public void setNumberOfMarker(int markers) {
+ this.markers = markers;
+ }
+
+ public int getMarkers() {
+ return markers;
+ }
+
+}
diff --git a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java
index 199607b938..46c449db14 100644
--- a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java
+++ b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java
@@ -1,7 +1,9 @@
package org.eclipse.tycho.eclipsebuild;
import java.io.IOException;
+import java.io.PrintWriter;
import java.io.Serializable;
+import java.io.StringWriter;
import java.nio.file.Path;
import java.util.concurrent.Callable;
@@ -83,6 +85,14 @@ protected void debug(String string) {
}
}
+ protected void debug(String string, Throwable t) {
+ if (debug) {
+ StringWriter writer = new StringWriter();
+ t.printStackTrace(new PrintWriter(writer));
+ debug(string + System.lineSeparator() + writer);
+ }
+ }
+
static String pathAsString(Path path) {
if (path != null) {
return path.toAbsolutePath().toString();
diff --git a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java
index c9e4717f3a..6fc02b9209 100644
--- a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java
+++ b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java
@@ -96,6 +96,9 @@ public final void execute() throws MojoExecutionException, MojoFailureException
return;
}
EclipseProject eclipseProject = eclipseProjectValue.get();
+ if (!isValid(eclipseProject)) {
+ return;
+ }
Collection projectDependencies;
try {
projectDependencies = projectManager.getProjectDependencies(project);
@@ -145,6 +148,10 @@ public final void execute() throws MojoExecutionException, MojoFailureException
}
}
+ protected boolean isValid(EclipseProject eclipseProject) {
+ return true;
+ }
+
protected abstract void handleResult(Result result) throws MojoFailureException;
protected abstract AbstractEclipseBuild createExecutable();