How do I checkout artifact sources given its coordinates in Maven? - maven

I'm about to write a tool with which our developers can checkout sources for an artifact given its maven coordinates. The tool should be able to optionally checkout sources recursively for all SNAPSHOT dependencies as well.
My first question would be: Do I need to write this tool at all? One would imagine that this isn't a very unique user scenario, but I have yet failed to find something suitable to achieve this. I have looked at scm:checkout and scm:bootstrap, both require knowledge about the connection url where as I only have a artifactID. Is there any other way, but to write a custom tool, to do this?
If not, my home brew tool would do something in the lines of:
Parse .m2/settings.xml to determine which repo to use Download the pom for the artefact.
Create a temporary bootstrap-pom with the scm-tag from the downloaded pom.
Use scm:bootstrap and the bootstrap-pom to checkout sources.
[Optionally] Search the sources for poms with SNAPSHOT dependencies and repeat the process.
My second question would be: Does this sound like a good way to go about it to you? Any caveats spring to mind?

For each project you want to checkout this way, you could add a profile containing plugin configuration for the scm plugin's bootstrap goal. The plugin config would be in the same POM as the scm URL, so that handles #2 & 3; you wouldn't need a separate bootstrap-pom.
For getting the initial POM, you could use dependency:get from the command line:
mvn dependency:get -Dartifact=some.group:my.artifact:version:pom -Ddestination=someDirectory
In the directory with the downloaded POM, you perform the bootstrap:
mvn -Pbootstrap-profile-id scm:bootstrap
which would check out the top level project.
I don't know how you'd make this recursive. You might be able to use dependency:copy-dependencies asking for transitive dependencies and copying POMs, and then running the bootstrap process on each of those. Not sure how that would work.

The solution of user944849 doesn't work for me, but here is an example that works
mvn dependency:get -Dartifact=ar.com.hjg:pngj:2.1.0:pom -Ddest=pom.xml
mvn scm:bootstrap -Dgoals=validate
mv target/checkout ~/projects/pngj

Related

Maven - dependency list and download artifacts

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.

Jenkins & Maven - build process

I am learning about Jenkins and I have to explore some existing build jobs that others wrote (in the company that I'm working).
So I am trying to understand a job which uses mvn command.
So under the build part (inside the job), I see these details:
Maven version: 3.0.5
Root POM: pom:xml
Goals and options: clean install -U -Pnotest,docs
I'm trying to understand what this mvn command means?
I tried to google it: "clean install -U"
But I didn't find what the parameter U means.
And I don't know what is "-Pnotest,docs".
can you guide me regarding how I can find what's it? (maybe "-Pnotest,docs" is from a xml file or it's from the artifactory etc..)
Thanks a lot!!!!
-U Forces a check for miss releases and updated snapshots on remote repositories
If Maven is regularly used in your company, and you will have to work with it on a day-to-day basis, I would advise you to find a mentor (any colleague that knows the tool well and is ready to share its knowledge with you) and work with them. Maven, when you first look at it, can be quite of a mouthful and you'll learn it more efficiently with their help.
For the problem at hand, Elarbi Mohamed Aymen's answer already tells you what the -U flag corresponds to. As for -P, it is used to activate profiles (in your case notest and docs). These profiles are usually defined in the pom.xml of the project being build.
See Running Apache Maven for the basic commands, and as advised on that page run mvn -h to have the complete list of flags the command can use.
Maven is one of the mechanism how to handle the build process and check project dependencies, especially for Java.
One of the option can be to have physically included dependencies (artifacts / libs) in the project, but its not so useful- in case of new version, you have to replace the file, sometimes you are using same lib in more apps, ten you have to handle it manually in all projects.
Except this, there is the maven- it has a global repository with shared artifacts / libs , which are common used- ref. https://repo1.maven.org/maven2/.
Except this, you can make your own libs/ artifacts in this case, its a modules / applications which are reusable, then you are storing it in private repository- this is the artifactory.
When you want to build your project, in case of maven project you have pom.xml , which is like manual for maven what to do / how to build.
clean and install are common goals, clean will wipe your local maven repository, install will download them again, with parameter -U it force to download them.
You can define your own goals in pom file, eg. to "tree build"- build some dependent modules, then build parent project.
Eg. with -D you pass parameters to the maven eg.
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app
- that will generate new project, based on given archetype- "template", with the given groupID and artifactID- groupID can be eg. company name, artifactID is then the name of specific app / component.
-P,--activate-profiles <arg> Comma-delimited list of profiles
to activate
-D,--define <arg> Define a system property

Define artifact finalName in Hudson on Maven project

I am unable to edit pom.xml. Is there a way to define final name of the maven artifact built by Hudson, something like this
<finalName>${project.artifactId}-${project.version}-${timestamp}</finalName>
Since mvn -DfinalName="xxx" on command line does not seem to work.
I am looking for Hudon/Jenkins feature to achieve this as well, or modifying settings.xml in maven repo. Basically any method except editing pom.xml
First, you could have a second build step (execute shell or windows batch) to simply rename the artifacts. Obviously, this will forego the automatic maven module artifacting, but are you using that? If not, just archive the file with post-build actions directly on Jenkins or repository of choice.
Second, the moment you check out the files from SVN, you do have access to modify them in your local workspace. Just don't commit them back to repository.
You could run a regex replace to look for <fileName>.*</filename> and replace with whatever you want.

copy artifact from local maven repository

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

How to update maven repository manually from the maven build?

We do not have our own repository at the moment. So, when we build with maven it creates .m2 repository in the home directory of the current user.
Now there are two third party jars which are not found in the Maven Central. Suppose one of them is hasp-srm-api.jar. Today the process is this:
a. The pom.xml of the project depending on hasp-srm-api.jar contain these lines:
<dependency>
<groupId>com.safenet</groupId>
<artifactId>hasp</artifactId>
<version>1</version>
</dependency>
b. Before doing the first build we execute the following command:
mvn install:install-file -Dfile=hasp-srm-api.jar -DgroupId=com.safenet -DartifactId=hasp -Dversion=1 -Dpackaging=jar
My question is this - is it possible to automate this step? I would like to be able to tell maven to check whether the hasp artifact exists and if not - install it manually using the aforementioned command line. How can I do it?
NO. It is not possible to have maven automatically deploy an artifact into a repository in the fashion you suggest. This goes for both local and remote repositories. If the artifact exists in a some repository somewhere, you can add that repository to your build's list of known remote repos, but other than that you have to add it yourself.
You can add it to your local .m2 repository, but that will then only be good for that individual environment. Other dev's will have to repeat the process. This is one of the main attractions of running your own repository server( like Nexus ); you can add the artifact to that repository and then everyone in your organization can use it forever. There is still no way to automate the deployment of the artifact, but it's easy to do and is permanent.
Note, setting up a repository manager is very easy to do. It's highly recommended. It makes the whole Maven thing make a whole lot more sense.
The best solution for such problems is using a repository manager which results in installing such kind of dependencies only once into the repository manager and the whole company can use it a usual dependency. That's it.
Other option you have is to write your own maven plugin. May be below link will be right place for you start
MOJO FAQ

Resources