You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by el...@apache.org on 2026/08/06 10:22:16 UTC

(maven-antrun-plugin) 01/01: Handle plain MavenProject reference in AttachArtifactTask (#375)

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

elharo pushed a commit to branch fix-375-attachartifact-mavenprojectref
in repository https://gitbox.apache.org/repos/asf/maven-antrun-plugin.git

commit 2583f33ffd189d1403f2668c31c87773b7c87301
Author: Elliotte Rusty Harold <el...@ibiblio.org>
AuthorDate: Thu Aug 6 10:22:06 2026 +0000

    Handle plain MavenProject reference in AttachArtifactTask (#375)
---
 .../apache/maven/ant/tasks/AttachArtifactTask.java |  22 +++-
 .../maven/ant/tasks/AttachArtifactTaskTest.java    | 143 +++++++++++++++++++++
 2 files changed, 163 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/maven/ant/tasks/AttachArtifactTask.java b/src/main/java/org/apache/maven/ant/tasks/AttachArtifactTask.java
index 0212a4b..a78f311 100644
--- a/src/main/java/org/apache/maven/ant/tasks/AttachArtifactTask.java
+++ b/src/main/java/org/apache/maven/ant/tasks/AttachArtifactTask.java
@@ -68,8 +68,7 @@ public class AttachArtifactTask extends Task {
             type = FileUtils.getExtension(file.getName());
         }
 
-        MavenProject mavenProject =
-                ((MavenAntRunProject) this.getProject().getReference(mavenProjectRefId)).getMavenProject();
+        MavenProject mavenProject = getMavenProject();
 
         if (this.getProject().getReference(mavenProjectHelperRefId) == null) {
             throw new BuildException("Maven project helper reference not found: " + mavenProjectHelperRefId);
@@ -81,6 +80,25 @@ public class AttachArtifactTask extends Task {
         projectHelper.attachArtifact(mavenProject, type, classifier, file);
     }
 
+    /**
+     * Resolves the Maven project from the configured reference, unwrapping the {@link MavenAntRunProject} wrapper if
+     * present. The reference may hold either a {@link MavenProject} or a {@link MavenAntRunProject}; any other type is
+     * rejected with a {@link BuildException}.
+     *
+     * @return the Maven project held by the reference
+     */
+    private MavenProject getMavenProject() {
+        Object reference = this.getProject().getReference(mavenProjectRefId);
+        if (reference instanceof MavenAntRunProject) {
+            return ((MavenAntRunProject) reference).getMavenProject();
+        }
+        if (reference instanceof MavenProject) {
+            return (MavenProject) reference;
+        }
+        throw new BuildException(
+                "Maven project reference is not a MavenProject or MavenAntRunProject: " + mavenProjectRefId);
+    }
+
     /**
      * @return {@link #mavenProjectRefId}
      */
diff --git a/src/test/java/org/apache/maven/ant/tasks/AttachArtifactTaskTest.java b/src/test/java/org/apache/maven/ant/tasks/AttachArtifactTaskTest.java
new file mode 100644
index 0000000..c840361
--- /dev/null
+++ b/src/test/java/org/apache/maven/ant/tasks/AttachArtifactTaskTest.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.ant.tasks;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.apache.maven.plugins.antrun.AntRunMojo;
+import org.apache.maven.plugins.antrun.MavenAntRunProject;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test class for {@link AttachArtifactTask}.
+ */
+class AttachArtifactTaskTest {
+
+    private static final String CLASSIFIER = "tests";
+
+    private static final String TYPE = "jar";
+
+    @TempDir
+    Path folder;
+
+    private MavenProject attachedToProject;
+
+    private String attachedClassifier;
+
+    private String attachedType;
+
+    private File attachedFile;
+
+    /**
+     * The task must also accept a plain {@link MavenProject} reference, such as the {@code maven.project} reference
+     * registered by {@link AntRunMojo}, instead of throwing a {@link ClassCastException}.
+     *
+     * @throws IOException In case of problems
+     */
+    @Test
+    void executesWhenProjectReferenceIsMavenProject() throws IOException {
+        MavenProject mavenProject = new MavenProject();
+        AttachArtifactTask task = newTask(AntRunMojo.DEFAULT_MAVEN_PROJECT_REFID, mavenProject);
+
+        task.execute();
+
+        assertEquals(mavenProject, attachedToProject);
+        assertEquals(TYPE, attachedType);
+        assertEquals(CLASSIFIER, attachedClassifier);
+        assertEquals(task.getFile(), attachedFile);
+    }
+
+    /**
+     * The default {@code maven.project.ref} reference, which wraps the project in a {@link MavenAntRunProject}, keeps
+     * working.
+     *
+     * @throws IOException In case of problems
+     */
+    @Test
+    void executesWhenProjectReferenceIsMavenAntRunProject() throws IOException {
+        MavenProject mavenProject = new MavenProject();
+        AttachArtifactTask task =
+                newTask(AntRunMojo.DEFAULT_MAVEN_PROJECT_REF_REFID, new MavenAntRunProject(mavenProject));
+
+        task.execute();
+
+        assertEquals(mavenProject, attachedToProject);
+    }
+
+    /**
+     * An incompatible reference type must be rejected with a clear {@link BuildException} rather than a raw
+     * {@link ClassCastException}.
+     *
+     * @throws IOException In case of problems
+     */
+    @Test
+    void throwsBuildExceptionWhenProjectReferenceHasIncompatibleType() throws IOException {
+        AttachArtifactTask task = newTask(AntRunMojo.DEFAULT_MAVEN_PROJECT_REFID, "not a project");
+
+        BuildException exception = assertThrows(BuildException.class, task::execute);
+
+        assertTrue(exception.getMessage().contains("Maven project reference"));
+    }
+
+    private AttachArtifactTask newTask(String projectRefId, Object projectReference) throws IOException {
+        MavenProjectHelper projectHelper = newHelperStub();
+
+        Project antProject = new Project();
+        antProject.addReference(projectRefId, projectReference);
+        antProject.addReference(AntRunMojo.DEFAULT_MAVEN_PROJECT_HELPER_REFID, projectHelper);
+
+        File file = Files.createTempFile(folder, "artifact", "." + TYPE).toFile();
+
+        AttachArtifactTask task = new AttachArtifactTask();
+        task.setProject(antProject);
+        task.setMavenProjectRefId(projectRefId);
+        task.setFile(file);
+        task.setClassifier(CLASSIFIER);
+        task.setType(TYPE);
+        return task;
+    }
+
+    private MavenProjectHelper newHelperStub() {
+        InvocationHandler handler = (proxy, method, args) -> {
+            if ("attachArtifact".equals(method.getName()) && args.length == 4) {
+                attachedToProject = (MavenProject) args[0];
+                attachedType = (String) args[1];
+                attachedClassifier = (String) args[2];
+                attachedFile = (File) args[3];
+            }
+            return null;
+        };
+        return (MavenProjectHelper)
+                Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] {MavenProjectHelper.class}, handler);
+    }
+}