Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?
like image 699
Jake Wharton Avatar asked Oct 19 '12 01:10

Jake Wharton


1 Answers

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...

like image 122
noahlz Avatar answered Oct 06 '22 22:10

noahlz