Is dependency-reduced-pom.xml automatically used instead of pom.xml? - maven

Is dependency-reduced-pom.xml created by Maven shade plugin automatically used in projects that depends on the uberjar (instead of the ordinary pom.xml)?
Asking this after reading a number of dependency-reduced-pom.xml related questions and haven't found the answer yet:
Maven shade plugin adding dependency-reduced-pom.xml to base directory
What is the purpose of dependency-reduced-pom.xml generated by the shade plugin?
What is `dependency-reduced-pom.xml` file which created when calling maven package command?

The dependency-reduced-pom.xml is generated at build time into ${basedir} of the project. This file is a temporary file that is only used for packaging into the shaded jar. Quoting the documentation of the createDependencyReducedPom attribute:
Flag whether to generate a simplified POM for the shaded artifact. If set to true, dependencies that have been included into the uber JAR will be removed from the <dependencies> section of the generated POM. The reduced POM will be named dependency-reduced-pom.xml and is stored into the same directory as the shaded artifact. Unless you also specify dependencyReducedPomLocation, the plugin will create a temporary file named dependency-reduced-pom.xml in the project basedir.
To make it clear, after the maven-shade-plugin has run:
your initial POM will be left unchanged;
a temporary file that you can completely ignore named dependency-reduced-pom.xml will have been generated inside the root folder (this is considered an open issue with this plugin);
the shaded artifact will contain your initial POM unchanged inside the META-INF directory and not the reduced POM (this is not really important but better mention it - there was an issue about this that was closed automatically: MSHADE-36);
the POM that will be deployed is the reduced POM;
the shaded artifact will be by default the main artifact of the project.

Related

Converting one module to standalone Maven project, including a minimal working POM

I would like to distribute the main artifact sources (main Java and tests) of a multi module project as a simple - standalone - Maven project.
The easy parts of this can be implemented using the maven-source-plugin. This also is able to include the POM in the generated source code jar. However, this is the artefact POM, which refers to the parent POM which is not included in the jar.
Other than creating the POM manually, is there a way to generate a minimal POM which contains the dependencies (extracted from the artifact POM and its parent)?
If you create the POM with the flatten-maven-plugin, all parent relations are resolved and you get an equivalent POM without the unnecessary parts.
https://www.mojohaus.org/flatten-maven-plugin/

Maven EAR plugin: Adding generated resources

In a custom Maven plugin, I add a file as resource by using the addResource of MavenProject.
This works well for JAR projects, but for EARs, I see that the relevant file is copied to target/classes and then ignored. It is not present in the EAR.
There is an earSourceDirectory property which I can probably use to "trick" Maven by setting it to target/classes but it seems like the wrong way.
How can I handle generated resources that should be packed into an EAR?
The Maven EAR plugin completely disregard all of the "resources" directories that can be set up for a given artifact. Instead, as you mentioned, it solely relies on the directory referenced by the earSourceDirectory property, src/main/application being the default value. (see https://maven.apache.org/plugins/maven-ear-plugin/ear-mojo.html#earSourceDirectory)
Therefore, you have two choices: either change that property value to point to target/classes as you proposed, or generate your files (as we did for one project) under src/main/application and then they will automatically be picked up by maven-ear-plugin.

maven shade plugin doesn't let me consume the reduced-dependencies.pom

After creating a jar with shade plugin, where I shaded a certain dependency, the reduced-dependencies.pom is generated and I would like to consume it in a different project.
I can't understand how this can be done, as ONLY the complete original pom gets to be installed (and later on deployed) to my .m2 repo.
I have read and could not find my answer here, here (where OrangeDog asked it inside the comments and wasn't answered) and here.
How can I use the reduced-pom instead of the original pom in a different project ???
After some farther testing it seemed that the problem was found:
if you use the <shadedArtifactAttached>true</shadedArtifactAttached> option in the shade plugin configuration then the shaded artifact is added near the original (non-shaded) artifact, and the original (non-shaded) artifact is the one that is being installed to .m2 along with the (non-shaded) pom.
In case not using this configuration (which is by default false), then the shade plugin behaves as expected:
there is only one artifact - the shade artifact - and it, along with its reduced-dependencies.pom gets to be uploaded to .m2, as expected.

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?
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:
The main artifact of a project is retrieved with project.getArtifact(), as an Artifact.
project.getArtifact().setFile(...) sets the actual file of the main artifact of the project. Again, for a project of packaging jar, this would be the actual JAR file that was generated on-disk. Concrete example: it is what the Maven JAR plugin does.
The MavenProjectHelper component is used to attach artifacts to the project. projectHelper.attachArtifact(project, "zip", file); would attach an artifact of type ZIP to the given project, with no classifier, and whose file is the given file. There is an overload to attach an artifact with a classifier. Concrete example: it is what the Maven Assembly Plugin does when it is configured to attach the artifacts it produces.
project.setFile(file) sets the POM file of the Maven project that created it.
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.

What is the necessity of declaring <packaging> in Maven POM file?

I made a Maven project and declared packaging as war.
<packaging>war</packaging>
But this returned an error,
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.2-beta-5:single (make-assembly) on project WaterDealer: Execution make-assembly of goal org.apache.maven.plugins:maven-assembly-plugin:2.2-beta-5:single failed: For artifact {ArtifactName:ArtifactName:0.0.1-SNAPSHOT:war}: An attached artifact must have a different ID than its corresponding main artifact.
But when I removed packaging declaration, everything worked just as expected.
Is there any specific reason for this happening? Why did declaring packaging type return an error An attached artifasct must have a different ID than its corresponding main artifact. ? How are they related?
I went through POM reference from this link Maven POM reference but did not find the information very useful.
the error is from the assembly plugin which is not directly related to the packaging.
the packaging defines the type of artifact produced by maven (in general: one pom.xml one artifact - there are exceptions to this rule, e.x. sources jars or javadocs).
the default is "jar". so if you do not specify anything maven will create a jar file.
The other available values for packaging should be a bit self explaining?
The error might be simply the name that results. So packaging jar will create a jar file, "war" will create a war file and so on. If your assembly plugin creates a war file that may conflict with the war created through the pom.xml
The packaging defines some of the binding which are done. This means if you decide to use packaging war it means to run maven-war-plugin in the package phase. This can be read in the appropriate documentation.
The question is why you using maven-assembly-plugin in a war module and apart from that why using such an old version. Take a look on this site which shows the uptodate versions of the plugins:
http://maven.apache.org/plugins/

Resources