I've been experimenting with profile-based system that is close to mixins [1]. Another existing maven extension for this is maven-tiles [2]. I think your design is close to maven-tiles, so you can try to survey it's developers to get feedback based on actual usage...
Personally after my experiments with these systems I've come to a conclusion that mixins is wrong direction. I envision that the best solution to all my use-cases is configurable lifecycle/lifecycle-mapping [3]. Configurable lifecycle should be like a collection of mixins defined in single module and thus guaranteed to work seamlessly with each-other. Mixin selection/activation mechanism should also be defined in configurable-lifecycle component and can be made as ergonomic as needed using custom configuration same way configuration is used by mojos. [1] https://github.com/sviperll/ozymandias/tree/master/maven-profiledep-extension [2] https://github.com/repaint-io/maven-tiles [3] https://issues.apache.org/jira/browse/MNG-6129 -- Victor Nazarov On Mon, Dec 5, 2016 at 1:56 AM, Stephen Connolly < [email protected]> wrote: > 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 >
