How does Maven use external dependencies in your own project? - maven

I had a quick question on how Maven configures dependencies in the pom.xml file. In my project's pom.xml file, when I add a dependency tag and provide the artifact id and group id, how/where does Maven store those dependencies to use in my project? Since Maven is a central repository, does Maven use the internet to pull the dependencies or does it download the repositories in your local machine and use it from there?

Maven repository is of three types :
Local
Central
Remote
Maven first starts finding in Local Repository created by Maven in %USER_HOME% directory. To override the default location, mention another path in Maven settings.xml file available at %M2_HOME%\conf directory.
When Maven does not find any dependency in a local repository, it starts searching in the Central repository.
Sometimes, Maven does not find a mentioned dependency in the central repository as well. It then stops the build process and output error message to console. To prevent such situation, Maven provides a concept of Remote Repository, which is the developer's own custom repository containing required libraries or other project jars.
For user-defined jars, you also need to specify :
<repositories>
<repository>
<id>in-project</id>
<name>Name_of_your_project</name>
<url>file://${project.basedir}/libs</url>
</repository>
</repositories>

In standard configuration, Maven looks first in your local Maven repository (.m2/repository in your user directory) and if it does not find anything, it tries to download from the remote repositories that you specified. If you did not specify any, it will use MavenCentral.
When Maven finds something, it will be downloaded to the local Maven repository for future use. If you have -SNAPSHOT dependencies, they will be updated regularly.

Related

How to update release artifacts in Maven?

I have the following case:
- Maven project compiles fine on one machine where artifact A (release one) exists in that machine's local Maven repository,
- artifact A was removed from the remote repository.
How can we be sure that the project builds fine on a new machine where local Maven repository is empty?
Try the install task install-file to put the jar into your local repo from your local hard drive:
mvn install:install-file -Dfile=<path-to-file>
See maven.apache.org for more details.
Few cases :
One, if you own artifact A and use <repository> to keep the versions in sync. You can anytime rebuild your project on the new machine to fetch the artifact.
Second, If artifact A is owned by you and you didn't use repositories until now, you can simply bump up its version and deploy it on the remote server(<repository>) and consume the new version on the machine where you want to. Use <repositories> in your pom.xml to specify the remote path as follows :
<repository>
<id>clojars</id>
<name>Clojars Maven Repository</name>
<url>http://clojars.org/repo/</url>
</repository>
Third, if you don't own the artifact A and it exists in a public maven central repositories, all you need to do is rebuild the correct dependency to fetch it over the net.
Worst case, the artifact A used is owned by you and doesn't exist in a public central repository. You can still copy-paste the jar file using any mode and move it to the machine's /m2/repository where you require it. But do note in such case you shouldn't reach this case ever again.
Also in the last case, you can copy it into your project and use it as suggested by #Adam
mvn install:install-file -Dfile=<path-to-file>

Maven internal Repository

I have internal nexus repository. I want to install plugins from internal repository, having the dependencies which I want to download from the central maven repository. I am new to maven and really struggling to do the required configuration.
Once you deployed your own plugins into a nexus repository (say "releases") add that repository into the Nexus Group that contains both maven central and your releases repository. Usually developers will only use one url (mirror configured in settings.xml) from nexus and deploy artifacts into a specific repository.
In addition you need to make sure to add the maven group id of your plugins into settings.xml in the pluginGroups section: https://maven.apache.org/settings.html#Plugin_Groups
That should already work.

i am getting "Missing artifact groupId:artifactId:version:lifecycle " while compiling the project

I am having problems compiling my company project made in maven and I am getting Missing artifact groupId:artifactId:version:lifecycle, so I have resolved most of the build path dependencies for jars, but now I am stuck with this one jar which is not present in the .m2 repository, so my doubt is if the jar is configured as dependency in pom.xml and it's not there in local repository (.m2/repository).
Can't maven just get it from central maven repository by just clicking pom.xml->run as -> maven build, or I have to put this file manually in the local repository?
It's true that, if a dependency is not present in the local repository, it will be downloaded from the maven central repository. But if there's a project specific dependency which is not present in the central repository, you have to explicitly specify the repository in which the dependency is present.
You can search the Maven Central Repository to see if the artifact you want is present in here.
If it is not present, you can add the repository, containing the artifact you want, using <repositories> tag.
<repositories>
<respository>
<id>myRepository</id>
<url>my.repo.link</url>
<repository>
</repositories>

Unconventional dependency name in maven

I have a few dependencies like this. For example : jdic
In my pom.xml, I defined a dependency
<dependency>
<artifactId>jdic</artifactId>
<groupId>jdic</groupId>
<version>0.8.6</version>
</dependency>
And I have a remote repository (internal server): eg http://repo/thirdparty/
And jdic can be found in http://repo/thirdparty/jdic/jar/jdic.jar
As you notice, the naming is not conventional groupId:artifactId:version, instead its just jdic.jar
so when I run maven compile
mvn clean compile
maven tells me that it cannot resolve dependencies.
I'm aware that we can just download those jars to the local repository .m2/repository and run
mvn compile (ie without clean)
and it the jar will not be a problem. But is there any other way that I can make it retrieve from the remote despite its unconventional name and lack of metadata/pom info for those dependencies?
I already have a mirror to this internal repository that overrides the central
You could install the jdic in your internal/mirror repository with the version (jdic-0.8.6.jar).
If you are using a repository manager and you uploaded the jar to it, it would automagically create a pom for it as well as ensure the dependency was created with version, as per maven convention.
A remote Maven repository is NOT any web server putting files in any way you want. There are lots of convention to follow. One of them is the way to represent the version (which is one essential element of an artifact). With your "remote repository" it is clear that there is no way Maven can find the artifact.
Setup a real Maven remote repository to host such files. You can have a look in Nexus and Artifactory.

How do I add an artifact to a local maven repository so that it will properly reference its own set of dependencies?

I am developing an application that depends on a number of legacy JAR files and I want the project to build straight out of version control without other users having to install these JARs in their local repository. I cannot add them to the corporate repository so I have created a repository that is local to this project and I have added these JARs to that repository using maven-install-plugin:install-file and setup the repository entry in the POM file so it knows to search the local repository.
This works exactly the way I want...up to a point. The problem is that most of these legacy JAR files have their own set of dependencies. I would like for them to work just like other artifacts that have their own set of dependencies so that maven can resolve everything and include all the necessary files but I can't find a way to do this with any maven-install-plugin:install-file options (or any other maven commands/plugins). I am pretty new at maven so I am probably just ignorant on this point.
As a work around, I attempted to go into the local repository directory and manually edit the POM file for the artifact to include the dependencies. This didn't cause any errors but it is also not pulling in those dependencies.
Can someone out there give me a clue?
The maven-install-plugin:install-file goal has a pomFile attribute. You can use this to specify a POM file for your legacy jar. You would create a POM file that points to all of the dependencies by artifactId in the <dependencies> section. If you have a remote nexus repository you can use the admin screen for the repository to deploy a jar.
Once you edit POM files in your project specific repository, host it as maven repo using Maven Repository Managers (like sonatype nexus). Add your project nexus repo as one of the maven repo in project pom.xml as below
<repositories>
<repository>
<id>my-project-mvn-repo</id>
<name>my-project-mvn-repo</name>
<url>http://<your project maven repo URL here></url>
</repository>
<repositories>
Now all developers should be able to make build. The legacy jar files POM contains dependency. Maven should take care of automatically pulling dependent jars on developer's workspace.

Resources