Re: Extension does not work from .mvn/extensions.xml

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: Extension does not work from .mvn/extensions.xml

Romain Manni-Bucau
For the marker i was thinking about "property" so your activation would be
"el:name" or anything else - idea just being not intrusive and impacting
for actual property activation.

Did you try to use an extension rewritting the model after it is read and
before it is executed with a lifecycle participant? Sounds easier to
implement since you just convert it to an active or not activation of a
built in type.
The IoC uses guice so it is notr trivial to use @priority but there are
ways to do so, that said i dont think you need checking the profile logic.

The default model builder is used when there is no IoC so shouldn't be used
here. If your activator is registered it is injected and then used in the
isActive loop if it returns true for presentInConfig call (check
DefaultProfileSelector).
This is likely where you will have to debug.

Le ven. 16 nov. 2018 00:06, J. Lewis Muir <[hidden email]> a écrit :

> On Wed, Nov 14, 2018 at 3:31 PM Romain Manni-Bucau
> <[hidden email]> wrote:
> > You can debug using mvnDebug but i think it is cause there is already a
> > property handler -
> >
> https://github.com/apache/maven/blob/master/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java
> > - so depending the scanning order you take one or the other. Try using
> > another marker maybe or making yours higher priority probably.
>
> Hi, Romain!
>
> Thank you for your reply!
>
> What do you mean by "using another marker"?
>
> How can I make mine have higher priority?
>
> I looked at
>
>
> http://codehaus-plexus.github.io/plexus-containers/plexus-component-annotations/apidocs/
>
> and the Component annotation has a number of elements, but none of
> them look like they would let me assign a priority (e.g., an element
> named "priority").  I also don't see an annotation that looks like it
> would let me assign a priority (e.g., an annotation named "Priority").
>
> The closest I could find to the concept of a priority was a Stack
> Overflow answer
>
>   https://stackoverflow.com/a/41970497
>
> where the author talks about a solution which I think refers to this commit
>
>
> https://github.com/Code-House/maven-osgi-resolver/commit/e0b9797657d90eb35a8a166efbf3e01c09fd4189
>
> where he adds a dependency on org.eclipse.sisu:org.eclipse.sisu.inject
> and adds a Priority annotation
>
>
> http://www.eclipse.org/sisu/docs/api/org.eclipse.sisu.inject/reference/org/eclipse/sisu/Priority.html
>
> However, in the very next commit, the author removes the Priority
> annotation believing it to be unnecessary
>
>
> https://github.com/Code-House/maven-osgi-resolver/commit/67e3b31d18d1efb0b8f279a1bbacfa39b88d3236
>
> I understand Sisu to be this project
>
>   http://www.eclipse.org/sisu/
>
> but I don't know much else about it.
>
> I'm also a little concerned with what I see in DefaultModelBuilderFactory
>
>
> https://github.com/apache/maven/blob/master/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
>
> in its newProfileActivators method: it creates an instance of
> PropertyProfileActivator which would seem to bypass any injection
> (including that of my AdvancedProfileActivator).  The class comment
> says, though,
>
>   This class is only meant as a utility for developers that want to
>   employ the model builder outside of the Maven build system, Maven
>   plugins should always acquire model builder instances via dependency
>   injection.
>
> So maybe I don't have to worry about it?
>
> Thanks!
>
> Lewis
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Extension does not work from .mvn/extensions.xml

Romain Manni-Bucau
Le ven. 16 nov. 2018 20:36, J. Lewis Muir <[hidden email]> a écrit :

> On Fri, Nov 16, 2018 at 12:02 AM Romain Manni-Bucau
> <[hidden email]> wrote:
> > For the marker i was thinking about "property" so your activation would
> be
> > "el:name" or anything else - idea just being not intrusive and impacting
> > for actual property activation.
>
> I see.  I thought that, in order for the hijack to work, it needed to
> use the same role hint; no?  I'll change the hint element to
> "paa:property" (for Profile Activation Advanced property) or something
> similar.
>

I didnt find in the code where the hint matches, just saw a chain so should
work if i didnt miss a later filtering. That said my naming advise was for
the pom content more than the code (to not interpret default property tag).



> > Did you try to use an extension rewritting the model after it is read and
> > before it is executed with a lifecycle participant? Sounds easier to
> > implement since you just convert it to an active or not activation of a
> > built in type.
>
> No, I didn't try that.  That's an interesting idea!  The lifecycle
> participant would give me a MavenSession object.  I can get to
> ActivationProperty objects via
>
>   MavenSession.getProjects()
>     MavenProject.getModel()
>       Model.getProfiles()
>         Profile.getActivation()
>           Activation.getProperty()
>
> but this is just the model, not how the model is interpreted (i.e.,
> how the profile is determined to be active or not).  I could examine
> the ActivationProperty objects, and if they are the special ones I
> want to handle (i.e., name is "mvel" or "mvel("
> <properties-map-identifier> ")"), then I could evaluate the MVEL
> expression and replace the ActivationProperty objects with ones that
> would evaluate to true or false always (e.g., a property name I know
> does not exist and using the negation operator or not to artificially
> cause it to always evaluate to true or false).  That seems like a
> hack, but maybe it's OK. (?)
>
> And I wouldn't have the ProfileActivationContext object that I would
> have in the ProfileActivator.isActive method.  But I guess I could
> work around that by getting the things I need directly from the
> MavenSession object (i.e., MavenSession.getSystemProperties() and
> MavenSession.getUserProperties()), but would that be considered
> correct, or would that likely break stuff?
>
> Am I anywhere near understanding what you're suggesting?
>

