Maven: download all the artifacts of a group - maven

I am using maven 3.0 with nexus as remote repository.
I am wondering, is there a way to download all the artifacts with the same groupId using maven without knowing the name of all the artifacts? In other words, is it possible to download all the artifacts from remote repository automatically by only mentioning the group Id?
For example, I want to download all the artifacts in group com.example.here to my local repository:
<groupId>com.example.here</groupId>
artifacts:
<artifactId>a1</artifactId>
...
<artifactId>an</artifactId>
and the version that I want is the latest.

You can use lftp (should be included in many UNIX distributions) to mirror a part of a Maven repository. Since the repository uses sub-directories based on groupIDs, you can use that do fetch all artifacts belonging to a certain group. E.g.
$ lftp https://repository.jboss.org/nexus/content/groups/public/apache-xalan/ -e 'mirror .'
Will grab everything under the apache-xalan groupId.
This may not work with every Maven repository. Some may only allow access to the directory structure at a certain depth or not at all.

Its not possible to do this since a dependency in maven needs to be referred by groupId:artifactId:version:classifier (optional).
One way I can think of is to create an assembly project that has dependencies on all the projects you want to download and the version optionally set to LATEST. You can use maven assembly plugin to create an archive from the dependency sets.

Related

Maven and dependencies NOT in repository

We have a dependency third-party library that is available online in jar form, but it is not in Maven Repository, or known to be in any other repository.
How can we use pom.xml to auto-retrieve this dependency, based on a URL?
We don't want to store it in our Git repo, because that's A Bad Thing.
The idea here is that when people check out the project, they can use their IDE Maven integration (or just mvn command line tools) to download all the dependencies. So we would want to be able to also download this other third party dependency just like all the ones in Maven repo.
I have not been able to come up with an answer to this based on searches -- all solutions seem to be "download it first and create a local repo." Obviously Maven can download from the Internet, since that's how it connects to Maven Central and other repos. So I don't see why it cannot download arbitrary URLs that present packages in recognizable formats.
Long term, the best solution is to use your own artifact repository like Nexus, Artifactory or Archiva.
All of these have a manual upload function that you can use to set the groupId, artifactId and version, so you can then refer to the artifact as usual.
If you want to go really low tech, I think you can just put some machine's local repository behind an Apache, provided you grant read/write access.
Then you need to add your new repository in the Maven settings.xml file, as described here.
Maven uses the coordinates to navigate the repository (which has a specific layout) and verify artifact checksums for corruption/tampering using metadata files in specific locations of the repo.
AFAIK this is similar to other package management systems like APT and RubyGems that use repo manifests and don't allow arbitrary URL downloads.
Skipping the repository manager
If you really don't want or can't use a repository manager, you can always download the artifact and manually install it using the Maven Install Plugin:
mvn install:install-file -Dfile=your-artifact-1.0.jar -DgroupId=org.some.group -DartifactId=your-artifact -Dversion=1.0
However, you'll have to do this on every machine that runs the build, every time that artifact needs to change.

Locate original repository of each dependency in maven

Scenario:
New enterprise policy forbids from using public repositories. For every dependency used (which are a lot) we have to provide to the devOps team the artifact group, id, version and from which repository it came.
We have used more than one external repository on our code base. Since all the artifacts are now on the local repository, we don't know where they came from.
What I was able to do:
I can use
mvn dependency:list -DoutputAbsoluteArtifactFilename=true -DprependGroupId
on each project to get artifact group, id, version.
And mvn dependency:list-repositories to get the repositories used in that project
What's missing:
Knowing which artifact is from which repository.
Thanks in advance
I am afraid this will not be possible in maven. Prior to maven 3.0.x, maven did not even kept track of remote repositories. After Maven 3.0.x, it moved to eclipse aether. Eclipse aether create _remote.repositories file for every repository which has repository information. It contains repository id which is defined in your settings.xml file. You could,
Delete your local repo contents.
Run following command,
find . -name _remote.repositories -exec grep "^[^#;]" {} \; > repo_info.txt
This will atleast give you the mapping.
Make a list of all external repositories that you use. Furthermore, take the list of all groupId, artifactId, version (Either by dependency:list each project or by scanning the local repository). Now for each dependency, ask the external repositories via REST if they contain this dependency.
If you start with MavenCentral, you have a high chance that you find your dependency in the first try.

Export Maven dependencies and maintain repository folder structure

