What are .pom files in Maven build artifacts? - maven

You can see from browsing any repository that Maven build artifacts contain .pom files. The contents of these files look a whole lot like pom.xml files. Where do these files come from? What are they used for? Additionally, build artifacts have maven-metadata.xml files, at least on search.maven.org, and these files have substantially the same content as the .pom files. What's the deal with that?

The files are the pom files from within the project. Those are deployed to the maven repository during the release build or by other build tools as well (gradle, ivy, etc.).
Those files are needed to describe the dependencies of the appropriate artifact otherwise you have no other opportunity to store such kind of information.
In your particular example (really old 2005) this is a pom file which is created at a time of times where maven was not such distributed. In this case the file does not contain any dependencies.
If you take a look here:
http://search.maven.org/#browse%7C-77609479
you see a number of versions of a single artifact. If you now take a look into the maven-metadata.xml you will see list of available versions.

The best answer I have found so far is in this SO thread. Here is an exact quote, highlighting the crux of the explanation:
Every jar needs to have a pom file describing it, you can just add something simple like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>aGroup</groupId>
<artifactId>aArtifactId</artifactId>
<version>aVersion</version>
<packaging>jar</packaging>
<name>a Name</name>
</project>
Another good explanation:
POM that is installed to Nexus will describe the jar. Used to pull the
dependencies that are associated to corresponding jar. When we add the
jar as dependency to our project, all the jars required for the
included jar will be identified through the corresponding pom.

Related

Intellij - Add project as dependency to another project

I am trying to make my project work on intellij (it works with eclipse). I have a project with this in my pom:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fitnetapplication</groupId>
<artifactId>fitnet-common</artifactId>
<version>6.0.2-Final</version>
<packaging>war</packaging>
<name>FitnetCommon</name>
<description>Socle Commun FitnetManager / SyrhaLogic</description>
Now i have another project which needs to be linked to this one, so I had:
com.fitnetapplication
fitnet-common
6.0.2-Final
runtime
war
<dependency>
<groupId>com.fitnetapplication</groupId>
<artifactId>fitnet-common</artifactId>
<version>6.0.2-Final</version>
<type>jar</type>
<scope>provided</scope>
<classifier>classes</classifier>
</dependency>
The problem is that on Intellij, the version is not accepted for some reason, I don't know why, it tells me that the version 6.0.2-Final is not found for the artifact fitnet-common
To confirm - you are actually running mvn clean install (or similar) on the first project before trying to resolve the dependency in the second project?
If you are, it sounds like you're installing the project using one Maven repo location, and then in the other project it is looking in a completely different location. Are your .m2 location settings identical for both projects?
Edit:
Is it because you're specifying the first project as a war packaging, but in the dependency declaration you are looking for a jar? They would essentially be two different artefacts:
.war - com.fitnetapplication:fitnet-common:6.0.2-Final:war
.jar - com.fitnetapplication:fitnet-common:6.0.2-Final:jar
Check in your .m2/com/fitnetapplication/fitnet-common/6.0.2-Final to see what you have there, likely it is just the war file.

What is required to use maven for artifact deployment?

