Wednesday, July 8, 2020

When a Maven Release Build says it "Could not resolve dependencies," but...

In This Corner - Apache Maven

I've had this fight with Maven before.  I was always in such a hurry when I finally made the change that ended the fight, that I never stopped to analyze exactly why the issue was resolved.

The whole thing starts when Maven sucker punches me right at the end of the round, when I've got everything working, and it's time to do a release build using the maven-release-plugin.  The build works perfectly, UNLESS it is running within the release plugin.   WHYYYYYYYYYYYY!?!?!?!

The error message starts with: "Could not resolve dependencies" but it goes on to say that the actual dependency that it failed to retrieve is a peer module in the same multi-module project.  That's when I scream obscenities and threaten to change all my builds back to Ant (which at this point, I'm not sure too many people even remember).

Wait.  Why is it trying to "retrieve" it?  It's a peer module, which should be resolved from the reactor.  Why is it trying to find it in a remote repository???

Then the hammering begins...

  • Check that all the groupId tags match each other
    • Yup.  Even removed them from child modules so they're inherited. That's not it.
  • Check that all the version tags match up so the release plugin replaces all of them at once.
    • Yup.  All good,  Even pulled them up into the parent pom's dependencyManagement and used {$project.version} instead of a string that could get messed up.  That's not the issue.
  • Clean up all the dependencies that aren't used (copied/pasted from another project)
    • Didn't work.  No difference.
  • Change the order of the modules in the parent pom
    • Didn't work.  Didn't expect it to.  The reactor reorders them for the build anyway.
  • Add the enforcer plugin in the parent project.
    • Didn't find anything wrong.  At least this keeps my co-workers from dorking it up though.  Will leave that enabled and probably go put it in other projects too.
  • Change the version of plugins to different ones that might have a bug fixed
    • Nope. Same behavior.
  • Compare poms section by section with another project that is building ok.
    • Nothing is jumping out.  The look the same.  WHAT IS DIFFERENT?!?!?
  • Maybe it's character encoding or whitespace.
    • Well, that was a longshot anyway.  Copy/paste in the same IDE/Editor.  Check binary character codes.  That's all the same.

Then the futile Googling begins...


  • Search "maven reactor multi-module dependencies failure"
    • Find some idiot saying to run mvn install, but I already know to NEVER DO THAT!!
  • Search "maven-release-plugin bug"
    • Nothing matches
  • Search "maven-dependency-plugin bug"
    • It actually might be this, but nothing is reported.  Read on and speculate for yourself.
  • Search "maven is stupid and I hate it"
    • Found lots of pointless ranting.

Clues, Circumstances, Sketchy Evidence, and a Good Guess

Then I remember that the state of the Maven reactor changes during the different parts of the build lifecycle.  That has to be related to why the peer module's artifact is missing in action.  But still, why is it ONLY happening during a release build?

Then I see something in the pom for the module that is failing that might explain it.
  <plugin>
      <groupid>org.apache.maven.plugins</groupid>
      <artifactid>maven-dependency-plugin</artifactid>
      <version>3.1.1</version>
      <executions>
          <execution>
              <goals>
                  <goal>properties</goal>
              </goals>
          </execution>
      </executions>
  </plugin>


So, ok... that is related to a hack for a code generation plugin so that it forces Maven to resolve a properties value like this:
<properties>
    <swaggerRef>${com.example.services.myservice:common-abbreviations-service:json:webapp}</swaggerRef>
</properties>

...early enough in the build for the code generation plugin to use it.

So, that explains why the dependency plugin is busy doing stuff BEFORE the reactor has everything ready to resolve locally.

But, it still DOESN'T explain why it only happens in a release build.

Stay tuned.  One day I'll figure out that part too.

(TL/DR) Solved

For now...
If you're having this kind of issue in a build, look around for something that is forcing the normal Maven lifecycle to execute in an unusual order.  The way I resolved this one was to refactor things a bit and make the hacky code-gen module a "leaf" in the module tree.  If there are no peer-module dependencies, it doesn't matter, even in a release-build, if the dependency plugin runs too early.