Looked a bit on how to impl this kind of extension and it would help if
maven wouldn't assume everything is hardcoded in components.xml (or eq) or
if sisu would enable to reuse its plexus scanner which has a very low
visibility today. It is also weird to not have access to the guice injector
in components and have to go through the plexuscontainer to lookup beans.

As code often says more than words, here a small hello world showing that
reusing this part of maven "core" is not that trivial:

@Component(role = AbstractMavenLifecycleParticipant.class)
public class CustomLifecycleExtension extends
AbstractMavenLifecycleParticipant {
    @Inject
    private PlexusContainer container;

    @Override
    public void afterProjectsRead(final MavenSession session) throws
MavenExecutionException {
        final Path root =
session.getRequest().getMultiModuleProjectDirectory().toPath();
        final Path configFolder = root.resolve(".extensions/custom");

        final Path mappings = configFolder.resolve("mappings.xml");
        if (Files.exists(mappings)) {
            final ComponentSetDescriptor componentSet =
readAs(mappings, ComponentSetDescriptor.class, null);
            System.out.println(componentSet);
        }

        super.afterProjectsRead(session);
    }

    private <T> T readAs(final Path path, final Class<T> type, final
String wrapper) {
        try {
            final ClassRealm container = this.container.getContainerRealm();
            final Class<?> converterType = container
                    .loadClass("org.eclipse.sisu.plexus.PlexusBeanConverter");
            final Class<?> typeLiteralType = container
                    .loadClass("com.google.inject.TypeLiteral");
            final Object converter = this.container.lookup(converterType);
            return type.cast(converterType.getMethod("convert",
typeLiteralType, String.class).invoke(
                    converter,
                    typeLiteralType.getMethod("get",
Class.class).invoke(null, type),
                    (wrapper != null ? "<" + wrapper + ">" : "") +
                            new String(Files.readAllBytes(path),
StandardCharsets.UTF_8)
                                    .replaceFirst("<\\?[^>]+\\?>", "").trim() +
                            (wrapper != null ? "</" + wrapper + ">" : "")));
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }
}

Indeed it can't work since componentsetdescriptor uses plexusconfiguration
which is not instantiable but it shows the workarounds needed to just
lookup plexus converter and reuse plexus xml binding.

The code should just look like that IMHO:

@Component(role = AbstractMavenLifecycleParticipant.class)
public class CustomLifecycleExtension extends
AbstractMavenLifecycleParticipant {
    @Inject
    private PlexusBeanConverter converter;

    @Override
    public void afterProjectsRead(final MavenSession session) throws
MavenExecutionException {
        final Path root =
session.getRequest().getMultiModuleProjectDirectory().toPath();
        final Path configFolder = root.resolve(".extensions/custom");

        final Path mappings = configFolder.resolve("mappings.xml");
        if (Files.exists(mappings)) {
            final ComponentSetDescriptor componentSet =
readAs(mappings, ComponentSetDescriptor.class, null);
            System.out.println(componentSet);
        }

        super.afterProjectsRead(session);
    }

    private <T> T readAs(final Path path, final Class<T> type, final
String wrapper) {
        try {
            return type.cast(
                    converter.convert(TypeLiteral.get(type),
                            (wrapper != null ? "<" + wrapper + ">" : "") +
                                    new
String(Files.readAllBytes(path), StandardCharsets.UTF_8)

.replaceFirst("<\\?[^>]+\\?>", "").trim() +
                                    (wrapper != null ? "</" + wrapper
+ ">" : "")));
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }
}

Once this part is fixed (using a custom parser) the next one is how to
contribute global components from an extension.

I'll ignore the parsing - currently I have a custom sax parser but I hope
to be able to drop it soon - it is quite easy to contribute back the new
mapping - note i dropped the lifecycle particupant which does not really
help there cause only contributing mappings when the extension is created
makes sense:

@Component(role = StartupContributor.class, instantiationStrategy =
Strategies.LOAD_ON_START)
public class StartupContributor {
    @Inject
    private MavenSession session;

    @Inject
    private PlexusContainer container;

    @PostConstruct
    public void init() {
        final Path root =
session.getRequest().getMultiModuleProjectDirectory().toPath();
        final Path configFolder = root.resolve(".extensions/custom");

        final Path mappings = configFolder.resolve("mappings.xml");
        if (Files.exists(mappings)) {
            final DefaultLifecycleMapping mapping = *loadOrParse(*mappings*)*;

            container.addComponent(mapping, LifecycleMapping.class,
"my-mapping");
        }
    }
}

Then we can put the new mapping as packaging and voilà :).

If you have tips for the parsing it is welcomed otherwise I'll continue to
play with my custom parser.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le dim. 5 juil. 2020 à 11:09, Romain Manni-Bucau <rmannibu...@gmail.com> a
écrit :

> Here is a sample public build: https://github.com/talend/component-runtime
> Interesting modules are - just listing one per type - if master looks
> weird tag 1.1.19 can be a fallback:
>
> 1.
> https://github.com/Talend/component-runtime/blob/master/component-starter-server/pom.xml
> 2.
> https://github.com/Talend/component-runtime/blob/master/documentation/pom.xml
> 3.
> https://github.com/Talend/component-runtime/blob/master/images/component-server-image/pom.xml
>
> Side note being some other - private :( - module do all the 3 things in a
> single module - and indeed faking module for build constraints is not an
> option.
>
> Hope it helps.
>
> Le dim. 5 juil. 2020 à 11:02, Hervé BOUTEMY <herve.bout...@free.fr> a
> écrit :
>
>> Le samedi 4 juillet 2020, 23:15:19 CEST Romain Manni-Bucau a écrit :
>> > Le sam. 4 juil. 2020 à 18:09, Stephen Connolly <
>> >
>> > stephen.alan.conno...@gmail.com> a écrit :
>> > > On Sat 4 Jul 2020 at 16:54, Romain Manni-Bucau <rmannibu...@gmail.com
>> >
>> > >
>> > > wrote:
>> > > > Le sam. 4 juil. 2020 à 16:38, Stephen Connolly <
>> > > >
>> > > > stephen.alan.conno...@gmail.com> a écrit :
>> > > > > On Sat 4 Jul 2020 at 10:21, Romain Manni-Bucau <
>> rmannibu...@gmail.com>
>> > > > >
>> > > > > wrote:
>> > > > > > Well, there are two points I'd like to emphasis:
>> > > > > >
>> > > > > > 1. I dont think we should wait for 2 majors to get that as a
>> > > > > > feature,
>> > > > >
>> > > > > would
>> > > > >
>> > > > > > be too late IMHO
>> > > > >
>> > > > > Well does my dynamic phases PR do what you need?
>> > > >
>> > > > Partly if you think to priority one, it moves the issue a bit
>> further
>> > > > due
>> > > > to priority usage which is not great in practice compare to names +
>> > > > requires to use 100, 200 etc to be able to inject plugin between two
>> > >
>> > > others
>> > >
>> > > > in children with the project becoming more complex. Think we must
>> have
>> > > > an
>> > > > explicit control here even with complex hierarchies.
>> > >
>> > > If you need that much control then you’re doing something wrong.
>> > >
>> > > How often do you need more than 3-4 plugin executions in strict
>> ordered
>> > > succession?
>> >
>> > All my projects not being libraries since ~7 years. Frontend is often 3
>> > exec, living doc is often 4-5 exec, docker is often 3-4 exec too (needs
>> > some computation steps for cds or build time precomputation things) plus
>> > custom resources, git integration meta, custom artifact attachement,
>> etc...
>> I like this approach: can we share a demo project to have a concrete case?
>>
>> > These are very common use cases today in the same build. It is key to
>> keep
>> > a single build orchestrator (mvn) for team sharing and CI
>> > industrialization. Issue being each project set it up differently and
>> > making it generic is often overcomplex (living doc can be jbake plugin
>> or a
>> > plain mvn exec:java or a groovy script etc... depending doc output and
>> > reusability of the code+libs). With software lifecycle passing from
>> years
>> > to months we are in a more dynamic and changing ecosystem our beloved
>> build
>> > tool should align on IMHO.
>> I suppose we all agree from very high level point of view: IMHO, we now
>> need
>> to dig a little more in detail on typical cases, with sample demo builds.
>> Then
>> we'll work on solutions.
>>
>> >
>> > > That sounds like a dedicated plugin use case
>> >
>> > This is why i want a generic extension as solution, each project have
>> its
>> > specificities and standardizing it is hard and likely adds too much
>> > complexity compared to let the user enriching default phases (can be a
>> > merge of 2 packagings instead of a new one fully defined).
>> yes, looks like adding "sub-packaging"s for additional build aspects
>> (frontend, living doc, container, ...), taking care of eventual
>> interactions
>> between each one
>>
>> >
>> > If I stick to plain maven and want a clean build without workarounds I
>> must
>> > write plugins+extensions for each of the apps - plugins and ext must be
>> > reusable or not be IMHO, sounds not great whereas maven backbone is very
>> > good, this is why I want to push it to the next step to keep a high
>> quality
>> > unique (in terms of #tools) build for projects.
>> >
>> > I dont have big blockers to do it without patching maven itself so will
>> not
>> > spend much energy if idea is not liked but I hope maven tackles it some
>> day
>> > in a built in fashion (which means better IDE and ecosystem integration
>> > even if personally I dont abuse of that).
>> from experience, sharing a solution before sharing issues that the
>> solution is
>> expected to solve makes it hard to get consensus.
>> You shared the high level issue: that's great.
>> Now we must share sample builds.
>> And work on solutions.
>> I'm all in
>>
>> Regards,
>>
>> Hervé
>>
>> >
>> > > > > > 2. Pom model is based on inheritance whereas years showed
>> > > > > > composition
>> > > >
>> > > > and
>> > > >
>> > > > > > reuse is saner so IMHO it does not belong to pom but .mvn
>> > > > >
>> > > > > Your proposal would only work if all projects shared the same
>> > > > > packaging
>> > > >
>> > > > as
>> > > >
>> > > > > Hervé pointed out that the lifecycle is pulled in based on
>> packaging.
>> > > >
>> > > > No cause you define the packaging to use in  the pom already - since
>> > >
>> > > maven
>> > >
>> > > > 2 IIRC - so you can define as much packagings as you want in .mvn.
>> To be
>> > > > concrete, it just enables to have an exploded extension in the
>> project
>> > > > instead of requiring it to be packaged as a jar. Does not reinvent
>> the
>> > > > wheel ;).
>> > > >
>> > > > > What you probably want is .mvn/${packaging}/lifecycle.xml so you
>> can
>> > > > > override custom
>> > > > >
>> > > > > A bug you may encounter is where phase names are not common
>> across the
>> > > > > reactor
>> > > >
>> > > > Yep, build/extension must enforce common checkpoints (package,
>> install,
>> > > > deploy out of my head) for all modules. Not a big deal if validated
>> > >
>> > > during
>> > >
>> > > > initialize phase I think.
>> > > >
>> > > > > > Le sam. 4 juil. 2020 à 10:19, Robert Scholte <
>> rfscho...@apache.org>
>> > >
>> > > a
>> > >
>> > > > > > écrit :
>> > > > > > > Stephen had an idea for it in Model 5.0.0[1], and IIRC I
>> still had
>> > >
>> > > my
>> > >
>> > > > > > > concerns.
>> > > > > > > It is still a draft with a lot of ideas, that hasn't really
>> been
>> > > > > >
>> > > > > > discussed
>> > > > > >
>> > > > > > > yet, because it was still out of reach.
>> > > > > > > However, we're getting closer
>> > > > > > >
>> > > > > > > Robert
>> > > > > > >
>> > > > > > >
>> > > > > > > [1]
>> > >
>> > >
>> https://cwiki.apache.org/confluence/display/MAVEN/POM+Model+Version+5.0.0#
>> > > POMModelVersion5.0.0-%3Cproject%3Eelement>
>> > > > > > > On 4-7-2020 09:03:08, Romain Manni-Bucau <
>> rmannibu...@gmail.com>
>> > > > >
>> > > > > wrote:
>> > > > > > > I agree I mixed both in my explanation....cause they only make
>> > >
>> > > sense
>> > >
>> > > > > > > together for a build as shown by the pre/post recurrent
>> request
>> > >
>> > > which
>> > >
>> > > > > > aims
>> > > > > >
>> > > > > > > to enrich the lifecycle to bind custom plugins.
>> > > > > > >
>> > > > > > > Today projects are no more just about creating a jar - war
>> are no
>> > > >
>> > > > more
>> > > >
>> > > > > > > about java etc... - most of the time (frontend, living doc,
>> build
>> > > >
>> > > > time
>> > > >
>> > > > > > > generation, security validation, ....). Indeed you can force
>> to
>> > >
>> > > bind
>> > >
>> > > > > > > plugins to existing phases but it is quite hard, unatural and
>> > >
>> > > rarely
>> > >
>> > > > > > > maintainable in time: whatever you do, you want a custom
>> packaging
>> > > > >
>> > > > > using
>> > > > >
>> > > > > > a
>> > > > > >
>> > > > > > > custom lifecycle (to be able to run separately phases of the
>> build
>> > >
>> > > -
>> > >
>> > > > > and
>> > > > >
>> > > > > > > sometimes independently, mvn frontend not depending of mvn
>> package
>> > >
>> > > or
>> > >
>> > > > > mvn
>> > > > >
>> > > > > > > compile would be neat but not required for me).
>> > > > > > >
>> > > > > > > So the extension i have in mind will handle both or wouldnt be
>> > > >
>> > > > usable.
>> > > >
>> > > > > > > About loosing the convention, after fighting for 7 years to
>> not
>> > > >
>> > > > respect
>> > > >
>> > > > > > it,
>> > > > > >
>> > > > > > > I think the ecosystem changed and we must accept it as bazel
>> and
>> > > >
>> > > > gradle
>> > > >
>> > > > > > do.
>> > > > > >
>> > > > > > > Does not mean we break ourself, we keep our default, it just
>> means
>> > >
>> > > an
>> > >
>> > > > > > > application must be able to redefining its own
>> lifecycle+packaging
>> > > > >
>> > > > > (which
>> > > > >
>> > > > > > > is a pair named a build ;)).
>> > > > > > >
>> > > > > > > Think we can't stack plugin on a single phase anymore, having
>> 5+
>> > > > >
>> > > > > plugins
>> > > > >
>> > > > > > on
>> > > > > >
>> > > > > > > pre-package is very hard to maintain and share in a team -
>> plus it
>> > > > >
>> > > > > doesnt
>> > > > >
>> > > > > > > really makes sense on a build point of view.
>> > > > > > >
>> > > > > > > Indeed we can add phases as we have process classes after
>> compile,
>> > > > > > > prepackage before package etc.. but it stays arbitrary for
>> maven
>> > > > >
>> > > > > project
>> > > > >
>> > > > > > > dev and does not reflect the agility projects take these days
>> IMHO
>> > > >
>> > > > and
>> > > >
>> > > > > if
>> > > > >
>> > > > > > > done in our core delivery it would slow down most build for no
>> > > > > > > gain
>> > > >
>> > > > so
>> > > >
>> > > > > it
>> > > > >
>> > > > > > > must be in user land IMHO.
>> > > > > > >
>> > > > > > > Hope it makes more sense presented this way.
>> > > > > > >
>> > > > > > >
>> > > > > > >
>> > > > > > > Le sam. 4 juil. 2020 à 05:28, Hervé BOUTEMY a
>> > > > > > >
>> > > > > > > écrit :
>> > > > > > > > first: thanks for sharing
>> > > > > > > >
>> > > > > > > > from a high level point of view, the risk I see is to loose
>> our
>> > > > > > > > conventions.
>> > > > > > > > But let's try and see before judging
>> > > > > > > >
>> > > > > > > > I think there are 2 topics currently mixed:
>> > > > > > > > - default lifecycle phases:
>> > > > > > > > do you want to add or remove phases? [1]
>> > > > > > > > - default plugin bindings:
>> > > > > > > > clearly, you want to have specific default bindings. On
>> default
>> > > > > > > > bindings, as
>> > > > > > > > they are defined per-packaging [2] (that's what is triggered
>> > >
>> > > behind
>> > >
>> > > > > > > > packaging
>> > > > > > > > in pom.xml)
>> > > > > > > >
>> > > > > > > > Regards,
>> > > > > > > >
>> > > > > > > > Hervé
>> > > > > > > >
>> > > > > > > > [1]
>> > >
>> > > https://maven.apache.org/ref/3.6.3/maven-core/lifecycles.html
>> > >
>> > > > > > > > [2]
>> > > > > >
>> > > > > >
>> https://maven.apache.org/ref/3.6.3/maven-core/default-bindings.html
>> > > > > >
>> > > > > > > > Le vendredi 3 juillet 2020, 09:20:25 CEST Romain
>> Manni-Bucau a
>> > > >
>> > > > écrit
>> > > >
>> > > > > > > > > Hi everyone,
>> > > > > > > > >
>> > > > > > > > > Wonder if we already discussed defining the lifecycle in
>> the
>> > > > >
>> > > > > project
>> > > > >
>> > > > > > > > (maybe
>> > > > > > > >
>> > > > > > > > > in $root/.mvn).
>> > > > > > > > > High level the need is to be able to change the default
>> > >
>> > > lifecycle
>> > >
>> > > > > in
>> > > > >
>> > > > > > > the
>> > > > > > >
>> > > > > > > > > root pom without having to define a custom extension - in
>> > > > > > > > > other
>> > > > >
>> > > > > words
>> > > > >
>> > > > > > > it
>> > > > > > >
>> > > > > > > > is
>> > > > > > > >
>> > > > > > > > > about having a built-in extension.
>> > > > > > > > > The typical need is to add a mojo in the default lifecycle
>> > > > > > > > > (add
>> > > > > > >
>> > > > > > > frontend
>> > > > > > >
>> > > > > > > > > magement for ex) or replace some plugins by others (for
>> > > > > > > > > example
>> > > > > > >
>> > > > > > > compiler
>> > > > > > >
>> > > > > > > > by
>> > > > > > > >
>> > > > > > > > > scalac plugin, surefire by spec2 plugin for a scala based
>> > >
>> > > project
>> > >
>> > > > > > > > etc...).
>> > > > > > > >
>> > > > > > > > > The way I'm seeing it is to let the xml defining the
>> lifecycle
>> > >
>> > > be
>> > >
>> > > > > put
>> > > > >
>> > > > > > > in
>> > > > > > >
>> > > > > > > > > .mvn/default-lifecycle.xml - I don't know if we want to
>> use
>> > > > > > > > > the
>> > > > > >
>> > > > > > prefix
>> > > > > >
>> > > > > > > > > (default here) as a reference you can put in the pom but
>> at
>> > >
>> > > least
>> > >
>> > > > > > > default
>> > > > > > >
>> > > > > > > > > makes sense IMO.
>> > > > > > > > > The lifecycle.xml itself would likely be extended to add
>> some
>> > > > > > > >
>> > > > > > > > precondition
>> > > > > > > >
>> > > > > > > > > to each plugin (if src/main/frontend exists then add
>> > >
>> > > frontend:npm
>> > >
>> > > > > for
>> > > > >
>> > > > > > > > ex).
>> > > > > > > >
>> > > > > > > > > I know it is a quite common need I have and not something
>> I
>> > >
>> > > would
>> > >
>> > > > > put
>> > > > >
>> > > > > > > in
>> > > > > > >
>> > > > > > > > a
>> > > > > > > >
>> > > > > > > > > custom extension because it is very "by project" and not
>> > > >
>> > > > shareable
>> > > >
>> > > > > > so a
>> > > > > >
>> > > > > > > > > shared extension does not make sense and packaging a
>> > > > >
>> > > > > plugin/extension
>> > > > >
>> > > > > > > > for a
>> > > > > > > >
>> > > > > > > > > single project is bothering for nothing.
>> > > > > > > > >
>> > > > > > > > > I'm planning to give a try with a custom extension in the
>> > >
>> > > summer
>> > >
>> > > > > but
>> > > > >
>> > > > > > > > > thought it can be worth some discussion there too.
>> > > > > > > > >
>> > > > > > > > > Wdyt?
>> > > > > > > > >
>> > > > > > > > > Romain Manni-Bucau
>> > > > > > > > > @rmannibucau | Blog
>> > > > > > > > >
>> > > > > > > > > | Old Blog
>> > > > > > > > > | Github
>> > > > > > > >
>> > > > > > > > https://github.com/rmannibucau>
>> > > > > > > >
>> > > > > > > > > | LinkedIn | Book
>> > >
>> > >
>> https://www.packtpub.com/application-development/java-ee-8-high-performanc
>> > > e
>> > >
>> > > >
>> ---------------------------------------------------------------------
>> > > >
>> > > > > > > > To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
>> > > > > > > > For additional commands, e-mail: dev-h...@maven.apache.org
>> > > > >
>> > > > > --
>> > > > > Sent from my phone
>> > >
>> > > --
>> > > Sent from my phone
>>
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
>> For additional commands, e-mail: dev-h...@maven.apache.org
>>
>>

Reply via email to