miércoles, 12 de agosto de 2015

Maven Plugin ClassLoader conflicts

Why Maven oh why????
We love you, we really do.  But some times you just manage to piss off your fans.

Let me tell you guys a story...

Imagine you have a pom.xml file that contains the following dependency:


  com.my.artifact.group
  my-artifact
  1.0.0

Now for the sake of the story let's say you have your custom plugin, or any for that matter:

  com.my.plugin.group
  my-plugin
  1.0.0

Now the hero in this story is happy with his new pom file and ready to make it build so he goes ahead an do:

mvn clean package


BUT WAIT, the build failed!!!!
The exception is not really importan but, again, for the sake of the story let's say it's a NoSuchMethodException.

Afterwards our hero starts tracking the cause of the error, and it so happens that the class with a missing method is part of
my-artifact
But how comes?
When he goes and looks for that class code the method is there.
Weird eh?

He keep on and decides checking different versions of the same artifact and he finally finds out that version 2.0.0 of the artifact does not have such method.

- But wait, I'm not using that artifact am I? - he thinks for himself

He does:
mvn dependency:tree

And also
mvn dependency:resolve

And as he thought the version is the correct one.
After a few hours of useless tests he decides to check the plugin, as it's the only thing left to check.

When he runs:
mvn dependency:tree

He sees something odd:
com.my.artifact.group:my-artifact:2.0.0

- OMFG 2.0.0, WTF!!!!! -  He thinks


And here the story ends!




Now for the more realistic part of this blog, the problem here is Maven uses the same classloader to load both the plugin's dependencies as well as the ones of the project you are trying to build.

So far so good, the problem comes when, like in the story two different versions of the same jar are not compatible. In our story they remove a whole method.

It get's worst there is no easy way track this issue as the logs will only who show that there is an issue but they will also show that the jar being loaded is the one declared in the pom's project giving you now clue on where the problem is coming from.


Solutions:


Well not much to do here. If you control the plugin you could just go ahead and check that pom and exclude the dependency (if possible).

If you don't control it, you can try excluding the dependency or the transitive dependency. Although after a quick search doesn't seems to be that easy.

Any way, the conclusion here is:
* Next time you face a similar problem check the plugin
* To Maven team, guys please find a way to separate the plugin classloader from the one of the application being build.


P.S.: didn't have time to create nice code snippets sorry!