You can mutate this model, this is all the trick ;)



> > The IoC uses guice so it is notr trivial to use @priority but there are
> > ways to do so, that said i dont think you need checking the profile
> logic.
>
> OK, I'll put this approach on the back burner and only come back to it
> if I can't get the lifecycle participant approach to work.
>
> > The default model builder is used when there is no IoC so shouldn't be
> used
> > here.
>
> OK, great.
>
> > If your activator is registered it is injected and then used in the
> > isActive loop if it returns true for presentInConfig call (check
> > DefaultProfileSelector).
> > This is likely where you will have to debug.
>
> But my problem is getting my activator to be injected instead of the
> regular one.  I think that's where the @Priority annotation comes in.
> But I think you're suggesting the lifecycle participant approach would
> be easier, so I'm trying that now.
>

Not instead but also. Instead of 3 impl you will get 4.



> Thank you!
>
> Lewis
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Extension does not work from .mvn/extensions.xml

J. Lewis Muir
On Sat, Nov 17, 2018 at 11:32 AM Romain Manni-Bucau
<[hidden email]> wrote:

> Le sam. 17 nov. 2018 17:06, J. Lewis Muir <[hidden email]> a écrit :
> > > Idea was to set an activation which will match true with default impls
> >
> > OK, I'm just trying to make sure I understanding that.  The default
> > activation impls are ActivationFile (file), ActivationOS (os),
> > ActivationProperty (property), and String (jdk).  The default
> > activator impls are FileProfileActivator,
> > OperatingSystemProfileActivator, PropertyProfileActivator, and
> > JdkVersionProfileActivator.  The idea would match true with these
> > default impls, right?  And the only way to make it match true with
> > these default impls would be to replace the ActivationProperty
> > instances in the model that need the special MVEL evaluation with new
> > ActivationProperty instances that will always evaluate to true or
> > false according to the pre-computed MVEL evaluation results, right?
> > In this approach, there would be no new impls (i.e., no
> > AdvancedActivationProperty and no AdvancedProfileActivator).
> >
> > Another thought I had is that I could modify the active-profiles list
> > of the MavenProject instances (i.e., MavenProject.setActiveProfiles)
> > of the model to include or exclude the profiles with the special MVEL
> > activation based on the result of evaluating those MVEL expressions.
> > Then I wouldn't need to do the hack of changing the ActivationProperty
> > instances to always evaluate to true or false according to the
> > pre-computed result of the MVEL evaluation.  Wouldn't that work?
> > This, however, does not seem the same as your description of the idea
> > of setting an activation that would "match true with default impls."
>
> Here you change the activation to match a default logic evaluation or you
> change profiles and model to be pre activated. Personally i prefer to keep
> profile cause it eases debugging but both work.

Hmm, I can't get it to work. :-(  I created my own lifecycle
participant by extending AbstractMavenLifecycleParticipant and
overrode afterProjectsRead, but the profile activation has already
been evaluated by the time this method is called.  That means I would
have to trigger evaluation again after I changed the
ActivationProperty to always evaluate to true or false to match the
result of the MVEL expression evaluation.

I could re-evaluate the profile activation with
DefaultProfileSelector, but if something else is injecting a different
ProfileSelector, then hard-coding DefaultProfileSelector would mess
that up.  Is there a way to instantiate the ProfileSelector that Maven
would normally instantiate?

And on top of that, I just tried a hack of manually adding the profile
to the MavenProject's active-profiles list

  List<Profile> activeProfiles = project.getActiveProfiles();
  activeProfiles.add(profileActivatedByMvel);
  project.setActiveProfiles(activeProfiles);

and it seems to have no effect: running "mvn help:active-profiles
validate" in a test project that uses the extension shows no active
profiles.

I also tried overriding
AbstractMavenLifecycleParticipant.afterSessionStart, but this seems to
be too early: the MavenSession doesn't have any projects.

Thank you!

Lewis

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Extension does not work from .mvn/extensions.xml

J. Lewis Muir
On Tue, Nov 20, 2018 at 2:30 AM Romain Manni-Bucau
<[hidden email]> wrote:
> 1. you have to use lib/ext folder and not extensions.xml cause it is loaded
> too late

Unfortunately, that's a deal breaker.  Using Maven's lib/ext is the
original situation I reported when I started this thread (i.e., it
worked from Maven's lib/ext, but not from the project's
.mvn/extensions.xml.)  There's no way I can get the developers of the
software I'm planning to use this in to install the extension in
Maven's lib/ext; it has to be able to work from the project's
.mvn/extensions.xml.  I guess this is the end of the road, then.
Bummer.