I'm trying to know whether it's possible to export/copy dependencies of a project managed using Maven while maintaining the folder structure that is adopted in the local repository.
The root of my need is that I have amassed through almost ten years a lot of artifacts in my local repository (~8GB). I am no longer working on those old projects from previous assignments that drew most of the artifacts in and now, I need to move just what is needed for one single project (~650MB of artifacts) to a different computer. I can't just set the other computer to download artifacts again because many of these artifacts were retrieved from a local Nexus proxy in previous assignments. Moreover, I don't have the source code for these artifacts so I can't just install them.
dependency:copy-dependencies doesn't do the trick because all artifacts are simply dumped in a single folder, instead of having say .m2\repository\mysql\mysql-connector-java\5.1.38\mysql-connector-java-5.1.38.jar
I believe my question can also be rephrased as “How can I extract from my local Maven repository a subset of the repository that is related to only one specific project?”
You can actually use the Maven Dependency Plugin and its copy-dependencies goal, as you mentioned.
What you actually missed is its useRepositoryLayout option
Place each artifact in the same directory layout as a default repository.
example: /outputDirectory/junit/junit/3.8.1/junit-3.8.1.jar.
Type: boolean.
Since: 2.0-alpha-2.
Required: No.
User Property: mdep.useRepositoryLayout.
Default: false.
You could hence execute - as an example - the following:
mvn dependency:copy-dependencies -Dmdep.useRepositoryLayout=true \
-DoutputDirectory=.m2/repository
If you missing some dependency, then download that dependencies from other source and paste it in your .m2(maven local repository ) folder.

Can I avoid Maven deployed war version with timestamp in Archiva?

In out project we are using using deployed war file in /archiva-2.2.0/repositories/internal/com/xyz/1-SNAPSHOT/proj-1-20160204.122021-15.war path using shell script to copy to jboss. However finding the latest build timestamp and build number is very difficult. Is there a way to avoid using timestamp while storing it in archiva like proj-1-SNAPSHOT.war?
I have already read about <uniqueVersion>false</uniqueVersion> whcih is not supported in maven 3.
I am using archiva-2.2.0, maven-3.3.9.
Maven repositories wasn't designed to distribute deployable components, your continuous integration environment should take care of this. Jenkins has eg Archive Artifacts (native) and Copy Artifact Plugin which you can use to store and recover binaries in your pipelines.
But you can workaround this behavior changing the version of the war to a stable one - removing the -SNAPSHOT suffix. This will lead you with a predictable URL.
I am posting this as it is a new finding, if I wget http://xx.xx.xx.xx:8083/repository/internal/com/xyz/1-SNAPSHOT/proj-1-SNAPSHOT.war. I get the latest deployed artifact in the archiva repository. So archiva does a 302 redirect to point to url of http://xx.xx.xx.xx:8083/repository/internal/com/xyz/1-SNAPSHOT/proj-1-20160204.122021-15.war location and downloads the latest build. I am not sure if this works for other repositories like nexus or artifactory etc.
Ofcourse I will need a cron job to periodically clear of the stale snapshot artifacts.

deploy on nexus artifacts with Snapshot policy but without SNAPSHOT string in version

apparently my Nexus is rejecting every deploy I throw at him if the artifact has not -SNAPSHOT in the version.
Data:
name of the failing artifact: entando-core-engine-experiment-bundles_with_bootstrap.jar where experiment-bundles_with_bootstrap is the version as in the version element of the pom.xml
hosted repository policy on my Nexus: Snapshot, allow redeploy and so on (classic conf for snapshots)
deployer: Jenkins 1.481
same Jenkins job, but entando-core-engine-SNAPSHOT.jar ---> SUCCESS
I need this naming convention because I'm building one of the several experiments we run internally, as opposite to the canonical develop branch which produces a proper entando-core-engine-SNAPSHOT.jar
Any advice?
I'm totally lost.
The thing is that usually your Nexus is configured not to allow a redeployment of a release. A release from Maven point of view is an artifact where it's version it NOT -SNAPSHOT. In contradiction a SNAPSHOT is intended to be deployed several times into nexus.
This sounds like you don't using the release plugin of Maven nor the Release PLugin of Jenkins.
Nexus is a repository manager that uses different repository formats, with the main format being the Maven repository format. Changing the names of artifacts on the server is not possible since it violates the format. They have to be located in the directory structure established by groupId, artifactId and version and use the artifactId-version-classifier.packaging for the file names.
If you need a different file name on the server you have to look at a different repository format (bad idea). If you need the filename on the client just download from the correct name and rename..

Resources