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 ? > > >>> > >> > > > > >>> > >> > > > >>> > >> > > >>> > > > > >>> > > > >>> > > >> > > >