I am setting up a CI system with repository archive, based on apache Archiva. Among various techniques for deploying file there, the most promising one seems to be using maven (as opposed to REST api that would require too much curl calls and Web interface that is not for automation).
It seems that for deploying artifact, such as zip archives of build artifacts, in maven there is a following plugin: deploy:deploy-file. However an attempt to simply invoke that command gave me no results.
I did not work with maven before; currently our builds are done by invoking cmake on source directory, then make from shell script. What do i need to add and have to be able to use maven for deploying the resulting artefact?
Is it necessary to create a pom file? If so, what steps do i need to add?
You can use deploy:deploy-file to upload these artifacts, and by default it will generate a POM for you. What you will need is to:
install Maven
create a settings.xml file, with a <server> element that contains the credentials for deploying to Archiva over HTTP
There's a bit more information here: http://maven.apache.org/plugins/maven-deploy-plugin/usage.html. If you are generating the POM, then you will need to supply the groupId (distinct grouping of artifacts), artifactId (filename without version), version (artifact version), and packaging (typically extension, such as zip) parameters along with the required ones of repositoryId, url and file.
However, it's not required to use Maven, or the REST API - you can also just use a simple HTTP PUT call:
curl -T artifact.zip http://localhost:8080/archiva/repository/my-releases/group/artifact/version/artifact-version.zip
You may also use scp, ftp, etc. to place the file directly in the Archiva filesystem. Note that in that case, you'll have to wait for Archiva's scheduled scan to pick it up.
Maven needs a WebDAV like repository (see also Nexus, Artifactory) to deploy its artifacts (mostly jar, war, ear or assemblies.
Look here for a how to on setting up Maven with Archiva.
Yes, it is necessary to have pom.xml in maven and also it is obvious that you need maven to be installed on your machine. Bare minimum, you need to provide artifact ID(like name of jar), group id(like package to identify the location of artifact in repository) and version. By default package structure will be jar unless you mention it as war/ear/pom. If you want to use any dependencies you can mention them in dependencies section.
Following is the minimum pom that is required.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Maven Quick Start Archetype</name>
</project>
Here is the quick tutorial to get acquainted with maven.

Automate creation of pom file dependencies based on the jar file

I have hundreds of jar files scattered across different projects that I need to create pom file dependencies files for. I'd really like to avoid manually searching for every jar file and adding the dependency manually. Is there an API I can use to accomplish this task or some other way ?
Ive tried using a generic pom as described : http://maven.apache.org/plugins/maven-install-plugin/examples/generic-pom-generation.html
Using this command - mvn install:install-file -Dfile=spring-webmvc-portlet-3.0.6.RELEASE -DgroupId=test -DartifactId=test -Dversion=version -Dpackaging=jar-DgeneratePom=true
But should the generated pom not match the jar file ? Or do I need to add this myself
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>version</version>
<packaging>jar-DgeneratePom=true</packaging>
<description>POM was created from install:install-file</description>
</project>
I wrote a script that generates an ivy file. It uses the jar checksums to identify the matching modules in Maven central.
https://github.com/myspotontheweb/ant2ivy
This solution could be adapted to generate a Maven POM.
You may create a bash script which uses the Maven Install plugin to produce a generic POM.
See http://maven.apache.org/plugins/maven-install-plugin/examples/generic-pom-generation.html

multi artifact id in one pom

There is a maven project(jar), but now it needs to be spilt into two artifacts
I want to have two maven artifact like following
<groupId>xxx</groupId>
<artifactId>xxx-client</groupId>
<groupId>xxx</groupId>
<artifactId>xxx-impl</groupId>
But all the code is in one single project.
My question would be, How can I package the tow required artifacts without changing the project too much.
Then ,
mvn package deploy
will auto deploy these two artifacts into repository
Actually I don't want to split these project into two maven project.
I am not sure if there is a possibility of having two <artifactId> tags in one POM, since it is unique. What you may do is, you can have two pom files, say, pom.xml, and pom_impl.xml, now
to deploy client do, mvn package deploy
to deploy impl do, mvn -f pom_impl.xml package deploy
Never tried though.
Clarification: The question seem ambiguous, seems like you have one project but you wanted to generated two artifacts (client, and impl) of the same code-base. On reading it again, I feel like you have two projects (two different code base) but you just wanted to unify it so that it behaves as two modules of the same project. My answer assumes the first case.
If I understood the question correct, you need to have a super pom (xxx/pom.xml) and two different poms for both of your projects (xxx-client and xxx-impl). The structure of your super pom will be like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<packaging>pom</packaging>
<modules>
<module>xxx-client</module>
<module>xxx-impl</module>
</modules>
</project>
Then when you deploy your main pom, it will deploy it's modules as well.
Here are references if you want to read more about super pom and modules.
This is called "multi module project" in the Maven world. You can find information on how to do this e.g. here. Indeed you need two separate POMs and an additional one to combine both.
specify pom
Make two pom ,then specify the pom in command line, that is the easiest way.

Why Maven is looking for .pom file when .jar is present in the repository?

I have the following dependency in my pom.xml
<dependency>
<groupId>aGroup</groupId>
<artifactId>anArtifact</artifactId>
<version>aVersion</version>
</dependency>
I also have the anArtifact-aVersion.jar file in ~/.m2/repository/aGroup/anArtifact/aVersion directory.
When I start building the project, maven looks for a .pom file instead of using the .jar file and attempts to download the following
http://repo1.maven.org/maven2/aGroup/anArtifact/aVersion/anArtifact-aVersion.pom
How can I configure maven to use the existing .jar file?
Every jar needs to have a pom file describing it, you can just add something simple like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>aGroup</groupId>
<artifactId>aArtifactId</artifactId>
<version>aVersion</version>
<packaging>jar</packaging>
<name>a Name</name>
</project>
Run your build using the "-o" switch to use Maven in offline mode. In offline mode, Maven will not check for updates of snapshot dependencies in remote repositories.
the best way to install an artifact to the local repository which were not built by Maven ist to use
mvn install:install-file ...
have a look at the install:install goal.
POM that is installed to nexus will describe the jar. Used to pull the dependencies that are associated to corresponding jar. When we add the jar as dependency to our project, all the jars required for the included jar will be identified through the corresponding pom.
It is looking for the pom to, among other things, resolve the transitive dependencies.

Resources