Install remote maven artifact to local repository - maven

I would like to install an artifact from maven central repository to my local repository. Can anyone help me on getting this? With other words, I want some jars from maven central repositories to be downloaded into my local repository, but using maven, not going in browser and downloading needed jar files.

I am not entirely sure why would you want artifacts from maven for reasons other than using them in a maven based project... But since that's what you want:
Maven installs artifacts locally when they are used - that is when you install a project that has them in dependencies. Therefore the simplest solution would be to create a dummy project, put the artifacts you want as dependencies and install it. Something like:
<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>dummy</groupId>
<artifactId>dummy</artifactId>
<version>dummy</version>
<dependencies>
<-- artifacts you want -->
</dependencies>
</project>
within pom.xml file in an empty folder. It will additionally create a dummy artifact in your local repository you might want to get rid of manually if it bothers you.

Related

Can you create a jar file from pom.xml during a Gradle build?

A build I am running needs to have access to a jar file that does not exist in our Nexus repository as only the pom.xml file does.
I am able to create the jar file locally using the just mentioned pom.xml file, but the Gradle build job is written to pull jar files from Nexus and not locally. And I do not have the ability to load the local jar file to our Nexus repo.
With the above in mind, is it possible to have the Gradle build job create the jar file from the pom.xml during the build (i.e. on the fly)?
Thank you.
Here is the pom.xml file's contents used to create the jar file - not sure if this is the best way or not.
<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>org.apache.logging.log4j </groupId>
<artifactId>log4j</artifactId>
<version>2.17.0</version>
<packaging>jar</packaging>
</project>
`
Sure, you can use maven publish gradle plugin. You can use this plugin to build a jar and publish to maven repository, or your private nexus repositor. This is the docs: https://docs.gradle.org/current/userguide/publishing_maven.html

Generate the maven artifact path

Maven install knows all the artifacts generated by a build, and will push them locally.
Installs the project's main artifact, and any other artifacts attached by other plugins in the lifecycle, to the local repository.
the help plugin probably supports this, but not sure of right expression
# has all the pieces (artifact, version, type) but is it fair to assume filename will always be that combo?
mvn help:evaluate -Dexpression=project.artifact
Is there any way to get that list of paths from a maven command?
I want to generate a list of specific artifacts to persist as artifact results in a build process, without publishing to a maven repo.
Artifact paths in Maven repository will follow the following formula by default:
groupId is broken into folders using the full stops as delimiter, then artifactId and version form the last two folders
filename of the artifact consists of artifactId and version, type is defined by packaging
So, let's say you have a multi-module project with main pom.xml:
<groupId>com.foobar.my.business</group>
<artifactId>myApp</artifactId>
<version>1.0-SNAPSHOT</version>
And it has two submodules, first is web module that creates a REST endpoint:
<parent>
<groupId>com.foobar.my.business</group>
<artifactId>myApp</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>myApp-web</artifactId>
<packaging>war</packaging>
Second one is persistence layer:
<parent>
<groupId>com.foobar.my.business</group>
<artifactId>myApp</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>myApp-persistence</artifactId>
<packaging>jar</packaging>
Let's say your local repository is found from ~/.m2/repository. Then your artifacts will be saved in local repository at:
~/.m2/repository/com/foobar/my/business/myapp/1.0-SNAPSHOT/myapp-1.0-SNAPSHOT.pom
~/.m2/repository/com/foobar/my/business/myapp-web/1.0-SNAPSHOT/myapp-web-1.0-SNAPSHOT.pom
~/.m2/repository/com/foobar/my/business/myapp-web/1.0-SNAPSHOT/myapp-web-1.0-SNAPSHOT.war
~/.m2/repository/com/foobar/my/business/myapp-persistence/1.0-SNAPSHOT/myapp-persistence-1.0-SNAPSHOT.pom
~/.m2/repository/com/foobar/my/business/myapp-persistence/1.0-SNAPSHOT/myapp-persistence-1.0-SNAPSHOT.jar
An artifact's final build name and the local repository location can be tinkered with. But you can use the following expressions to check those:
${settings.localRepository} will return path to local repository.
${project.build.finalName} will return final build artifact name.
To get this list in almost the correct format, you can run:
On Windows mvn -q exec:exec -Dexec.executable="cmd" -Dexec.args="/C echo ${settings.localRepository}\${project.groupId}\${project.artifactId}\${project.version}\${project.build.finalName}.${project.packaging}"
On POSIX mvn -q exec:exec -Dexec.executable='echo' -Dexec.args='${settings.localRepository}/${project.groupId}/${project.artifactId}/${project.version}/${project.build.finalName}.${project.packaging}'
Then you just have to fix the full stops in groupId.
There is also a mvn dependency:build-classpath command which will show the location of each dependency on the file system that can come in handy sometimes.

How to access files from module using maven without searching it in local .m2 repository & central maven repository?

I have two projects. Project A & B. Project B is dependent on project A.
To run project B, I have to add project A's depedency in project B's pom.xml.
If I change something from Project A. I have to do mvn install again to update local repository with latest code of project A. Then I can run Project B.
Can I access Project A's changed code in project B without doing mvn install?
No. You can't access the updated code. That is because, when you build a maven application, it will get all the dependencies from your .m2 repository. If it does not find the dependency there, then it will search your remote repository.
In your case, when you update A's code and don't build it, then the updated artifact will not be be available in your .m2 repository. Now if you build Project B, then it will try to fetch project A artiufact from .m2 repository. Since you did not build A after modifying the code, B will fetch the artifact that is currently there in the .m2 folder i.e. the artifact with the old code.
Another approach that you can use is to have a parent pom. This is just an aggregator pom which will execute the pom.xml for both of your modules. For eg:
<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>org.sonatype.mavenbook.multispring</groupId>
<artifactId>simple-parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>module-A</module>
<module>module-B</module>
</modules>
</project>
Please be aware that the packaging for this should be pom.

Plugin is not being found after I install it in local repo

I have written a plugin and to install it in the local repository I run the command :
mvn install
The plugin is successfully added to my local maven repository but when I run :
com.tools:generate:0.0.1-SNAPSHOT:generatepom
I receive the error :
plugin com.tools:generate:0.0.1-SNAPSHOT or one of its dependencies
could not be resolved: Failed to read artifact descriptor for
com.tools:generate:jar:0.0.1-SNAPSHOT: Failure to find
com.tools:generate:pom:0.0.1-SNAPSHOT in
https://nexus.mydomain.com:8181/prod/content/groups/level0/ was cached
in the local repository, resolution will not be reattempted until the
update interval of nexuspro-level0 has elapsed or updates are forced
-> [Help 1]
It seems to be searching for the plugin on Nexus even though the plugin is installed locally. How can I configure maven to run the plugin in the local repository ?
Here is the build & beginning of pom.xml :
<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.tools</groupId>
<artifactId>generate</artifactId>
<packaging>maven-plugin</packaging>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>com.tools</groupId>
<artifactId>generate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<configuration>
<repositoryUri>http://repository.sonatype.org/service/local/lucene/search?sha1=</repositoryUri>
</configuration>
</plugin>
</plugins>
</build>
most likely your plugin's pom contains different identification (groupId,artifactId,version).
Also, make sure that you specified maven-plugin there.
If it is not the case, please provide plugin's pom excerpt, or its build log excerpt (the "istalling ..." part).
You can read about developing plugins here.
I would suggest to turn your approach around and deploy the plugin to the remote repository.
If that is not desired it should however work fine. You might be running into a problem with your Maven repository meta data. I would try to run
mvn -U com.tools:generate:0.0.1-SNAPSHOT:generatepom
forcing an update as a next step.

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