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

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/

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/

How to run Maven Javadoc in a project with pom packaging?

I have a project that packages the delivery of a software using the assembly plugin. The packaging of the project is pom.
To make a nicer documentation i am using the dependency plugin to download the sources of the different projects and then using the javadoc plugin to generate a new documentation that merges the javadoc for the different projects into one.
The issue I am having is that maven javadoc will not run if the packaging is pom.
It complains with the message: Not executing Javadoc as the project is not a Java classpath-capable package
However, if I put packaging jar it works. Unfortunately then an empty unwanted jar file is generated.
Is there a way to get the maven javadoc to run with packaging pom?
Cheers,
Javi
The workaround I have found was to set the packaging in the pom to jar and prevent maven jar plugin to generate the jar.

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.

Understanding Java Artifacts and Maven

I am trying to understand relationship between artifact, group, class definitions.
For example, I've seen the following artifact declaration:
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.53.0</version>
Is there a file associated with this artifact?
Is this enough information to pull down the file down when building your Maven Project?
Where is it getting the file from? Is it getting it from selenium, or does Maven house these artifacts, and it is getting from Maven?
Where exactly is it downloading the artifact from?
What's in the artifact file? Class definitions? Multiple classes can be defined in there, right?
Maven seems to be making a jar file. Is it compounding all the classes into that file?
Also, how is artifact file different from JAR file and can you make your own artifact file?
Is there a file associated with this artifact?
Yes, what you have posted is known as a coordinate. It references a jar named selenium-java that is in the group org.seleniumhq.selenium.
Groups, identified by the groupId component of the coordinate, are a way of namespacing artifacts within maven to prevent naming collisions.
This coordinate says that the project has a dependency on version 2.53.0 of a maven artifact named selenium-java in the group org.seleniumhq.selenium.
Is this enough information to pull down the file down when building your Maven Project?
Yes, the coordinate is how the artifact is located within the maven repository and is enough information to locate and download the artifact when building a maven project.
Where is it getting the file from? Is it getting it from selenium, or does Maven house these artifacts, and it is getting from Maven?
Where exactly is it downloading the artifact from?
Where the file is retrieved from is based on your maven configuration. By default maven will first check the local maven repository on your machine to see if the artifact has already been downloaded. If not, it will then check Maven Central.
You can also host your own maven repositories using tools such as Nexus or Artifactory that can mirror repositories on the internet such as Maven Central as well as store artifacts you create yourself that you do not with to share with others.
What's in the artifact file? Class definitions? Multiple classes can be defined in there, right?
An artifact can be any type of file. In the case of the selenium coordinate above the artifact is a jar file. There will also be a pom file associated with that coordinate that explains all of the dependencies of the selenium-java jar.
http://search.maven.org/#artifactdetails%7Corg.seleniumhq.selenium%7Cselenium-java%7C2.53.0%7Cjar
Maven seems to be making a jar file. Is it compounding all the classes into that file?
You can build normal jars or fat jars with maven. By default maven will build a normal jar. If you wish to package all of a jars dependencies within it (i.e. fat jar) you need to use a special maven plugin.
http://maven.apache.org/plugins/maven-shade-plugin/
Also, how is artifact file different from JAR file and can you make your own artifact file?
Artifact is a generic term used to describe anything you can store within a maven repository. Maven repositories can store many different types of files. In the case of this coordinate the artifact is a jar file.

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

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.

Resources