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

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/

Related

Why doesn't the dependency contain a jar in the maven public repository https://mvnrepository.com?

I a maven rookie and am wondering how to get a binary jar file if it is not already in the repo. Specifically i'm in need of: jackson-dataformats-text-2.13.0.jar. Do I need to build it myself? I'm used to creating a project and marking a library as a dependency and seeing the jar downloaded into my .m2 cache but all i see in my cache is:
jchan#jchan-Z170N:~/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformats-text/2.13.0$ ls
jackson-dataformats-text-2.13.0.jar.lastUpdated jackson-dataformats-text-2.13.0.pom.sha1
jackson-dataformats-text-2.13.0.pom _remote.repositories
Can someone advise how I am to get a built version of the jar from maven central?
We are still maintaining our ant build and I need the jar file for this. (i know i know, ancient stuff but team is not ready to port just yet).
parent pom don't contain jar file
This is the reason why no bundle link is present on the official public maven repository https://mvnrepository.com
The maven dependency is not a jar, is a parent. So the extension is: .pom which is just a plain pom.xml
Parent dependencies don't contain compiled class like .jar.
In your specific case, there are another dependencies who contains jars:
https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.13.0/
https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-xml/2.13.0/
advice
Check what classes do you need on your ant project and search if exist a jar (with the classes you need) on https://mvnrepository.com
Another option is to get all the dependencies from pom :
https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformats-text/2.9.0/jackson-dataformats-text-2.9.0.pom and download them into your ant project. In theory is the same of add the parent pom in a maven project

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.

How can I expect maven to resolve dependencies required by the child jar?

I have a parent project(has its own pom.xml) in which I import the child project as a jar with its own pom.xml.
In the parent pom.xml I have specified my child jar as a dependency - this gets resolved, but i want maven to resolve the dependencies required by my child jar.
My Use case to replicate :
When I include spring-web-mvc.jar the transitive dependencies are resolved automatically.
I have a similar requirement where I include my child.jar into a main framework project and expect the transitive dependencies to get resolved (Notw: the child.jar is not hosted it is packaged as jar and present on the local file system)
Current Structure:
Child Project:
|----/src/main/java
|----/src/main/resources
|----child-pom.xml
>This child project will be a jar as dependency in the parent project
Parent Project
|----/src/main/java
|----/src/main/resources
|----/src/main/webapp/WEB-INF/lib/child.jar
|---- parent-pom.xml
The problem:
When i create a war from parent project i want all the dependecy including transitive ones to show in WEB-INF lib.
Currently this is not happening.
First when talking of parent/ child Maven projects normaly you have your"childs" specified as modules in a common parent project which itself is beeing packed with the packaging type pom rather than make them a dependency of the parent project.
When it comes to the dependencies of your "childs" or generally "dependencies of your dependencies" those are called transitive dependencies and are pretty well explained in the official documentation found here: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
The resolving of those transitive dependencies is one of Mavens core strenghts and guaranteed by default unless they lead to conflicts that make the build fail.
Two things to help here are having a closer look into the enforcer plugin (http://maven.apache.org/enforcer/maven-enforcer-plugin/) and the shader plugin (http://maven.apache.org/plugins/maven-shade-plugin/) .... well and the official documentation of corse (reading the whole thing takes less than a day - then supports you further for specific topics whereas we gladly further support you too if you already have pom.xml files and you are stuck somewhere.
While the enforcer-plugin covers certain conflicts regarding different versions of the same artefacts the shader plugin will just pack everything you specified to a single jar for reverseengineering (its not the normal use case but i sometimes use it that way if i am not absolutly sure what ends in my final archives).
Also worth a look at is the dependency-plugin already available in the maven distributions - mvn dependency:tree -Dverbose will give you pretty detailed information on the resolved dependencies (and probably version conflicts).

What are the difference between pom.xml and effective pom in Apache Maven?

Could somebody explain to me, what are are differences between the file pom.xml and the file effective pom.xml in an apache maven project?
The Super POM
All Maven project POMs extend the Super POM, which defines a set of defaults shared by all projects.
The Simplest POM
All Maven POMs inherit defaults from the Super POM. If you are just writing a simple project that produces a JAR from some source in src/main/java, want to run your JUnit tests in src/test/java, and want to build a project site using mvn site, you don’t have to customize anything. All you would need, in this case, is the simplest possible POM shown in The Simplest POM. This POM defines a groupId, artifactId, and version: the three required coordinates for every project.
The Effective POM
It is the merge between The Super POM and the POM from The Simplest POM.
NOTE: This info was extracted from the following link (in the link the explanation is very complete)
Maven: The Complete Reference - 3.2. The POM
You can see the difference of a pom.xml and the effective pom.xml using
mvn help:effective-pom
which is describe here.
In a multi module project you'll use a parent pom.xml for defining general settings for all modules and then in each module there will only be specific settings.
The above goal will help you analyze the resulting pom that you could of course actually use instead of the parent reference.
The whole idea is by using the generalization (super-pom) / specialization (module pom) approach there is a central place where you can specify the general configuration. This is much more efficient then having to cut&paste the general parts.
Please also note that the effective pom will add the default behavior e.g. for the jar plugin so that you can debug issues like
Maven JAR Plugin 3.0.2 Error: You have to use a classifier to attach supplemental artifacts to the project instead of replacing them
with this approach. See also Maven `help:effective-pom` only generating for a single project, not all projects

Maven packaging ear finding dependency from project level but not from parent

I've currently got a parent pom that declares two modules: an ear and a war. The ear is reliant on the war (and declares a dependency for it with group/artifact id and packaging type).
When packaging from the parent pom level, the reactor picks up both artifacts and properly packages the war into the ear as you would expect. However, when packaging from the ear's project pom (despite having declared elements in both projects pointing to the parent pom) the ear fails to find the war artifact.
I know that when packaging at the ear level Maven finds its way to the parent correctly, but does it not then iterate down to the various modules that the parent contains to pick up artifacts?
Thanks :)
That's the way Maven works. It's OK. When resolving dependencies, Maven looks for them in reactor, then local repository, then remote repos. So, when doing a build from a parent project level, both projects are in the reactor, so EAR can pick WAR easily. (To be specific, it's not because the parent-child relation, but the fact they are modules.) However, when you build an EAR module in isolation, reactor can't provide WAR as well as local repo as well as remote repos. If you install WAR module into local repo by mvn install and then try to build EAR, WAR artifact will be found using local repo.
Sounds like your parenting structure is broken, if the EAR depends on the WAR then it should be a child module.

Resources