You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by Thomas Broyer <t....@gmail.com> on 2014/10/13 01:17:58 UTC

How to resolve artifacts while respecting projects' dependency management? (or finding an alternative)

Hi all,

I have a situation where a plugin needs to take the project's classpath and
add some elements to it. What I'd like is that the elements be resolved as
if they were declared as dependencies in the project's POM: take into
account dependencyManagement for the artifact's version and (more
importantly) its transitive dependencies.
How to do it? (in a way compatible with all Maven 3.x releases)

Or do you think it'd be a better approach to just ask people add those
dependencies to their projects? They're tools needed for building the
project, but they don't need to be in the javac classpath. I tend to
believe this approach is much cleaner, but would appreciate external
feedback.
The plugin currently resolves the dependencies using maven-compat's
ArtifactResolver but I don't think this respects the projects
dependencyManagement (BTW, the "root" artifact passed comes from the
pluginArtifactMap); it also unconditionally add the JARs to the classpath,
which could cause conflicts I believe in some (edge-case) conditions. The
first question I asked because I'd like to keep backwards compatibility and
try to fix things (or at least make them better), but if the best practice
is to add the dependencies to the project using the plugin, I'd just leave
resolution as it is today but disable it behind a flag (either the plugin
extends the classpath in some "broken" way, or you add the dependencies to
your project and the plugin just uses the project's classpath).

-- 
Thomas Broyer
/tɔ.ma.bʁwa.je/ <http://xn--nna.ma.xn--bwa-xxb.je/>

Re: How to resolve artifacts while respecting projects' dependency management? (or finding an alternative)

Posted by Thomas Broyer <t....@gmail.com>.
On Mon, Oct 13, 2014 at 7:53 AM, Anders Hammar <an...@hammar.net> wrote:

> If it is a dependency only needed by the plugin in question (during build
> time) it should not be added to the project's dependencies. However, it
> should probably be added as a dependency to the plugin in the pom, hich
> will add it to the classpath for the plugin execution. However, AFAIK that
> section does not honor versions declared in the depMgmt section.
>

Remember, the goal is to add it to the project's deps to form a classpath
(for a forked JVM or URLClassLoader).
Not respecting dependencyManagement could cause conflicts and all sorts of
weird, hard-to-diagnose, bugs.

Actually, my use case is not much different from annotation processors
(assuming you don't leverage -processorpath): annotation processors are
only needed by the plugin running javac, but an annotation processor might
have a transitive dependency that the project also uses (at a minimum the
one that contains annotations that will be processed, but also various
helpers to generate Java code; think auto-commons, javawriter, maybe even
freemarker or velocity). What you'd want is the classpath containing the
project dependencies, and the annotation processor and its dependencies
that are not also project dependencies, all of that respecting
dependencyManagement. Actually, you'd want the classpath to look exactly as
if the annotation process was declared as a project dependency.

The problem with "plugin dependencies" is that you have less control on the
resolution process, specifically that dependencyManagement doesn't apply
there (which is a good thing, as it could break the plugin!)
Here, the plugin itself doesn't use the dependency so it doesn't need to be
in the plugin's classloader; so using a plugin dependency does not seem to
be a good idea either.

Another example: imagine JUnit was split into 2 JARs: one with the APIs and
one with the actual "runner". Now you'd include the former as a project
dependency but would expect Surefire to provide the latter, but you'd want
Surefire to use your project's dependencyManagement (let's say you use
<scope>import</scope> in your dependencyManagement to make sure all JUnit
deps use the same version, for example). This is actually the exact use
case I'm facing (just with other deps and another plugin); and in some
cases the project will have a direct dependency on the "junit-runner", in
which case you'd expect it to be used, and the plugin to not add anything.


> /Anders
>
> On Mon, Oct 13, 2014 at 1:17 AM, Thomas Broyer <t....@gmail.com> wrote:
>
> > Hi all,
> >
> > I have a situation where a plugin needs to take the project's classpath
> and
> > add some elements to it. What I'd like is that the elements be resolved
> as
> > if they were declared as dependencies in the project's POM: take into
> > account dependencyManagement for the artifact's version and (more
> > importantly) its transitive dependencies.
> > How to do it? (in a way compatible with all Maven 3.x releases)
> >
> > Or do you think it'd be a better approach to just ask people add those
> > dependencies to their projects? They're tools needed for building the
> > project, but they don't need to be in the javac classpath. I tend to
> > believe this approach is much cleaner, but would appreciate external
> > feedback.
> > The plugin currently resolves the dependencies using maven-compat's
> > ArtifactResolver but I don't think this respects the projects
> > dependencyManagement (BTW, the "root" artifact passed comes from the
> > pluginArtifactMap); it also unconditionally add the JARs to the
> classpath,
> > which could cause conflicts I believe in some (edge-case) conditions. The
> > first question I asked because I'd like to keep backwards compatibility
> and
> > try to fix things (or at least make them better), but if the best
> practice
> > is to add the dependencies to the project using the plugin, I'd just
> leave
> > resolution as it is today but disable it behind a flag (either the plugin
> > extends the classpath in some "broken" way, or you add the dependencies
> to
> > your project and the plugin just uses the project's classpath).
> >
> > --
> > Thomas Broyer
> > /tɔ.ma.bʁwa.je/ <http://xn--nna.ma.xn--bwa-xxb.je/> <
> http://xn--nna.ma.xn--bwa-xxb.je/> <
> > http://xn--nna.ma.xn--bwa-xxb.je/>
> >
>



-- 
Thomas Broyer
/tɔ.ma.bʁwa.je/ <http://xn--nna.ma.xn--bwa-xxb.je/>

Re: How to resolve artifacts while respecting projects' dependency management? (or finding an alternative)

Posted by Anders Hammar <an...@hammar.net>.
If it is a dependency only needed by the plugin in question (during build
time) it should not be added to the project's dependencies. However, it
should probably be added as a dependency to the plugin in the pom, hich
will add it to the classpath for the plugin execution. However, AFAIK that
section does not honor versions declared in the depMgmt section.

/Anders

On Mon, Oct 13, 2014 at 1:17 AM, Thomas Broyer <t....@gmail.com> wrote:

> Hi all,
>
> I have a situation where a plugin needs to take the project's classpath and
> add some elements to it. What I'd like is that the elements be resolved as
> if they were declared as dependencies in the project's POM: take into
> account dependencyManagement for the artifact's version and (more
> importantly) its transitive dependencies.
> How to do it? (in a way compatible with all Maven 3.x releases)
>
> Or do you think it'd be a better approach to just ask people add those
> dependencies to their projects? They're tools needed for building the
> project, but they don't need to be in the javac classpath. I tend to
> believe this approach is much cleaner, but would appreciate external
> feedback.
> The plugin currently resolves the dependencies using maven-compat's
> ArtifactResolver but I don't think this respects the projects
> dependencyManagement (BTW, the "root" artifact passed comes from the
> pluginArtifactMap); it also unconditionally add the JARs to the classpath,
> which could cause conflicts I believe in some (edge-case) conditions. The
> first question I asked because I'd like to keep backwards compatibility and
> try to fix things (or at least make them better), but if the best practice
> is to add the dependencies to the project using the plugin, I'd just leave
> resolution as it is today but disable it behind a flag (either the plugin
> extends the classpath in some "broken" way, or you add the dependencies to
> your project and the plugin just uses the project's classpath).
>
> --
> Thomas Broyer
> /tɔ.ma.bʁwa.je/ <http://xn--nna.ma.xn--bwa-xxb.je/> <
> http://xn--nna.ma.xn--bwa-xxb.je/>
>