mark maven artifacts for later re-packaging the exact output - maven

I'm looking for a way to mark the artifacts used by maven to re-package wars.
Since some of the dependencies I use, depend on range of versions, the artifacts may change over time, and I want the ability to re-release a specific version of my web application (for example, when hotfix is needed).
After some research, I found that I can use
mvn dependency:go-offline -Dmaven.repo.local=/path
to save all dependencies in /path, and later
mvn -o -Dmaven.repo.local=/path
to use the same artifacts.
This is a fair solution, but will require large amount of storage (or maintaining a version control repository of that storage).
I'm looking for a solution which is more elegant, that uses only the artifact names and versions, instead of actual files. I saw that there's dependency:list and dependency:tree mojos which shows the dependencies used, but is there a way to tell maven to use this list as an input to avoid updating artifacts?
Thanks

Related

List users of an artifact in a repository

I need a tool that will help to find all artifacts that reference another artifact.
When I rebuild an artifact, I need to update/rebuild all artifacts that were using the old version. But I work in a big organisation, and nobody knows really where the artifact is spread in the organisation, so nobody is ever completely sure that everybody use the latest versions.
What I need would be a tool - maybe an artifactory plugin or feature, or a maven plugin doing a lookup in the repository - that indexes all the known poms, and is able to make a listing of all artifacts that have the updated artifact in their dependencies, either directly and transitively. Thus a list of artifacts I would need to rebuild. Quite the opposite of dependency:tree.
Filtering that list by repository, groupId, packaging, etc. is a nice to have. But I can live without.
Any idea?
You can use the Artifactory Query Language with the REST API to do that. For example, if you want to find all builds that use "MySuperAwesomeDependency-1.0.2" your AQL statement would be something like:
//Find builds that use a dependency that is a snapshot
builds.find({"module.dependency.item.name":{"$match":"MySuperAwesomeDependency-1.0.2*"}})
The key in the above statement would be the module.dependency.item.name, which allows you to search for dependencies by name, assuming you store the dependencies in Artifactory.

Find dependant (reverse dependencies) in maven project

I'm trying to find a command that does the opposite of mvn dependency:tree. I want to find out all the projects that depend on a specific module. As trivial as it may sound, I couldn't find such thing.
The use case is in order to find, in a very large project, if I can delete a module or if there are other modules that use it as their dependency.
Try this:
mvn dependency:tree -Dincludes=module
Where module is the dependency you're interested in. You should get the list of libraries that depend on the module you've specified, either directly or transitively.
Although outdated since the question is from 2014, I was looking for something similar:
matching dependencies (f.e. junit) to a list of projects (f.e. maven-compiler-plugin 3.6.0) in use, which should give a list of dependent dependencies currently in use (f.e. junit 4.12). That should point us (for our own projects) to outdated dependencies (f.e. junit 3.8). This will be used for the undeployment of overgrown services (in this case).
Since I was unable to find an automated version (other than manual nexus/repo-plugins or maven-dependency-greps), I wrote a small java tool: reverseDependencies. Feel free to use if you come across a similar task. Note: it will check against the online Nexus-like repository or cache file that you specify.
This is something that is not part of Maven. But it can be implemented in Maven repositories like Nexus and Bintray. The closest I've found is in Bintray and its Build Integration.
But since my clients are using different Maven repositories I needed something that works for any repository. So I created Pom Dependency Analyzer Web that can keep track of dependents, and dependencies.

Creating Hermetic Maven Builds

