Search code examples
mavendeploymentmulemunit

Difference between projectHelper.attachArtifact and project.getArtifact().setFile


I'm currently facing an issue with the execution of my MUnit tests using the command line.

I'm facing a problem of "duplicate project artifact assignment" Using version 1.2 of mule-domain-maven-plugin that was fixed here with version 1.3. Removing this line of code causes FileNotFoundException on mule-domain-config.xml when running my MUnit.

After decompiling the code, I can see that 1.2 (which works with my MUnits), has 2 lines of code :

this.projectHelper.attachArtifact(this.project, "zip", domain);
this.project.getArtifact().setFile(domain);

I can see that 1.3 has only this line :

this.projectHelper.attachArtifact(this.project, "zip", domain);

Does anybody know the difference between this.projectHelper.attachArtifact(this.project, "zip", domain); and this.project.getArtifact().setFile(domain); and how to resolve this issue?


Solution

  • The difference is the same as the difference between the main artifact and attached artifacts.

    First of all, an artifact is, put simply, an object containing the Maven coordinates pointing to it (group id / artifact id / version / classifier / type), a repository where to resolve it or where it was resolved, and a file, which is the actual concrete file to use / download / upload.

    Except for POM projects, a Maven project generates a single main artifact. It depends on its packaging; for example a project with a packaging of jar will create a main JAR artifact whose file contains all the classes of your project, and a project with a packaging of war will create the web application. Furthermore, the project itself is tied to its POM file; this means that a project, not only has a file for its main artifact, but also has reference to the POM file that created it. It is only for projects of packaging pom that no main artifact will be created; this is because such projects are parent or aggregator projects, containing build logic to be shared between multiple projects, but they do not produce a main deliverable.

    In addition to this, a project has attached, or secondary, artifacts. They correspond to additional artifacts that are also generated during the build of a project, and differ from the main one by their classifier and/or type, and, naturally, their actual file. Those additional artifacts are installed and deployed alongside the main one. As an example, a typical project of packaging jar would also generate its Javadoc and Sources as a JAR file as attached artifacts having the classifier javadoc and sources. It follows that a project of packaging pom can only have attached artifacts, since it has no main artifact. Finally, it is perfectly allowed to have a project without attached artifacts; only the main one (or none at all in case of a pom project) would get deployed.

    Inside a Maven plugin, all those considerations comes down to the following:

    To give examples, we can consider the artifacts deployed under org.mule.tools.maven in Central. Under the artifact id mule-maven-plugin, there are multiple files:

    • mule-maven-plugin-2.1.jar is the main artifact file,
    • which was created by the POM file mule-maven-plugin-2.1.pom,
    • while mule-maven-plugin-2.1-javadoc.jar and mule-maven-plugin-2.1-sources.jar are attached with their respective classifier.

    As second example, consider the artifact id mule-esb-maven-tools. The only file deployed (except for the hash files) is mule-esb-maven-tools-1.1.pom. This is perfectly normal since it's a POM project, so it has no main artifact (there are no JARs or other deployed); there's only the POM file of the project, with no attached artifacts.