I'm currently trying to figure out how to make mixins possible in POM 5.

Mixins basically bring a form of multiple inheritance to the POM... which
leads to the problems of how to solve conflicts.

Inheritance Style
=============

The first problem I hit was how to actually deal with a parent that
declares some mixins and a child that declares other mixins where those
mixins declare some of the same mixins from the parent but different
versions... yes a some what esoteric edge case... but we can rest assured
that users will hit this.

I see two solutions to that problem:

Option A: each project is consumed as its effective-pom (i.e. the mixins
are merged before we consider application)
Option B: each project is treated as a graph of its mixins, then to apply
inheritance we do conflict resolution on the versions, pick the "nearest"
version, prune out the subtrees of the "loser" versions and away we go.

Option B feels like the more "correct" option... but heck I cannot even
describe it well so how on earth are users to understand it.

Thus, in the interests of simplifying life for users I am proceeding with
the Option A approach... if that means that your parent has declared the
myfaces-app:2.3 mixin and the child declares a tomee-web:3.0 mixin and that
mixin happens to include myfaces-app:2.5 then the child pom will have both
the myfaces-app:2.3 and myfaces-app:2.5 mixins applied... which may leave
some "junk" that was in the myfaces-app:2.3 but removed from
myfaces-app:2.5 present in the child pom... at least they can figure out
where that "junk" is coming from and remove it from their own effective pom
or bump the parent.

Thoughts?

Inheritance Priority
==============

Mixins on their own are fine. Parents on their own are also fine... when we
have the two, how do we decide who wins.

My current thinking is that there would be some parts of the model that can
only come from the parent: informational stuff, deployment stuff.

But that should be a very small part of the model. We want mixins to be
able to contribute to the rest of the model.

And here's the rub, in my parent I define some default conventions for
plugins, dependencies, etc... we then want the mixins to be able to bring
their best practices with them, so mixins need to be higher priority than
the parent... but we also want the parent to be able to enforce some things.

So say I want my parent to enforce that we only use myfaces for JSF. I may
have dependency management for various other jars... then the child brings
in some mixin and that mixin is directing all the JSF jars to the RI (not
because the mixin is focused on the RI, but because they wanted to align on
one thing)

If mixins happen before parent, then some of the key rules of the mixin
will be defeated.
If mixins happen after parent, then the parent cannot enforce policy.

I believe the enforcement of organizational policies is an important use
case for parent projects, but the quest for mixins that I have seen from
the JIRA is about being able to pull in configuration that has been tested
and should supercede the organizational *defaults*.

I think the solution to this is to give the parent a <policy> section
(which could only contain the elements permitted in a mixin) and have the
inheritance priority be:

1. Start with the defaults for the current template (a.k.a packaging in
4.0.0 speak)
2. Apply the defaults from the parent pom
3. Apply the template specific defaults from the parent pom
4. Apply each mixin in turn (global first, then template specific)
5. Apply the project itself configuration
6. Apply the parent policy.

I think that the parent policy should be inherited from its parents but
whatever is said in the parent policy can override what is said in the
grandparent.

Thoughts?

Thanks for your consideration

-Stephen

Reply via email to