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

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

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

Romain Manni-Bucau
Hi Lewis

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.


Le mer. 14 nov. 2018 22:24, J. Lewis Muir <[hidden email]> a écrit :

> Hello, all!
>
> I have an extension
>
>   https://github.com/imca-cat/profile-activation-advanced
>
> that allows property-based profile activation based on an MVEL
> expression.
>
> My problem is that it works
>
> ===
> $ mvn help:active-profiles validate
> ...
> The following profiles are active:
>
>  - foo_env-development (source: org.example.foo:foo:1.0.0)
> ...
> ===
>
> when loaded via Maven's lib/ext directory or when specified on the
> command line with "-Dmaven.ext.class.path=<path-to-extension-jars>", but
> does *not* work
>
> ===
> $ mvn help:active-profiles validate
> ...
> The following profiles are active:
>
> ...
> ===
>
> when loaded via a project's .mvn/extensions.xml file.
>
> The extension hijacks the normal property activator like this
>
>   @Component(role = ProfileActivator.class, hint = "property")
>   public class AdvancedProfileActivator implements ProfileActivator {
>     ...
>   }
>
> and evaluates the property value as an MVEL expression if the property
> name equals "mvel" or "mvel(" <properties-map-identifier> ")".
>
> Does anyone know why it would work from Maven's lib/ext directory, but
> not from a project's .mvn/extensions.xml file?  Or does anyone know how
> to debug this?
>
> Is it possible that the hijack doesn't work when loaded from a
> project's .mvn/extensions.xml because the original profile activator is
> found on the class path *before* the AdvancedProfileActivator of the
> extension, but when the extension JAR is placed in Maven's lib/ext,
> the AdvancedProfileActivator is found on the class path *before* the
> original profile activator?  (Just a wild guess.)
>
> The full source code of the extension's profile activator is at
>
>
> https://github.com/imca-cat/profile-activation-advanced/blob/master/src/main/java/org/imca_cat/maven/profile_activation_advanced/AdvancedProfileActivator.java
>
> To reproduce the problem, simply create a new Maven project directory
> containing the following pom.xml file:
>
> ===
> <?xml version="1.0" encoding="UTF-8"?>
> <project xmlns="http://maven.apache.org/POM/4.0.0"
>     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
>         http://maven.apache.org/xsd/maven-4.0.0.xsd">
>   <modelVersion>4.0.0</modelVersion>
>   <groupId>org.example.foo</groupId>
>   <artifactId>foo</artifactId>
>   <version>1.0.0</version>
>   <packaging>pom</packaging>
>   <profiles>
>     <profile>
>       <id>foo_env-development</id>
>       <activation>
>         <property>
>           <name>mvel</name>
>           <value>(!isdef foo_env) || foo_env == "development"</value>
>         </property>
>       </activation>
>     </profile>
>   </profiles>
> </project>
> ===
>
> (The foo_env-development profile should activate if the foo_env property
> (or system property) is not set or is set to the string "development".)
>
> Create .mvn/extensions.xml:
>
> ===
> <?xml version="1.0" encoding="UTF-8"?>
> <extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0"
>     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0
>         http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
>   <extension>
>     <groupId>org.imca-cat.maven</groupId>
>     <artifactId>profile-activation-advanced</artifactId>
>     <version>0.1.0</version>
>   </extension>
> </extensions>
> ===
>
> Run the following command:
>
> ===
> $ mvn help:active-profiles validate
> ===
>
> It should report that the foo_env-development profile is active (because
> the foo_env property is not set), but it does not. :-(
>
> I previously asked on the Maven User list
>
>
> https://lists.apache.org/thread.html/99ee87ba1bc86d98652173482b3a5882a52e344fad18df2cd50e8750@%3Cusers.maven.apache.org%3E
>
> but did not receive any replies.
>
> Thank you for your help!
>
> 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 sam. 17 nov. 2018 17:06, J. Lewis Muir <[hidden email]> a écrit :

> On Sat, Nov 17, 2018 at 1:53 AM Romain Manni-Bucau
> <[hidden email]> wrote:
> > > > Not instead but also. Instead of 3 impl you will get 4.
> > >
> > > I see.  I guess I don't know where to hook into the model, then.  I
> > > can't find anything in the model that implements the is-active
> > > computation for a Profile or Activation, so I don't see how to hook
> > > into it other than mutating the model with the hack I previously
> > > proposed which was to evaluate the MVEL expression and replace the
> > > ActivationProperty with one with a specially constructed name and
> > > value that would always evaluate to the just computed result of the
> > > MVEL expression.
> > >
> >
> > 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.


> > > So, in the approach where I have 4 implementations, how do I get Maven
> > > to use my AdvancedProfileActivator?  I assumed this was done based on
> > > the Component annotation hint element, and I thought the hint had to
> > > match the element under the activation element in the POM (e.g.,
> > > <activation><property>...</property></activation> means the hint for
> > > Maven's PropertyProfileActivator must be "property", which it is).
> > > So, for
> <activation><advancedProperty>...</advancedProperty></activation>,
> > > the hint for my AdvancedProfileActivator must be "advancedProperty".
> > > If that's right, then that makes sense to me.  But I still don't know
> > > how to get Maven to create an instance of AdvancedActivationProperty
> > > in the model when it reads the POM.
> >
> > If you have plexus plugin it will do
>
> Hmm, so to date I've been implementing this as a core extension, not
> as a Plexus plugin (if I'm understanding terminology correctly).  Are
> you suggesting it would be better to implement this as a Plexus
> plugin?
>

This is not two things incompatible actually but yes. In short an extension
integrates with maven lifecycle and plexus with maven ioc (lower level).


> Also, based on your previous comments, I don't think you're suggesting
> at all doing this thing of adding a new tag (e.g.,
> <activation><advancedProperty>...</advancedProperty></activation>),
> since you said you were thinking of the separation logically, not
> physically in the XML.
>

Would break several tooling to do that so likely not a good bet.


> 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 Mon, Nov 19, 2018 at 4:16 PM Romain Manni-Bucau
<[hidden email]> wrote:
> Time to push your code and an example on github to encourage help/people to
> run it ;)

OK, here's how to get the extension with the proof of concept code and
install it locally:

===
$ git clone https://github.com/imca-cat/profile-activation-advanced.git
$ cd profile-activation-advanced
$ git checkout lifecycle-participant-poc
$ mvn clean install
===

The proof of concept extension just changes the value of any profile
property activation with a name of "paa:mvel" to the string "!false".
It does not evaluate any MVEL expression at the moment; it's just a
proof of concept for changing the model.  Since the system property
"paa:mvel" is not defined, the altered property activation should
evaluate to true, but I don't know how to get Maven to re-evaluate the
property activations after I've changed them.

And here's how to get and run a small test that uses the locally
installed extension:

===
$ git clone https://github.com/jlmuir/profile-activation-advanced-test.git
$ cd profile-activation-advanced-test
$ mvn help:active-profiles validate
===

I'm expecting the "mvn help:active-profiles validate" command to show
that the foo_env-development profile is active with output like

===
The following profiles are active:

 - foo_env-development (source: org.example.foo:foo:1.0.0)
===

but it does not.  So, it seems the extension is not successfully
changing the model (i.e., not successfully activating the
foo_env-development profile).

Thank you!

Lewis

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