1

I'm in a situation now where we've moved many projects to a Docker-in-Docker build and use multi-stage Dockerfiles, starting from a custom base image with Maven to build our projects then copy the artifacts to a deployable image. We've written our Dockerfiles using an initial dependency:go-offline step after copying POMs only, in order to cache the layer with the dependencies to try to keep build times down as much as possible when starting from empty images.

The problem is we've just tripped on https://issues.apache.org/jira/browse/MDEP-204 which is a pretty old bug that has since been solved in more recent versions of the maven-dependency-plugin. However, Maven seems to default to a pretty old one.

FIRST, I thought for a moment that I could use a plugin-registry.xml file in our base image to force Maven to default to a newer version, but it seems the feature has been deprecated and I'm not having any luck finding if it was replaced by anything else.

THEN, I thought about trying to be really weird and sneaky and seeing if I could modify the Super-POM somehow to change the default version of the plugin, but that doesn't work. The version in the Super-POM is different than what Maven is defaulting to, and what's more is different projects are defaulting to different versions of the plugin and none of them are specifying that in their POMs. Is there some way like help:effective-pom or a plugin-aware version of dependency:tree that could tell me why some projects are picking certain versions?

I need Maven to reliably use the right version of the plugin when executing go-offline but I'm not sure where I can control it other than directly in the command, but I'd like to avoid having to modify each individual Dockerfile.

Is there still a global mechanism I can build into the Builder image to upgrade the plugin for every project at once, and how do I use it? Or am I just out of luck?

Sloloem
  • 1,587
  • 2
  • 15
  • 37
  • Define the plugins in your pom file (or a parent pom ) in pluginManagement section... that makes your build reliable and independent from any Maven version... best practice... – khmarbaise Nov 19 '20 at 21:42
  • @khmarbaise Parent POM is kindof out of the realm of possibility for us, BUT we do have an organization-wide BOM in ..most... projects for dependencyManagement and I like the idea of adding pluginManagement to that. I'll try that tomorrow morning. – Sloloem Nov 19 '20 at 22:09
  • A corporate parent with defining the plugin versions is best idea ... that helps a lot ... and makes your builds reliable... over different Maven versions etc. and more important it makes them reproducible....I'm not taking about a BOM ... I'm talking about a corporate parent pom... – khmarbaise Nov 20 '20 at 13:17
  • @khmarbaise Yes, technically you're right and I'm very aware of that. But organizationally and politically that would never fly. If I suggested it I'd probably spend the next 6 years arguing with people about it and making sure we didn't completely botch the implementation and that sort of shitshow is much better suited to The Workplace than here. But it's a fight I don't want to have. – Sloloem Nov 20 '20 at 16:42
  • Then the company is not interested in making development effective and support the people... which is very sad... – khmarbaise Nov 21 '20 at 16:40
  • You're not wrong. – Sloloem Nov 23 '20 at 17:25

1 Answers1

4

The short answer that is slightly incorrect but is worth thinking about anyway is: you can't.

A project is in charge of deciding what versions of plugins to use for its purposes, and can, for example, hard code a plugin version in its pom.xml. Overriding such a thing externally would cause the build not to be the same as the author intended.

But, see below:

The longer answer is: it sort of depends on what you want to to do. If really all you want to do is run the go-offline goal, which, by the way, will not, sadly, reliably make your Maven run entirely independent of the network, you can run an individual plugin goal from the command line, and, when you do so, you can specify any version of the plugin you wish. This command line invocation should run the goal in question using version 3.1.2 of the maven-dependency-plugin:

$ mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline
Laird Nelson
  • 15,321
  • 19
  • 73
  • 127
  • That's completely fair. I'm aware it's a bit rude to take that much control away from individual projects but changing 30+ Dockerfiles is a pain. The goal is to pre-cache the project dependencies prior to running the actual build, otherwise the build will re-download every jar every single time you run that build as if you had just installed Maven for the first time. As far as I know that means caching the layer with go-offline in docker, or pre-populating a repository which creates a really big image and requires constant maintenance. – Sloloem Nov 19 '20 at 22:05
  • (To be clear: nothing in my answer suggests altering any project or taking any control away from it whatsoever. I just wanted to make sure that's clear.) – Laird Nelson Nov 20 '20 at 01:07
  • I mean...apart from the alterations being made to the Dockerfile to run the version of the command with the fully-qualified plugin name. But yes, the projects themselves will still use whatever they want outside of the one go-offline command. – Sloloem Nov 20 '20 at 17:49