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