On Thu, May 5, 2022 at 10:16 PM Tamás Cservenák <ta...@cservenak.net> wrote:

> Hm,
>
> By reading this blog entry from 2012 (!), I see it summarizes nicely at the
> end:
> * You may be using some broken plugins that you will need to fix, or
> replace.
> * You may be battling a circular dependency hell (which was why you used
> dependency:copy in the first place) which indicates a bad build smell that
> you should eradicate.
> * You may not have the time… well think of all the time you are wasting
> running "mvn install" when you could get away without going so far along
> the lifecycle.
>
> Can you point me to some "reproducer" project (of ANY of these issues
> mentioned in this 10 year old blog), that
> * will reproduce this with modern Maven, think 3.8.x
> * is NOT broken topologically (cycles), is not using broken (by using
> broken plugins) and developers does have time?


Well, one limitation is with extensions: to use a project providing an
extension (custom lifecycle, whatever), you have to install it first. You
could argue that the project would otherwise be broken topologically (and I
agree!) but there's really no way (or did I miss some new feature?) to do
such things without installing the extension first (with Gradle, in
addition to the buildSrc, you can use a "composite build" where one build
provides plugins for the other, including "settings plugins" –where the
settings.gradle file is also where you declare the included build–; Pants
allows you to have in-repo plugins, it's a no-brainer with Bazel too as
it's just how things work, I can't really tell for SBT but you could at
least put plugins in a project/ and possibly symlink to another project to
mimic an "included build" like Gradle)

Other setups seem to work "by accident"; e.g. a project with 3 submodules:
annotations, processor, whatever; where 'whatever' has a dependency on
'annotations' and uses 'processor' in
maven-compiler-plugin's <annotationProcessorPaths>, the order of the
<module> in the aggregator POM is crucial to make it work ('processor' has
to come before 'whatever') *and* you'll have to explicitly include
'processor' in your project list: 'mvn -pl whatever -am verify' won't build
'processor', you have to use 'mvn -pl processor,whatever -am verify'. I
would infer Maven's behavior for reactor ordering as taking the <modules>
declaration order by default, when there's no dependency between modules,
and then the maven-compiler-plugin happens to be able to resolve
'processor' from the reactor build; change the order <module> are declared
and *kaboom*; in the end it does work only "by accident" (or "by chance" if
you prefer).
I wouldn't say the maven-compiler-plugin is "broken", it's just another
Maven limitation: it has no way of knowing that the
<annotationProcessorPaths> actually lists dependencies that could come from
the reactor build and that it would take them into account for determining
which modules to build and in which order.

I don't have an actual use case at hand, this is all theoretical based on
my knowledge of how Maven works so correct me if I'm wrong, but using
custom lifecycles, and due to how build lifecycles work in Maven, running a
goal "in a project" (it's never actually "in a project", it's always run in
all projects of the reactor build, and the plugin itself has to detect or
be configured to know in which module to actually run or skip) might only
partially "build" the depended-on modules in such a way that they won't
work when the plugin actually need them.
Let's take a very hypothetical example, a plugin goal that scaffolds things
in a project, so must not trigger the project's lifecycle as that would
possibly break and we don't care (so either the plugin has no @execute, or
it executes an "early" phase such as 'initialize', or maybe
'process-classes' if it scaffolds tests and somehow needs the project's
main code to do that), but will use some dependency to determine what/how
to do its job (so has a plugin dependency, let's say on another module of
the reactor build). If we do 'mvn -pl target-project -am
the-plugin:scaffold -Dwhatever', then the 'scaffolding-config' submodule
declared as a plugin dependency of 'the-plugin' in project 'target-project'
won't be built besides what the plugin's goal @execute declares. So you'd
actually have to first 'mvn install -pl scaffolding-config' and then 'mvn
-pl target-project the-plugin:scaffold -Dwhatever' (note that I haven't
included -am here).
You could argue this is somehow "broken", I wouldn't disagree, but then
don't argue that Maven itself is not somehow "broken by design" or at a
minimum "limited" in its capabilities: there are cases where using "mvn
install" would be *required* to make things work. Either that or not using
Maven for those things, and rather rely on third-party tooling outside
Maven.

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

Reply via email to