Well, using the session for that would be much simpler... just my 5 cents
So you could use participant only to implement this "protection", but keep
using spy for the rest.

T

On Wed, Jun 29, 2022 at 1:24 PM François Guillot <
francoisguillo...@gmail.com> wrote:

> Hey,
>
> Thanks for all your suggestions.
> I don't like AbstractMavenLifecycleParticipant that much because it doesn't
> offer fine-grained callbacks. Only sessionStar/End and projectsRead.
> While EventSpy allows to hook into many more events fired by the
> EventCatapult.
> But this is just a detail.
>
> Thanks for the suggestion about sisu-maven-plugin.
>
> I thought about the idea of using the file system and a marker file to
> detect double applications and all that.
> I might do that then.
>
> Thanks
>
> François
>
>
> Le mer. 29 juin 2022 à 13:08, Tamás Cservenák <ta...@cservenak.net> a
> écrit :
>
> > And one more thing....
> >
> > Migrate off from legacy Plexus XML
> > src/main/resources/META-INF/plexus/components.xml
> >
> > and use JSR330 instead:
> > - add javax.inject:javax.inject:1 as dependency
> > - annotate your imple with @Singleton/@Named( "default" )
> > - use sisu-maven-plugin in the build to index annotated classes
> >
> > Thanks all
> > T
> >
> > On Wed, Jun 29, 2022 at 1:05 PM Tamás Cservenák <ta...@cservenak.net>
> > wrote:
> >
> > > Also, if you'd not use oldie EventSpy, but
> > > AbstractMavenLifecycleParticipant instead, you'd gain access to
> session,
> > > and would become even simpler:
> > > just stick something with specific (to your extension, like G:A) key
> and
> > > dummy value (Boolean,TRUE) into session.
> > > And then you know: if that key IS PRESENT when init, you was not the
> > first
> > > instance of extension to init.
> > >
> > > T
> > >
> > > On Wed, Jun 29, 2022 at 1:01 PM Tamás Cservenák <ta...@cservenak.net>
> > > wrote:
> > >
> > >> Howdy,
> > >>
> > >> First of all, if you alter the maven classpath, there is not much
> Maven
> > >> itself can do (as it happens before maven happens). How are
> conflicting
> > >> classes handled depends on Java, not Maven.
> > >>
> > >> So, I'd really just neglect the use of `maven.ext.class.path` (or
> adding
> > >> things to lib/ext). Using these you (or user) is tampering with very
> > >> internals, and should be really aware of what is being done.
> > >>
> > >> Hence, I went with the 2nd case, the `.mvn/extensions.xml` and used
> this
> > >> one:
> > >> <?xml version="1.0" encoding="UTF-8"?>
> > >> <extensions>
> > >>     <extension>
> > >>         <groupId>org.example</groupId>
> > >>         <artifactId>double-core-bindings-override</artifactId>
> > >>         <version>1.0</version>
> > >>     </extension>
> > >>     <extension>
> > >>         <groupId>org.example</groupId>
> > >>         <artifactId>double-core-bindings-override</artifactId>
> > >>         <version>2.0</version>
> > >>     </extension>
> > >> </extensions>
> > >>
> > >> And to my biggest surprise, Maven did load both extensions just fine
> > >> (based on file order, if you make it 2.0, then 1.0, it will load in
> that
> > >> order).
> > >>
> > >> [cstamas@urnebes DoubleCoreBindingsOverride]$ ./mvnw validate
> > >> [INFO] Found MyExtension in realm
> > >> 'coreExtension>org.example:double-core-bindings-override:1.0'
> > >> [INFO] Found MyExtension in realm
> > >> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >> [INFO] Inside MyExtension#init for extension loaded in realm
> > >> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >> [INFO] Instantiating MyPluginManager for extension loaded in realm
> > >> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >> [INFO] Using the MavenPluginManager 'MyPluginManager' from realm '
> > >> coreExtension>org.example:double-core-bindings-override:2.0'
> > >> [INFO] Inside MyExtension#init for extension loaded in realm
> > >> 'coreExtension>org.example:double-core-bindings-override:1.0'
> > >> [INFO] Using the MavenPluginManager 'MyPluginManager' from realm '
> > >> coreExtension>org.example:double-core-bindings-override:2.0'
> > >> [INFO] Scanning for projects...
> > >> [INFO]
> > >> [INFO] -------------< org.example:double-core-bindings-override
> > >> >--------------
> > >> [INFO] Building DoubleCoreBindingsOverride reproducer 2.0
> > >> [INFO] --------------------------------[ jar
> > >> ]---------------------------------
> > >> [INFO]
> > >>
> ------------------------------------------------------------------------
> > >> [INFO] BUILD SUCCESS
> > >> [INFO]
> > >>
> ------------------------------------------------------------------------
> > >> [INFO] Total time:  0.037 s
> > >> [INFO] Finished at: 2022-06-29T12:51:56+02:00
> > >> [INFO]
> > >>
> ------------------------------------------------------------------------
> > >> [cstamas@urnebes DoubleCoreBindingsOverride]$
> > >>
> > >> ===
> > >>
> > >> All in all, to prevent this (obviously user mistake), I'd not think
> too
> > >> much about it: maybe just create a "known" file during init
> > >> - if file does not exist, write an extension version into it
> > >> - if exists, read its content and if matches extension version, all
> ok,
> > >> otherwise just explode?
> > >> - delete the file in close (when session ends)
> > >>
> > >> This way you will ensure that IF there was a user mistake (double
> > >> configured your extension w/ different versions), it will not end up
> in
> > an
> > >> inconsistent build, but the user is forced to fix it?
> > >> You could also just create a file (and neglect version), as if file
> was
> > >> created during init, your 2nd instance should fail (as it means there
> > are
> > >> more than one instances of your extension present).
> > >>
> > >>
> > >> HTH
> > >> T
> > >>
> > >>
> > >> On Tue, Jun 28, 2022 at 4:31 PM François Guillot <
> > >> francoisguillo...@gmail.com> wrote:
> > >>
> > >>> Hi again
> > >>>
> > >>> I can't go into details because it's a proprietary extension, but we
> > need
> > >>> to change the behaviour of
> > >>> - *DefaultMavenPluginManager*: we need to intercept calls to
> > Mojo#execute
> > >>> so here we proxy the Mojo class that is created from the
> mojoInterface
> > >>> with
> > >>> some custom stuffs
> > >>> - *DefaultBuildPluginManager*: we decorate the #executeMojo with some
> > >>> custom calls to internal classes of ours
> > >>>
> > >>> For now, all is good. I just realized the overridden components might
> > not
> > >>> come from the expected extension so let's say we are theorizing about
> > >>> some
> > >>> possible future binary breakage.
> > >>>
> > >>> You can find attached a small reproducer:
> > >>>
> > >>>
> >
> https://drive.google.com/file/d/1M-wfS8E_VgHF6qd1CthkHQuzkYEMqNe1/view?usp=sharing
> > >>>
> > >>> (I could not attach the zip directly to Gmail ...)
> > >>>
> > >>> To reproduce, once unzipped:
> > >>> - ./mvnw clean install => install 1.0 in your local repo
> > >>> - change version to 2.0 in pom.xml
> > >>> - ./mvnw clean install => install 2.0 in your local repo
> > >>> - add ".mvn/extensions.xml" with
> > >>> ----------
> > >>> <?xml version="1.0" encoding="UTF-8"?>
> > >>> <extensions>
> > >>> <extension>
> > >>> <groupId>org.example</groupId>
> > >>> <artifactId>double-core-bindings-override</artifactId>
> > >>> <version>1.0</version>
> > >>> </extension>
> > >>> </extensions>
> > >>> ----------
> > >>> - execute ./mvnw validate
> > >>>
> > >>>
> >
> -Dmaven.ext.class.path=${HOME}/.m2/repository/org/example/double-core-bindings-override/2.0/double-core-bindings-override-2.0.jar
> > >>>
> > >>> You should then see sth like
> > >>>
> > >>> [INFO] Found MyExtension in realm 'maven.ext'
> > >>> [INFO] Found MyExtension in realm
> > >>> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Inside MyExtension#init for extension loaded in realm
> > >>> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Instantiating MyPluginManager for extension loaded in realm
> > >>> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Using the MavenPluginManager 'MyPluginManager' from realm '
> > >>> coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Inside MyExtension#init for extension loaded in realm
> > 'maven.ext'
> > >>> [INFO] Using the MavenPluginManager 'MyPluginManager' from realm '
> > >>> coreExtension>org.example:double-core-bindings-override:2.0'
> > >>>
> > >>> The extension from maven.ext (extension version 1.0) is found and
> > >>> injected
> > >>> The extension from extensions.xml (extension version 2.0) is found
> and
> > >>> injected
> > >>> The #init for the 2.0 extension is called
> > >>> The #init for the 1.0 extension is called (maven.ext)
> > >>> Only the MyPluginManager instance from extension 2.0 is present, even
> > >>> when
> > >>> called from the extension 1.0.
> > >>>
> > >>> I understand why this happens but this is potentially dangerous.
> > >>> I tried various ways to avoid that from happening but failed.
> > >>> Hence my question, is there a better way to declare core overrides
> than
> > >>> in
> > >>> components.xml ?
> > >>>
> > >>>
> > >>> Also, side question, when I'm changing the
> META-INF/maven/extension.xml
> > >>> to
> > >>> contain
> > >>>
> > >>> <exportedPackages>
> > >>>     <exportedPackage>org.example</exportedPackage>
> > >>> </exportedPackages>
> > >>>
> > >>> Then, the problem 'goes away':
> > >>> [INFO] Found MyExtension in realm
> > >>> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Found MyExtension in realm
> > >>> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Inside MyExtension#init for extension loaded in realm
> > >>> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Instantiating MyPluginManager for extension loaded in realm
> > >>> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Using the MavenPluginManager 'MyPluginManager' from realm '
> > >>> coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Inside MyExtension#init for extension loaded in realm
> > >>> 'coreExtension>org.example:double-core-bindings-override:2.0'
> > >>> [INFO] Using the MavenPluginManager 'MyPluginManager' from realm '
> > >>> coreExtension>org.example:double-core-bindings-override:2.0'
> > >>>
> > >>> Can you explain what exactly happens in this case ?
> > >>> Maybe I could leverage that to solve my double application problem ?
> > >>>
> > >>> many thanks,
> > >>> François
> > >>>
> > >>>
> > >>> Le mar. 28 juin 2022 à 13:26, Tamás Cservenák <ta...@cservenak.net>
> a
> > >>> écrit :
> > >>>
> > >>> > In other words, why do you need to override MavenPluginManager in
> > >>> several
> > >>> > different ways?
> > >>> > (or we just theoretize, about some possible future binary
> breakage?)
> > >>> >
> > >>> > T
> > >>> >
> > >>> > On Tue, Jun 28, 2022 at 1:12 PM Tamás Cservenák <
> ta...@cservenak.net
> > >
> > >>> > wrote:
> > >>> >
> > >>> > > Ok,
> > >>> > >
> > >>> > > best would be to create then a reproducer, but have to note:
> > >>> > > while Maven can "protect" (warn) about duplicate/wrong plugin
> > >>> > > declarations, as "lower" we go (and extensions, especially when
> you
> > >>> throw
> > >>> > > things into lib/ext) are earlier and earlier on the bootstrap of
> > >>> Maven,
> > >>> > and
> > >>> > > it cannot do much there...
> > >>> > > Hence, while Maven tries its best to protect you (users) from
> > >>> mistakes,
> > >>> > it
> > >>> > > cannot always do it, especially when things are just added to
> > >>> > classpath....
> > >>> > >
> > >>> > > Also, non-backward compatible with your implementation of the
> Maven
> > >>> > > component (interface) of MavenPluginManager?
> > >>> > > Again, I'd really like to see what happens here, what the
> extension
> > >>> > intent
> > >>> > > is, not only "reproducer" for "multiple extensions override the
> > same
> > >>> > > component".
> > >>> > >
> > >>> > > Tamas
> > >>> > >
> > >>> > > On Tue, Jun 28, 2022 at 12:32 PM François Guillot <
> > >>> > > francoisguillo...@gmail.com> wrote:
> > >>> > >
> > >>> > >> Hi Tamás,
> > >>> > >>
> > >>> > >> I have one extension (say 'MyExtension'), that declares a
> binding
> > >>> > override
> > >>> > >> for MavenPluginManager.
> > >>> > >> MyExtension is not supposed to be applied several times per
> build,
> > >>> and
> > >>> > I'm
> > >>> > >> trying my best to keep only one of them 'active' if that
> happens.
> > >>> > >> Given there are various ways to declare extensions
> > >>> > ('.mvn/extensions.xml',
> > >>> > >> 'lib/ext' in Maven installation, '-Dmaven.ext.class.path'), the
> > >>> order of
> > >>> > >> applications of extensions, the fact they are not loaded in the
> > same
> > >>> > >> classloader makes it a bit hard to do.
> > >>> > >> But I'm managing that.
> > >>> > >> The only thing I'm not managing 'in code' is controlling which
> > >>> extension
> > >>> > >> wins and overrides the Maven core bindings.
> > >>> > >>
> > >>> > >> I'm thinking ahead if at some point I'm making a non backward
> > >>> compatible
> > >>> > >> change (wrt to my extension code) in my implementation of
> > >>> > >> MavenPluginManager, than I can be in trouble, where the 'chosen'
> > >>> > >> MavenPluginManager implementation will not be compatible with
> the
> > >>> > 'chosen'
> > >>> > >> MyExtension.
> > >>> > >>
> > >>> > >> I can't share the code of my extension, but I could produce a
> > little
> > >>> > >> reproducer with a noop extension to show you what I mean.
> > >>> > >>
> > >>> > >> Le mar. 28 juin 2022 à 11:45, Tamás Cservenák <
> > ta...@cservenak.net>
> > >>> a
> > >>> > >> écrit :
> > >>> > >>
> > >>> > >> > Howdy,
> > >>> > >> >
> > >>> > >> > I am a bit uncertain if I correctly understand your problem:
> so
> > >>> you
> > >>> > have
> > >>> > >> > several MavenPluginManager implementations in several
> > extensions,
> > >>> and
> > >>> > >> those
> > >>> > >> > extensions are not compatible with each other?
> > >>> > >> >
> > >>> > >> > Could we step back a little and could you explain what your
> > >>> extension
> > >>> > is
> > >>> > >> > doing? Best if you could show us some sources?
> > >>> > >> >
> > >>> > >> > HTH
> > >>> > >> > Tamas
> > >>> > >> >
> > >>> > >> >
> > >>> > >> >
> > >>> > >> > On Tue, Jun 28, 2022 at 10:18 AM François Guillot <
> > >>> > >> > francoisguillo...@gmail.com> wrote:
> > >>> > >> >
> > >>> > >> > > Hi,
> > >>> > >> > >
> > >>> > >> > > I need to override some default Maven bindings in my custom
> > >>> > extension,
> > >>> > >> > for
> > >>> > >> > > instance "org.apache.maven.plugin.MavenPluginManager"
> > >>> > >> > >
> > >>> > >> > > I'm doing this by providing a
> "META-INF/plexus/components.xml"
> > >>> in my
> > >>> > >> > > extension's jar with
> > >>> > >> > > <<
> > >>> > >> > >
> > >>> > >> > > <?xml version="1.0" encoding="UTF-8"?>
> > >>> > >> > > <component-set>
> > >>> > >> > >   <components>
> > >>> > >> > >     <component>
> > >>> > >> > >
>  <role>org.apache.maven.plugin.MavenPluginManager</role>
> > >>> > >> > >
> > >>>  <implementation>com.acme.MyMavenPluginManager</implementation>
> > >>> > >> > >
> > >>> > >> > >     </component>
> > >>> > >> > >   </components>
> > >>> > >> > > </component-set>
> > >>> > >> > >
> > >>> > >> > > >>
> > >>> > >> > >
> > >>> > >> > > This works fine, but this has limitations.
> > >>> > >> > > If for some reasons, my extension is applied twice or more
> to
> > >>> the
> > >>> > >> build,
> > >>> > >> > > then all of these applications will override the Maven core
> > >>> binding.
> > >>> > >> My
> > >>> > >> > > finding is that the last application wins.
> > >>> > >> > > This can be problematic if the user is applying several
> > >>> _versions_
> > >>> > of
> > >>> > >> my
> > >>> > >> > > extension (probably unknowingly), because the overridden
> > >>> > >> > MavenPluginManager
> > >>> > >> > > might be coming from a version of my extension that is not
> > >>> > compatible
> > >>> > >> > with
> > >>> > >> > > the code in the other one.
> > >>> > >> > >
> > >>> > >> > > Is there a more programmatic way to override Maven core
> > >>> bindings,
> > >>> > that
> > >>> > >> > > would allow me to decide whether a given extension should
> > >>> perform
> > >>> > the
> > >>> > >> > > override or not ?
> > >>> > >> > >
> > >>> > >> >
> > >>> > >>
> > >>> > >
> > >>> >
> > >>>
> > >>
> >
>

Reply via email to