You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2026/09/21 10:06:44 UTC
(maven-ear-plugin) 01/01: Migrate integration test from maven-verifier to maven-executor
This is an automated email from the ASF dual-hosted git repository.
slachiewicz pushed a commit to branch agent/maven-executor-migration
in repository https://gitbox.apache.org/repos/asf/maven-ear-plugin.git
commit af9ef2adeac9f24461dc36f546d8d2387f842511
Author: Sylwester Lachiewicz <sl...@apache.org>
AuthorDate: Mon Sep 21 12:06:31 2026 +0200
Migrate integration test from maven-verifier to maven-executor
maven-verifier is deprecated (apache/maven-verifier#186)
---
pom.xml | 6 +-
.../maven/plugins/ear/it/AbstractEarPluginIT.java | 140 ++++++++++++++++-----
2 files changed, 114 insertions(+), 32 deletions(-)
diff --git a/pom.xml b/pom.xml
index a9cbc68..218ca13 100644
--- a/pom.xml
+++ b/pom.xml
@@ -181,9 +181,9 @@
</dependency>
<dependency>
- <groupId>org.apache.maven.shared</groupId>
- <artifactId>maven-verifier</artifactId>
- <version>2.0.0-M1</version>
+ <groupId>org.apache.maven.executor</groupId>
+ <artifactId>maven-executor</artifactId>
+ <version>1.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/src/test/java/org/apache/maven/plugins/ear/it/AbstractEarPluginIT.java b/src/test/java/org/apache/maven/plugins/ear/it/AbstractEarPluginIT.java
index 3f077a9..d643519 100644
--- a/src/test/java/org/apache/maven/plugins/ear/it/AbstractEarPluginIT.java
+++ b/src/test/java/org/apache/maven/plugins/ear/it/AbstractEarPluginIT.java
@@ -23,9 +23,16 @@ import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -34,10 +41,12 @@ import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
+import org.apache.maven.executor.ExecutorException;
+import org.apache.maven.executor.ExecutorHelper;
+import org.apache.maven.executor.ExecutorRequest;
+import org.apache.maven.executor.ExecutorResult;
import org.apache.maven.plugins.ear.util.ResourceEntityResolver;
-import org.apache.maven.shared.verifier.VerificationException;
-import org.apache.maven.shared.verifier.Verifier;
-import org.apache.maven.shared.verifier.util.ResourceExtractor;
+import org.apache.maven.shared.utils.io.FileUtils;
import org.junit.jupiter.api.Assertions;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
@@ -78,33 +87,47 @@ public abstract class AbstractEarPluginIT {
* @return the base directory of the project
*/
protected File executeMojo(final String projectName, boolean expectNoError, boolean cleanBeforeExecute)
- throws VerificationException, IOException {
+ throws IOException {
System.out.println(" Building: " + projectName);
File testDir = getTestDir(projectName);
- Verifier verifier = new Verifier(testDir.getAbsolutePath());
- verifier.setAutoclean(cleanBeforeExecute);
- // Let's add alternate settings.xml setting so that the latest dependencies are used
- String localRepo = System.getProperty("localRepositoryPath");
- verifier.setLocalRepo(localRepo);
- verifier.addCliArguments("-s", settingsFile.getAbsolutePath()); //
- verifier.addCliArgument("-X");
- verifier.addCliArgument("package");
+ String mavenHome = System.getProperty("maven.home");
+ if (mavenHome == null || mavenHome.isEmpty()) {
+ fail("The 'maven.home' system property must be set to the Maven installation used to run "
+ + "the integration tests (see the maven-failsafe-plugin configuration in pom.xml)");
+ }
- // On linux and MacOS X, an exception is thrown if a build failure occurs underneath
- try {
- verifier.execute();
- } catch (VerificationException e) {
- // @TODO needs to be handled nicely in the verifier
- if (expectNoError || !e.getMessage().contains("Exit code was non-zero")) {
- throw e;
- }
+ List<String> arguments = new ArrayList<>();
+ if (cleanBeforeExecute) {
+ arguments.add("clean");
+ }
+ arguments.add("package");
+ // Let's add alternate settings.xml setting so that the latest dependencies are used
+ arguments.add("-s");
+ arguments.add(settingsFile.getAbsolutePath());
+ arguments.add("-X");
+ String localRepo = System.getProperty("localRepositoryPath");
+ arguments.add("-Dmaven.repo.local=" + localRepo);
+
+ ExecutorResult result;
+ try (ExecutorHelper executorHelper =
+ ExecutorHelper.forMavenInstallation(Paths.get(mavenHome), ExecutorHelper.Mode.AUTO)) {
+ ExecutorRequest request = ExecutorRequest.mavenBuilder()
+ .cwd(testDir.toPath())
+ .arguments(arguments)
+ .grabOutputAsString(true)
+ .build();
+ result = executorHelper.execute(request);
+ } catch (ExecutorException e) {
+ throw new IOException("Failed to execute Maven for project " + projectName, e);
}
- // If no error is expected make sure that error logs are free
+ writeBuildLog(testDir, result);
+
+ // If no error is expected make sure that the build was successful and error logs are free
if (expectNoError) {
- verifier.verifyErrorFreeLog();
+ verifyErrorFreeLog(result, projectName);
}
return testDir;
}
@@ -115,10 +138,43 @@ public abstract class AbstractEarPluginIT {
* @param projectName the name of the project
* @return the base directory of the project
*/
- protected File executeMojo(final String projectName) throws VerificationException, IOException {
+ protected File executeMojo(final String projectName) throws IOException {
return executeMojo(projectName, true, true);
}
+ /**
+ * Writes the captured build output to a {@code log.txt} file in the test project's base directory, mirroring
+ * the log file the previous test harness used to leave behind for debugging.
+ *
+ * @param testDir the base directory of the tested project
+ * @param result the result of the Maven execution
+ */
+ private static void writeBuildLog(final File testDir, final ExecutorResult result) throws IOException {
+ File logFile = new File(testDir, "log.txt");
+ try (Writer writer = new OutputStreamWriter(new FileOutputStream(logFile), StandardCharsets.UTF_8)) {
+ writer.write(result.stdOutString().orElse(""));
+ writer.write(result.stdErrString().orElse(""));
+ }
+ }
+
+ /**
+ * Asserts that the given execution was successful and that its captured output does not contain an
+ * {@code [ERROR]} line.
+ *
+ * @param result the result of the Maven execution
+ * @param projectName the name of the tested project
+ */
+ private static void verifyErrorFreeLog(final ExecutorResult result, final String projectName) {
+ assertTrue(
+ result.success(),
+ "Build of project " + projectName + " was not successful, exit code: "
+ + result.exitCode().map(String::valueOf).orElse("unknown"));
+ String stdOut = result.stdOutString().orElse("");
+ String stdErr = result.stdErrString().orElse("");
+ assertFalse(stdOut.contains("[ERROR]"), "Found [ERROR] in build stdout of project " + projectName);
+ assertFalse(stdErr.contains("[ERROR]"), "Found [ERROR] in build stderr of project " + projectName);
+ }
+
/**
* Executes the specified projects and asserts the given artifacts. Asserts the deployment descriptors are valid.
* Asserts Class-Path entry of manifest of EAR modules.
@@ -148,7 +204,7 @@ public abstract class AbstractEarPluginIT {
boolean[] artifactsToValidateManifestDirectory,
final String[][] expectedClassPathElements,
final boolean cleanBeforeExecute)
- throws VerificationException, IOException {
+ throws IOException {
final File baseDir = executeMojo(projectName, true, cleanBeforeExecute);
final File earModuleDir = getEarModuleDirectory(baseDir, earModuleName);
@@ -176,7 +232,7 @@ public abstract class AbstractEarPluginIT {
*/
protected File doTestProject(
final String projectName, final String[] expectedArtifacts, final boolean[] artifactsDirectory)
- throws VerificationException, IOException {
+ throws IOException {
return doTestProject(projectName, null, expectedArtifacts, artifactsDirectory, null, null, null, true);
}
@@ -187,8 +243,7 @@ public abstract class AbstractEarPluginIT {
* @param expectedArtifacts the list of artifacts to be found in the EAR archive
* @return the base directory of the project
*/
- protected File doTestProject(final String projectName, final String[] expectedArtifacts)
- throws VerificationException, IOException {
+ protected File doTestProject(final String projectName, final String[] expectedArtifacts) throws IOException {
return doTestProject(projectName, expectedArtifacts, new boolean[expectedArtifacts.length]);
}
@@ -201,7 +256,7 @@ public abstract class AbstractEarPluginIT {
* @return the base directory of the project
*/
protected File doTestProject(final String projectName, final String[] expectedArtifacts, boolean cleanBeforeExecute)
- throws VerificationException, IOException {
+ throws IOException {
return doTestProject(
projectName,
null,
@@ -438,7 +493,34 @@ public abstract class AbstractEarPluginIT {
}
protected File getTestDir(String projectName) throws IOException {
- return ResourceExtractor.simpleExtractResources(getClass(), "/projects/" + projectName);
+ return extractTestProjectResources(getClass(), "/projects/" + projectName);
+ }
+
+ /**
+ * Extracts the test project resources found at the given classpath resource path into a fresh directory under
+ * {@code java.io.tmpdir} (or {@code maven.test.tmpdir} if set), mirroring the extraction previously performed
+ * by the previous test harness's resource extraction utility.
+ *
+ * @param cls the class whose classloader is used to locate the resource
+ * @param resourcePath the classpath resource path of the test project, e.g. {@code /projects/project-001}
+ * @return the directory the resources were extracted to
+ */
+ private static File extractTestProjectResources(final Class<?> cls, final String resourcePath) throws IOException {
+ String tmpDirPath = System.getProperty("maven.test.tmpdir", System.getProperty("java.io.tmpdir"));
+ File destDir = new File(new File(tmpDirPath), resourcePath);
+ FileUtils.deleteDirectory(destDir);
+
+ URL resource = cls.getResource(resourcePath);
+ if (resource == null) {
+ throw new IllegalArgumentException("Resource not found: " + resourcePath);
+ }
+ try {
+ File sourceDir = new File(resource.toURI());
+ FileUtils.copyDirectoryStructure(sourceDir, destDir);
+ } catch (URISyntaxException e) {
+ throw new IOException("Couldn't convert URL to File: " + resource, e);
+ }
+ return destDir;
}
// Generated application.xml stuff