From 0134866dee959d0fb42b879d32b76834558b1332 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Sun, 28 Jan 2024 16:16:45 +0100 Subject: [PATCH] Fix #401 - Maven v4 compatibility --- .github/workflows/maven.yml | 5 +- pom.xml | 26 ++----- .../verify.groovy | 2 +- src/it/projects/setup-parent/pom.xml | 5 ++ .../toolchains-paths/invoker.properties | 1 + src/it/projects/toolchains-paths/pom.xml | 58 +++++++++++++++ src/it/projects/toolchains-paths/scripts/test | 2 + .../toolchains-paths/scripts/test.cmd | 1 + .../projects/toolchains-paths/toolchains.xml | 14 ++++ .../projects/toolchains-paths/verify.groovy | 5 ++ .../java/org/codehaus/mojo/exec/ExecMojo.java | 24 ++---- .../codehaus/mojo/exec/PathsToolchain.java | 45 +++++++++--- .../mojo/exec/PathsToolchainFactory.java | 73 ++++--------------- 13 files changed, 151 insertions(+), 110 deletions(-) create mode 100644 src/it/projects/toolchains-paths/invoker.properties create mode 100644 src/it/projects/toolchains-paths/pom.xml create mode 100755 src/it/projects/toolchains-paths/scripts/test create mode 100644 src/it/projects/toolchains-paths/scripts/test.cmd create mode 100644 src/it/projects/toolchains-paths/toolchains.xml create mode 100644 src/it/projects/toolchains-paths/verify.groovy diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 3e953733..82d1985e 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -24,6 +24,5 @@ jobs: name: Verify uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v3 with: - jdk-matrix: '[ "8", "17", "21" ]' - ff-maven: "3.9.5" # Maven version for fail-fast-build - maven-matrix: '[ "3.6.3", "3.8.8", "3.9.5" ]' # Maven versions matrix for verify builds + ff-maven: "3.9.6" # Maven version for fail-fast-build + maven-matrix: '[ "3.6.3", "3.9.6", "4.0.0-alpha-12" ]' # Maven versions matrix for verify builds diff --git a/pom.xml b/pom.xml index 5bcf4d49..34404cc0 100644 --- a/pom.xml +++ b/pom.xml @@ -181,13 +181,6 @@ provided - - org.codehaus.plexus - plexus-component-annotations - 2.2.0 - true - - org.apache.commons commons-exec @@ -261,6 +254,9 @@ org.apache.maven.plugins maven-compiler-plugin + + none + default-testCompile @@ -296,18 +292,6 @@ - - org.codehaus.plexus - plexus-component-metadata - 2.2.0 - - - - generate-metadata - - - - org.apache.maven.plugins maven-dependency-plugin @@ -352,6 +336,10 @@ + + org.eclipse.sisu + sisu-maven-plugin + diff --git a/src/it/projects/mexec-gh-389-block-exit-non-zero/verify.groovy b/src/it/projects/mexec-gh-389-block-exit-non-zero/verify.groovy index 914185bf..63b4ffeb 100644 --- a/src/it/projects/mexec-gh-389-block-exit-non-zero/verify.groovy +++ b/src/it/projects/mexec-gh-389-block-exit-non-zero/verify.groovy @@ -24,4 +24,4 @@ assert buildLogLines[infoMessageLineNumber - 1] == "[one, two, three]" // Verify that subsequent lines contain the beginning of the thrown SystemExitException stack trace assert buildLogLines[infoMessageLineNumber + 1].startsWith("[WARNING]") assert buildLogLines[infoMessageLineNumber + 2].contains("SystemExitException: System::exit was called with return code 123") -assert buildLogLines[infoMessageLineNumber + 3].contains("SystemExitManager.exit (SystemExitManager.java") +assert buildLogLines[infoMessageLineNumber + 3].matches(".*SystemExitManager.exit ?\\(SystemExitManager.java.*") diff --git a/src/it/projects/setup-parent/pom.xml b/src/it/projects/setup-parent/pom.xml index 0c907107..a849490a 100644 --- a/src/it/projects/setup-parent/pom.xml +++ b/src/it/projects/setup-parent/pom.xml @@ -86,6 +86,11 @@ maven-resources-plugin @maven-resources-plugin.version@ + + org.apache.maven.plugins + maven-toolchains-plugin + 3.1.0 + diff --git a/src/it/projects/toolchains-paths/invoker.properties b/src/it/projects/toolchains-paths/invoker.properties new file mode 100644 index 00000000..6150ccc3 --- /dev/null +++ b/src/it/projects/toolchains-paths/invoker.properties @@ -0,0 +1 @@ +invoker.goals = --toolchains toolchains.xml validate diff --git a/src/it/projects/toolchains-paths/pom.xml b/src/it/projects/toolchains-paths/pom.xml new file mode 100644 index 00000000..491f3b64 --- /dev/null +++ b/src/it/projects/toolchains-paths/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + + + org.codehaus.mojo.exec.it + parent + 0.1 + + + toolchains-paths + 0.0.1-SNAPSHOT + pom + + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + + my-paths + + + + + + + toolchain + + + + + + org.codehaus.mojo + exec-maven-plugin + @project.version@ + true + + test + paths + + + + execution + + exec + + validate + + + + + + diff --git a/src/it/projects/toolchains-paths/scripts/test b/src/it/projects/toolchains-paths/scripts/test new file mode 100755 index 00000000..31b00be9 --- /dev/null +++ b/src/it/projects/toolchains-paths/scripts/test @@ -0,0 +1,2 @@ +#! /bin/sh +echo Hello from exec-maven-plugin diff --git a/src/it/projects/toolchains-paths/scripts/test.cmd b/src/it/projects/toolchains-paths/scripts/test.cmd new file mode 100644 index 00000000..c3f2f961 --- /dev/null +++ b/src/it/projects/toolchains-paths/scripts/test.cmd @@ -0,0 +1 @@ +echo Hello from exec-maven-plugin diff --git a/src/it/projects/toolchains-paths/toolchains.xml b/src/it/projects/toolchains-paths/toolchains.xml new file mode 100644 index 00000000..9bff3212 --- /dev/null +++ b/src/it/projects/toolchains-paths/toolchains.xml @@ -0,0 +1,14 @@ + + + + paths + + my-paths + + + + scripts + + + + diff --git a/src/it/projects/toolchains-paths/verify.groovy b/src/it/projects/toolchains-paths/verify.groovy new file mode 100644 index 00000000..6222c702 --- /dev/null +++ b/src/it/projects/toolchains-paths/verify.groovy @@ -0,0 +1,5 @@ +File log = new File(basedir, 'build.log') + +assert log.exists() +assert log.getText().contains( "[INFO] Toolchain in exec-maven-plugin: Paths[scripts]" ) +assert log.getText().contains( "Hello from exec-maven-plugin" ) \ No newline at end of file diff --git a/src/main/java/org/codehaus/mojo/exec/ExecMojo.java b/src/main/java/org/codehaus/mojo/exec/ExecMojo.java index 4dae13d2..797551e4 100644 --- a/src/main/java/org/codehaus/mojo/exec/ExecMojo.java +++ b/src/main/java/org/codehaus/mojo/exec/ExecMojo.java @@ -59,13 +59,13 @@ import org.apache.maven.artifact.resolver.filter.IncludesArtifactFilter; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import org.apache.maven.toolchain.Toolchain; import org.apache.maven.toolchain.ToolchainManager; -import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.CommandLineUtils; @@ -344,6 +344,9 @@ public class ExecMojo extends AbstractExecMojo { @Parameter(property = "exec.asyncDestroyOnShutdown", defaultValue = "true") private boolean asyncDestroyOnShutdown = true; + @Component + private ToolchainManager toolchainManager; + public static final String CLASSPATH_TOKEN = "%classpath"; public static final String MODULEPATH_TOKEN = "%modulepath"; @@ -936,22 +939,11 @@ public int[] getSuccessCodes() { } private Toolchain getToolchain() { - Toolchain tc = null; - - try { - if (session != null) // session is null in tests.. - { - ToolchainManager toolchainManager = - (ToolchainManager) session.getContainer().lookup(ToolchainManager.ROLE); - - if (toolchainManager != null) { - tc = toolchainManager.getToolchainFromBuildContext(toolchain, session); - } - } - } catch (ComponentLookupException componentLookupException) { - // just ignore, could happen in pre-2.0.9 builds.. + // session and toolchainManager can be null in tests ... + if (session != null && toolchainManager != null) { + return toolchainManager.getToolchainFromBuildContext(toolchain, session); } - return tc; + return null; } /** diff --git a/src/main/java/org/codehaus/mojo/exec/PathsToolchain.java b/src/main/java/org/codehaus/mojo/exec/PathsToolchain.java index 2f7174a6..489d4486 100644 --- a/src/main/java/org/codehaus/mojo/exec/PathsToolchain.java +++ b/src/main/java/org/codehaus/mojo/exec/PathsToolchain.java @@ -19,38 +19,59 @@ * under the License. */ +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Objects; -import org.apache.maven.toolchain.DefaultToolchain; +import org.apache.maven.toolchain.ToolchainPrivate; import org.apache.maven.toolchain.model.ToolchainModel; -import org.codehaus.plexus.logging.Logger; /** * Searches a list of configured paths for the requested tool. * * @author Markus KARG (markus@headcrashing.eu) */ -class PathsToolchain extends DefaultToolchain { +class PathsToolchain implements ToolchainPrivate { + private final ToolchainModel model; + private List paths; - public PathsToolchain(final ToolchainModel model, final Logger logger) { - super(model, "paths", logger); // NOI18N + public PathsToolchain(ToolchainModel model) { + this.model = model; + } + + @Override + public ToolchainModel getModel() { + return model; } - public List getPaths() { - return this.paths; + @Override + public String getType() { + return model.getType(); } - public void setPaths(final List paths) { + public void setPaths(List paths) { this.paths = paths; } - @Override - public String toString() { - return "Paths" + this.getPaths(); // NOI18N + private List getPaths() { + return paths != null ? paths : Collections.emptyList(); } + @Override public String findTool(final String toolName) { - return ExecMojo.findExecutable(toolName, this.paths); + return ExecMojo.findExecutable(toolName, getPaths()); + } + + @Override + public boolean matchesRequirements(Map requirements) { + return requirements.entrySet().stream() + .anyMatch(entry -> Objects.equals(model.getProvides().get(entry.getKey()), entry.getValue())); + } + + @Override + public String toString() { + return "Paths" + getPaths(); // NOI18N } } diff --git a/src/main/java/org/codehaus/mojo/exec/PathsToolchainFactory.java b/src/main/java/org/codehaus/mojo/exec/PathsToolchainFactory.java index 3ea4ef05..2cc0b925 100644 --- a/src/main/java/org/codehaus/mojo/exec/PathsToolchainFactory.java +++ b/src/main/java/org/codehaus/mojo/exec/PathsToolchainFactory.java @@ -19,24 +19,17 @@ * under the License. */ -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; +import javax.inject.Named; +import javax.inject.Singleton; + import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Properties; import org.apache.maven.toolchain.MisconfiguredToolchainException; -import org.apache.maven.toolchain.RequirementMatcherFactory; import org.apache.maven.toolchain.ToolchainFactory; import org.apache.maven.toolchain.ToolchainPrivate; import org.apache.maven.toolchain.model.ToolchainModel; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; -import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.xml.Xpp3Dom; @@ -45,35 +38,27 @@ * * @author Markus KARG (markus@headcrashing.eu) */ -@Component(role = ToolchainFactory.class, hint = "paths") +@Named("paths") +@Singleton class PathsToolchainFactory implements ToolchainFactory { - @Requirement - private Logger logger; - + @Override public ToolchainPrivate createToolchain(final ToolchainModel model) throws MisconfiguredToolchainException { if (model == null) return null; - final PathsToolchain pathsToolchain = new PathsToolchain(model, this.logger); - final Properties provides = this.getProvidesProperties(model); - for (final Map.Entry provide : provides.entrySet()) { - final String key = (String) provide.getKey(); - final String value = (String) provide.getValue(); - if (value == null) - throw new MisconfiguredToolchainException( - "Provides token '" + key + "' doesn't have any value configured."); - - pathsToolchain.addProvideToken(key, RequirementMatcherFactory.createExactMatcher(value)); - } - + final PathsToolchain pathsToolchain = new PathsToolchain(model); final Xpp3Dom config = (Xpp3Dom) model.getConfiguration(); if (config == null) return pathsToolchain; final Xpp3Dom pathDom = config.getChild("paths"); - if (pathDom == null) return pathsToolchain; + if (pathDom == null) { + throw new MisconfiguredToolchainException("paths element is empty"); + } final Xpp3Dom[] pathDoms = pathDom.getChildren("path"); - if (pathDoms == null || pathDoms.length == 0) return pathsToolchain; + if (pathDoms == null || pathDoms.length == 0) { + throw new MisconfiguredToolchainException("paths -> path elements are not present"); + } final List paths = new ArrayList<>(pathDoms.length); for (final Xpp3Dom pathdom : pathDoms) { @@ -94,38 +79,8 @@ public ToolchainPrivate createToolchain(final ToolchainModel model) throws Misco return pathsToolchain; } + @Override public ToolchainPrivate createDefaultToolchain() { return null; } - - protected Properties getProvidesProperties(final ToolchainModel model) { - final Object value = this.getBeanProperty(model, "provides"); - - return value instanceof Properties ? (Properties) value : toProperties((Xpp3Dom) value); - } - - protected static Properties toProperties(final Xpp3Dom dom) { - final Properties props = new Properties(); - - final Xpp3Dom[] children = dom.getChildren(); - for (final Xpp3Dom child : children) props.put(child.getName(), child.getValue()); - - return props; - } - - protected Object getBeanProperty(final Object obj, final String property) { - try { - final Method method = new PropertyDescriptor(property, obj.getClass()).getReadMethod(); - - return method.invoke(obj); - } catch (final IntrospectionException | IllegalAccessException e) { - throw new RuntimeException("Incompatible toolchain API", e); - } catch (final InvocationTargetException e) { - final Throwable cause = e.getCause(); - - if (cause instanceof RuntimeException) throw (RuntimeException) cause; - - throw new RuntimeException("Incompatible toolchain API", e); - } - } }