> 2. you have to override the property activator as you mentionned cause
> otherwise your profile is added (through plexus) in the list of activator,
> set the activation to true and then property one sets it to false
>
> To do 2 you just have to use sisu @Priority and ensure the hint is property:

I tried adding the Priority annotation, and it works from Maven's
lib/ext, but it also works *without* it, so I'm hesitant to add it
unless I know it's really necessary.  The readme file in Maven's
lib/ext says

  Use this directory to contribute 3rd-party extensions to the Maven
  core. These extensions can either extend or override Maven's default
  implementation.

Do I really need the Priority annotation, or will my extension's
AdvancedProfileActivator (annotated with '@Component(role =
ProfileActivator.class, hint = "property")') always take precedence
over the default by virtue of being in Maven's lib/ext?

Thank you!

Lewis

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Extension does not work from .mvn/extensions.xml

Romain Manni-Bucau
Le mar. 20 nov. 2018 19:23, J. Lewis Muir <[hidden email]> a écrit :

> On Tue, Nov 20, 2018 at 2:30 AM Romain Manni-Bucau
> <[hidden email]> wrote:
> > 1. you have to use lib/ext folder and not extensions.xml cause it is
> loaded
> > too late
>
> Unfortunately, that's a deal breaker.  Using Maven's lib/ext is the
> original situation I reported when I started this thread (i.e., it
> worked from Maven's lib/ext, but not from the project's
> .mvn/extensions.xml.)  There's no way I can get the developers of the
> software I'm planning to use this in to install the extension in
> Maven's lib/ext; it has to be able to work from the project's
> .mvn/extensions.xml.  I guess this is the end of the road, then.
> Bummer.
>

Even with mvnsh, maven opts or the -D?


> > 2. you have to override the property activator as you mentionned cause
> > otherwise your profile is added (through plexus) in the list of
> activator,
> > set the activation to true and then property one sets it to false
> >
> > To do 2 you just have to use sisu @Priority and ensure the hint is
> property:
>
> I tried adding the Priority annotation, and it works from Maven's
> lib/ext, but it also works *without* it, so I'm hesitant to add it
> unless I know it's really necessary.  The readme file in Maven's
> lib/ext says
>

Without it you dont deactivate default one - you can check it debugging it.


>   Use this directory to contribute 3rd-party extensions to the Maven
>   core. These extensions can either extend or override Maven's default
>   implementation.
>
> Do I really need the Priority annotation, or will my extension's
> AdvancedProfileActivator (annotated with '@Component(role =
> ProfileActivator.class, hint = "property")') always take precedence
> over the default by virtue of being in Maven's lib/ext?
>

This kind of order is fragile so better to be deterministic ans more robust
imho


> Thank you!
>
> Lewis
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Extension does not work from .mvn/extensions.xml

J. Lewis Muir
On Tue, Nov 20, 2018 at 1:01 PM Romain Manni-Bucau
<[hidden email]> wrote:
> Le mar. 20 nov. 2018 19:23, J. Lewis Muir <[hidden email]> a écrit :
> > There's no way I can get the developers of the
> > software I'm planning to use this in to install the extension in
> > Maven's lib/ext; it has to be able to work from the project's
> > .mvn/extensions.xml.
>
> Even with mvnsh, maven opts or the -D?

Well, it's for a project where I'm not a core developer, so I don't
think there will be much support for anything that requires doing
something extra.

I doubt mvnsh would fly.

MAVEN_OPTS would work, but it's external and not with the project
source code, so it requires each developer to do some special setting
up.  I doubt it would fly.

The closest I can get would be -D in the project's .mvn/maven.config.
This would require adding the two JARs
(profile-activation-advanced-0.2.0.jar and mvel2-2.4.2.Final.jar) to
the project's source code repo, though.  That right there is already
undesirable.  And then, say the JARs were added under the project's
root at lib-ext, the following would need to be added to the project's
.mvn/maven.config:

  -Dmaven.ext.class.path=lib-ext/profile-activation-advanced-0.2.0.jar:lib-ext/mvel2-2.4.2.Final.jar

That's the closest I could get, and it requires the paths in the
maven.ext.class.path system property to be resolved relative to the
project root (so that the relative paths to the JAR files will be
correct), and I don't even know if that's guaranteed.

So, it's a pretty tough sell at this point.

> > I tried adding the Priority annotation, and it works from Maven's
> > lib/ext, but it also works *without* it, so I'm hesitant to add it
> > unless I know it's really necessary.  The readme file in Maven's
> > lib/ext says
>
> Without it you dont deactivate default one - you can check it debugging it.

Hmm, how can I check it by debugging?  I tried without the Priority
annotation with a breakpoint in AdvancedProfileActivator.isActive, and
I looked at the caller DefaultProfileSelector.isActive frame, which is
one frame down in the stack, and I see the AdvancedProfileActivator in
the DefaultProfileSelector's activators list, and I don't see the
default PropertyProfileActivator.  Attached is a screenshot.  Maybe
I'm looking in the wrong place?

Thanks!

Lewis



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]