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.
Related
Is it possible to find all dependencies in a maven projects like mvn dependency:tree, save results to file and then use mvn command for download all dependencies from list file in command line?
thanks
In my experience the various plugins do not get a 100% coverage so the builds will fail. What worked for me, was to start with an empty .m2/repositories folder, and then do the maven commands you need to do, and then persist the now populated .m2/repositories folder.
I experimented with converting it to a local file repository in the project itself so we could do with offline builds, but this turned out to be too big for our purposes. It might not be that much of an obstacle today.
Unless you have very strict political requirements, the usual pragmatic solution is to have a local repository on your network like nexus or artifactory mirroring maven central which is then accessed as a mirror.
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.
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.
I don't understand why this is so difficult:
In a script, I need to copy an artifact from nexus to a certain directory. Using the Nexus REST API I would have to specify the repository which I don't want to have to know about. So I tried getting the artifact with maven-dependency-plugin's get goal instead, which works well. (In that case I get it from a group on our nexus which includes both, releases and snapshots.)
However, I now have the artifact in my local repo and the same plugin's "copy" goal does not seem to be able to get that artifact out of there. Is it really necessary to descend into the .m2 folder and grab that jar with the unix cp command? Anybody ever copied artifacts from their local repos to other dirs before?
Alternatively, if someone can tell me how to get an artifact via the Nexus API without specifying the repo, that would work, too.
Just tried this, and it worked for me:
mvn dependency:copy-dependencies -DincludeArtifactIds=jcharts -DincludeGroupIds=jcharts -DoutputDirectory=/tmp/
This copied the artifact jcharts:jcharts to /tmp/ It was in my local (and remote) repo when this was executed.
Seems like the problem was the _maven.repositories file in conjunction with the particular maven setup at my company.
We don't put the info about the local repo in our settings.xml. It's all in the parent pom that all our projects use. But if you want to do some pure mvn-CLI magic you don't have the parent-pom so you have to provide the URL to the local repo yourself. This is possible with the dependecy:get goal, which is why I was able to download my artifact from our Nexus into my local repo.
When using copy, however, you can't specify a URL. But why would I want to? I just downloaded that artifact into my local repo, right?
That's where the _maven.repositories file comes into play. Even with the -o switch, maven3 consults that file, which specifies the original repo that the artifact came from. (thanks to the guys in this thread for posting their findings!). If it can't reach the repo, it will claim that your file isn't there. (Btw., this is not helpful imho. It should say something about the original repo not being reachable and that the file therefore won't be copied.)
This was the reason why copy didn't work for me.
Simply renaming that file does the trick.
I will have to investigate a cleaner solution to this, though.
To make things even more complicated, I couldn't use dependency:copy or dependency:copy-dependecies. For some reasons they require a pom, which I don't have in my usecase. What does work is org.apache.maven.plugins:maven-dependency-plugin:2.8:copy which I believe is supposed to be the same thing, but that's another story.
Thanks for your answers!
If you are using Sonatype Nexus, you should consider disabling "Central" as outlined in their book.
Otherwise, per #Keith, dependency:copy-dependency will do what you are trying to do. dependency:get specially downloads from remote repositories, as stated in the documentation
You can also force Maven to not download from non-local repositories l by running it in offline mode: -o
Edit
You can also use Maven Wagon Plugin to copy the file from your local repository to an arbitrary directory. This shouldn't require a pom (but you may need to provide the full URL to the jar).
I needed to be able to specify the group ID, artifact ID and version (and packaging), this worked for me:
mvn dependency:copy \
-Dartifact=org.openmrs.web:openmrs-webapp:2.2.0-SNAPSHOT:war \
-DoutputDirectory=/tmp
I am a bit new to maven, but I have some experiences with ant and the build process. I would like to do one thing that is kind of driving me nuts:
Given:
A remote repository (git, svn, hg,…) that holds static content (like images),
one maven project that uses/manages the mentioned repository in the same way as it does with all other dependencies (checkout on install, update whenever updates occur), in other words: the maven project depends on that repository
I finally want to be able to access the content (no *.svn or *.git) and copy it into my build, on build time*.
I want maven to store a local copy of that repository in maven`s local repository (~/.m2/repository) only once on each machine and manage it like all other dependencies.
*I am not trying to build a Java project
Thanks for help!
From what I've seen, Maven projects don't use version control repositories as external artifacts. That's a little too fine-grained for what you want, I think.
I've done something similar, when Project A wanted to use resources from Project B.
Project B, as part of its build procedure, collected it's resources into a ZIP file and deployed the ZIP file into a maven repository.
Project A then references the ZIP file artifact, unpacking it when building to where it needs it.
Look into the dependency plugin for maven, especially the dependency:unpack and dependency:unpack-dependencies goal.
Have fun