I am attempting to create a way in which hermetic builds can be achieved while still relying on SNAPSHOT dependencies in your project.
For the purposes of example, say I have a project which has a dependency structure like this:
┌ other-1.2-SNAPSHOT
mine-1.2.3 ──┤
└ thing-3.1-SNAPSHOT ── gizmo-6.1.3-SNAPSHOT
What I would like to do is resolve all the SNAPSHOT dependencies locally to something which is related to my current version and then deploy those as releases to my Nexus' release repository. Not all of these dependencies are internal so I cannot simply just make a release on each.
So, in this example, other-1.2-SNAPSHOT would become something like other-1.2-mine-1.2.3 and thing-3.1-SNAPSHOT would become thing-3.1-mine-1.2.3. This is relatively trivial in about 60 lines of python.
The problem, however, is in resolving transitive SNAPSHOTs to concrete versions. So I also need to convert gizmo-6.1.3-SNAPSHOT to gizmo-6.1.3-mine.1.2.3 and have thing-3.1-mine-1.2.3 depend on it.
This is only an example of one way in which to achieve what I want. The goal is that in a year or two down the road I can checkout my release branch for version 1.2.3 and be able to run mvn clean package or the like without having to worry about resolving long-since-gone SNAPSHOT dependencies.
It's important that this branch be compilable and not just retain all dependencies using something like the jar-and-dependencies functionality of the assembly plugin. I'd like to potentially be able to modify the source files and make another release build (e.g., applying a hotfix).
So,
Is there anything like this available that will be able to convert SNAPSHOT dependencies in a recursive fashion to be concrete?
Are there any plugins which manage this kind of thing for you? The release plugin had promise with some configuration options on its branch goal but it doesn't resolve external deps to the degree that I want.
Are other techniques available for creating hermetic Maven builds?
This is not a widely used technique, but you can always check your specific SNAPSHOT dependencies into your project as a "project" repository, as described in this blog post: Maven is to Ant as a Nail Gun is to a Hammer
In short, use the Dependencies Plugin to create repository located in your project directory. The below is copied from the linked blog post (which you should read):
1) Run mvn -Dmdep.useRepositoryLayout=true -Dmdep.copyPom=true dependency:copy-dependencies
"This creates /target/dependencies with a repo-like layout of all your projects dependencies"
2) Copy target/dependencies/ to something like libs/
3) Add a repository declaration like the following to your POM:
<repositories>
<repository>
<releases />
<id>snapshots-I-need-forever</id>
<name>snapshots-I-need-forever</name>
<url>file:///${basedir}/libs</url>
</repository>
</repositories>
You make this an automated part of your build/release process: step 1 by configuring the Dependencies plugin to a lifecycle phasephase, and step 2 using AntRun Plugin to move the downloaded dependencies to the right place..
Hope this works for you. I have to go take a shower now...
The maven versions plugin will do most of what you want.
http://mojo.codehaus.org/versions-maven-plugin/
However you will almost certianly need to run it in a pre-build step in which you resolve all the dependencies and update the pom file accordingly. Then re-run maven (which re-reads the pom) to run the real build. You might be able to configure everything within the pom itself triggered with a separate goal thus avoiding a separate script.
This works better if you use particular versions instead of SNAPSHOT dependencies and let the pre-build step upgrade them if necessary. The only real difference for dependency resolution is that maven will always re-download -SNAPSHOT dependencies whereas it will only download normal dependencies if there is a new version available. However many plugins (including the versions plugin) treat -SNAPSHOT dependencies differently causing problems. Since every CI build has a new version number I never use -SNAPSHOT, prefering a different tag like -DEV with more predictable behaviour for things like developer local builds etc.
I've spent a lot of time getting maven to do things similar to this. Most maven projects I know have some kind of pre-build step in order to set version numbers or get around other limitations such as this. Trying to do all this in one step usually fails because maven only reads the pom once, string substitution doesn't work in a few places and the deployed/installed pom doesn't generally doesn't contain the results of string substituion or changes made during the build.

Falling back maven dependency to more general classifier

Maven was designed mainly to support Java. I would like however, to store in maven repository some platform-dependent artifacts.
I have 2 classifiers for that purpose:
linux-x86
linux-x64
Is it possible to define a dependency in such a way that if linux-x64 artifact was not found, then Maven attempts to find linux-x86?
Thanks
I'm afraid there's no way of doing this. In fact, it is really against Maven philosophy of being strict and straight about dependencies. Just imagine what compiler should do with such dependencies declaration? Should compile using linux-x86 artifact or linux-x64 artifact? I assume that the API/SPI of this modules is the same thing, but only you know that. Compiler needs specific classpath. And it is hard to say what does it mean in Maven that artifact cannot be found, because people can use different repositories and have different stuff in their local repos, so the build is not repeatable any more. Maven team currently assume as deprecated and advise against version ranges because of build unrepeatability and this is really "soft" thing compared to your idea.
My advice is to always release these two artifact (linux-x86 and linux-x64) and release also the artifacts that depend on them using this 2 classifiers. That's the Maven way.

View a dependency tree in Maven?

I'd like to make sure I'm not including duplicate libraries in my Maven project. I'm pulling in quite a few dependencies from a few different repositories including main, Spring's repo, and JBoss' repository. How can I see a graph of the dependencies so I can make sure I'm not depending on multiple versions of a single library?
It would be kind of a bummer if I was including something like org.springframework:spring-core:3.0.1.RELEASE and org.springframework:org.springframework.spring-core:3.0.5.RELEASE which actually do show up as different dependencies, as weird as it sounds, because Spring's repository names things weirdly. What can I do to make sure I don't have duplicate dependencies?
The dependency:tree maven plugin should do what you want and show the tree.
Alternatively force Maven2 to copy dependencies into target/lib to copy the the artifacts in the target/lib directory which should also show duplicates but you would still need to grep all the POMs in the ~/.m2/repository to see which library is pulling in which version manually and that would be time consuming for large local repositories.
Duplicate libraries can be a problem, but duplicate classes can exist even if no libraries are duplicated. JBoss Tattletale can analyze a set of jar files and produce a report which lists all duplicated classes. There’s a Maven plugin for running the report - see http://docs.jboss.org/tattletale/userguide/1.2/en-US/html/maven.html
If you'd like to get a graphical, searchable representation of the dependency tree (including all modules from your project, transitive dependencies and eviction information), check out UpdateImpact: https://app.updateimpact.com (free service).
Using the search, you can find out how many times a given library is imported, by what modules and in which versions, as well as verify if older versions of a library are evicted by newer ones.
Disclaimer: I'm one of the developers of the site

Resources