I think this is still waiting for feedback from me. There are parts that I still don't like. Now that maven-wrapper is mostly done, I will put effort on build-consumer first, because even once implemented, there will be several other tasks that needs to be done. After that I might have time to evaluate this topic.
Robert On 25-5-2020 17:43:13, Enrico Olivelli <eolive...@gmail.com> wrote: Stephen, do we have news about this great feature ? Enrico Il giorno sab 23 nov 2019 alle ore 11:51 Stephen Connolly stephen.alan.conno...@gmail.com> ha scritto: > Ok I figured out dynamic lookup from plexus: > > $ mvn -version > Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; > 2018-06-17T19:33:14+01:00) > Maven home: /usr/local/Cellar/maven/3.5.4/libexec > Java version: 1.8.0_152, vendor: Oracle Corporation, runtime: > /Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre > Default locale: en_IE, platform encoding: UTF-8 > OS name: "mac os x", version: "10.14.6", arch: "x86_64", family: "mac" > $ mvn validate > [ERROR] The project uses experimental features that require exactly Maven > 3.7.0-SNAPSHOT -> [Help 1] > [ERROR] > [ERROR] To see the full stack trace of the errors, re-run Maven with the -e > switch. > [ERROR] Re-run Maven using the -X switch to enable full debug logging. > [ERROR] > [ERROR] For more information about the errors and possible solutions, > please read the following articles: > [ERROR] [Help 1] > http://cwiki.apache.org/confluence/display/MAVEN/MavenExecutionException > > Much nicer! > > > > On Fri, 22 Nov 2019 at 16:12, Stephen Connolly > stephen.alan.conno...@gmail.com> wrote: > > > I have advanced the PoC a bit more by adding an experiments mechanism. > > > > To use the dynamic phases PoC you now need to: > > > > 1. Build and install Maven on the branch > > 2. Add the experiments extension in .mvn/extensions.xml, e.g. > > > > > > > > xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 > > http://maven.apache.org/xsd/core-extensions-1.0.0.xsd"> > > > > > > org.apache.maven > > maven-experiments > > 3.7.0-SNAPSHOT > > > > > > > > > > 3. Update your pom to use the new dynamic phases. > > > > The reason for the experiments extension is to guard against assuming the > > phases will work and prevent "normal" versions of Maven from producing a > > bad build. > > > > Here's a build with the extension enabled: > > > > [INFO] Enabling experimental features of Maven 3.7.0-SNAPSHOT > > [INFO] Experimental features enabled: > > [INFO] * dynamic-phases > > [INFO] Scanning for projects... > > [INFO] > > ------------------------------------------------------------------------ > > [INFO] Reactor Build Order: > > [INFO] > > [INFO] foo > > [jar] > > [INFO] bar > > [jar] > > [INFO] test > > [pom] > > [INFO] > > [INFO] -------------------------- > > >--------------------------- > > [INFO] Building foo 1.0-SNAPSHOT > > [1/3] > > [INFO] --------------------------------[ jar > > ]--------------------------------- > > [INFO] > > [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ foo > > --- > > [WARNING] Using platform encoding (UTF-8 actually) to copy filtered > > resources, i.e. build is platform dependent! > > [INFO] skip non existing resourceDirectory > > /Users/stephenc/tmp/test/foo/src/main/resources > > [INFO] > > [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ foo --- > > [INFO] No sources to compile > > [INFO] > > [INFO] --- maven-resources-plugin:2.6:testResources > > (default-testResources) @ foo --- > > [WARNING] Using platform encoding (UTF-8 actually) to copy filtered > > resources, i.e. build is platform dependent! > > [INFO] skip non existing resourceDirectory > > /Users/stephenc/tmp/test/foo/src/test/resources > > [INFO] > > [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ > > foo --- > > [INFO] No sources to compile > > [INFO] > > [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ foo --- > > [INFO] No tests to run. > > [INFO] > > [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ foo --- > > [WARNING] JAR will be empty - no content was marked for inclusion! > > [INFO] > > [INFO] --- maven-antrun-plugin:1.3:run (2) @ foo --- > > [INFO] Executing tasks > > [echo] beat you > > [INFO] Executed tasks > > [INFO] > > [INFO] --- maven-antrun-plugin:1.3:run (1) @ foo --- > > [INFO] Executing tasks > > [echo] hi > > [INFO] Executed tasks > > [INFO] > > [INFO] --- maven-antrun-plugin:1.3:run (4) @ foo --- > > [INFO] Executing tasks > > [INFO] > > [INFO] --- maven-antrun-plugin:1.3:run (3) @ foo --- > > [INFO] Executing tasks > > [echo] bye > > [INFO] Executed tasks > > [INFO] > > ------------------------------------------------------------------------ > > [INFO] Reactor Summary for test 1.0-SNAPSHOT: > > [INFO] > > [INFO] foo ................................................ FAILURE [ > > 2.745 s] > > [INFO] bar ................................................ SKIPPED > > [INFO] test ............................................... SKIPPED > > [INFO] > > ------------------------------------------------------------------------ > > [INFO] BUILD FAILURE > > [INFO] > > ------------------------------------------------------------------------ > > [INFO] Total time: 2.813 s > > [INFO] Finished at: 2019-11-22T15:43:59Z > > [INFO] > > ------------------------------------------------------------------------ > > > > Here's the same project with the extensions disabled > > > > [INFO] Scanning for projects... > > [INFO] > > ------------------------------------------------------------------------ > > [INFO] Reactor Build Order: > > [INFO] > > [INFO] foo > > [jar] > > [INFO] bar > > [jar] > > [INFO] test > > [pom] > > [INFO] > > [INFO] -------------------------- > > >--------------------------- > > [INFO] Building foo 1.0-SNAPSHOT > > [1/3] > > [INFO] --------------------------------[ jar > > ]--------------------------------- > > [INFO] > > [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ foo > > --- > > [WARNING] Using platform encoding (UTF-8 actually) to copy filtered > > resources, i.e. build is platform dependent! > > [INFO] skip non existing resourceDirectory > > /Users/stephenc/tmp/test/foo/src/main/resources > > [INFO] > > [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ foo --- > > [INFO] No sources to compile > > [INFO] > > [INFO] --- maven-resources-plugin:2.6:testResources > > (default-testResources) @ foo --- > > [WARNING] Using platform encoding (UTF-8 actually) to copy filtered > > resources, i.e. build is platform dependent! > > [INFO] skip non existing resourceDirectory > > /Users/stephenc/tmp/test/foo/src/test/resources > > [INFO] > > [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ > > foo --- > > [INFO] No sources to compile > > [INFO] > > [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ foo --- > > [INFO] No tests to run. > > [INFO] > > [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ foo --- > > [WARNING] JAR will be empty - no content was marked for inclusion! > > [INFO] > > [INFO] --- maven-antrun-plugin:1.3:run (4) @ foo --- > > [INFO] Executing tasks > > [INFO] > > ------------------------------------------------------------------------ > > [INFO] Reactor Summary for test 1.0-SNAPSHOT: > > [INFO] > > [INFO] foo ................................................ FAILURE [ > > 0.745 s] > > [INFO] bar ................................................ SKIPPED > > [INFO] test ............................................... SKIPPED > > [INFO] > > ------------------------------------------------------------------------ > > [INFO] BUILD FAILURE > > [INFO] > > ------------------------------------------------------------------------ > > [INFO] Total time: 1.054 s > > [INFO] Finished at: 2019-11-22T15:43:38Z > > [INFO] > > ------------------------------------------------------------------------ > > > > Notice how the dynamic phases are completely ignored if the experiment is > > not activated > > > > And here's the foo pom.xml to show what the executions are > > > > > > 4.0.0 > > localdomain > > foo > > 1.0-SNAPSHOT > > > > > > > > maven-antrun-plugin > > > > > > 1 > > before:integration-test > > > > run > > > > > > > > > > > > > > > > > > 2 > > before:integration-test[1000] > > > > run > > > > > > > > > > > > > > > > > > > > 3 > > after:integration-test > > > > run > > > > > > > > > > > > > > > > > > 4 > > integration-test > > > > run > > > > > > > > > > > > > > > > > > > > > > > > > > > > Finally this is what you get if you have the experiment extension added > > but try to build with an older version of Maven: > > > > [WARNING] Error injecting: > > org.apache.maven.feature.check.MavenExperimentEnabler > > java.lang.NoClassDefFoundError: > > org/apache/maven/feature/api/MavenFeatureContext > > at java.lang.Class.getDeclaredConstructors0 (Native Method) > > at java.lang.Class.privateGetDeclaredConstructors (Class.java:2671) > > at java.lang.Class.getDeclaredConstructors (Class.java:2020) > > at com.google.inject.spi.InjectionPoint.forConstructorOf > > (InjectionPoint.java:245) > > at com.google.inject.internal.ConstructorBindingImpl.create > > (ConstructorBindingImpl.java:115) > > at com.google.inject.internal.InjectorImpl.createUninitializedBinding > > (InjectorImpl.java:706) > > at com.google.inject.internal.InjectorImpl.createJustInTimeBinding > > (InjectorImpl.java:929) > > at > > com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive > > (InjectorImpl.java:852) > > at com.google.inject.internal.InjectorImpl.getJustInTimeBinding > > (InjectorImpl.java:291) > > at com.google.inject.internal.InjectorImpl.getBindingOrThrow > > (InjectorImpl.java:222) > > at com.google.inject.internal.InjectorImpl.getProviderOrThrow > > (InjectorImpl.java:1040) > > at com.google.inject.internal.InjectorImpl.getProvider > > (InjectorImpl.java:1071) > > at com.google.inject.internal.InjectorImpl.getProvider > > (InjectorImpl.java:1034) > > at com.google.inject.internal.InjectorImpl.getInstance > > (InjectorImpl.java:1086) > > at org.eclipse.sisu.space.AbstractDeferredClass.get > > (AbstractDeferredClass.java:48) > > at com.google.inject.internal.ProviderInternalFactory.provision > > (ProviderInternalFactory.java:85) > > at > > > com.google.inject.internal.InternalFactoryToInitializableAdapter.provision > > (InternalFactoryToInitializableAdapter.java:57) > > at com.google.inject.internal.ProviderInternalFactory$1.call > > (ProviderInternalFactory.java:66) > > at > > > com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision > > (ProvisionListenerStackCallback.java:112) > > at org.eclipse.sisu.bean.BeanScheduler$CycleActivator.onProvision > > (BeanScheduler.java:230) > > at > > > com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision > > (ProvisionListenerStackCallback.java:120) > > at > com.google.inject.internal.ProvisionListenerStackCallback.provision > > (ProvisionListenerStackCallback.java:66) > > at com.google.inject.internal.ProviderInternalFactory.circularGet > > (ProviderInternalFactory.java:61) > > at > > com.google.inject.internal.InternalFactoryToInitializableAdapter.get > > (InternalFactoryToInitializableAdapter.java:47) > > at com.google.inject.internal.ProviderToInternalFactoryAdapter.get > > (ProviderToInternalFactoryAdapter.java:40) > > at com.google.inject.internal.SingletonScope$1.get > > (SingletonScope.java:148) > > at com.google.inject.internal.InternalFactoryToProviderAdapter.get > > (InternalFactoryToProviderAdapter.java:39) > > at com.google.inject.internal.InjectorImpl$1.get > > (InjectorImpl.java:1050) > > at org.eclipse.sisu.inject.LazyBeanEntry.getValue > > (LazyBeanEntry.java:81) > > at org.eclipse.sisu.plexus.LazyPlexusBean.getValue > > (LazyPlexusBean.java:51) > > at org.eclipse.sisu.wire.EntryListAdapter$ValueIterator.next > > (EntryListAdapter.java:111) > > at java.util.AbstractCollection.addAll (AbstractCollection.java:343) > > at org.apache.maven.DefaultMaven.getLifecycleParticipants > > (DefaultMaven.java:377) > > at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:206) > > at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192) > > at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105) > > at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954) > > at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288) > > at org.apache.maven.cli.MavenCli.main (MavenCli.java:192) > > at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) > > at sun.reflect.NativeMethodAccessorImpl.invoke > > (NativeMethodAccessorImpl.java:62) > > at sun.reflect.DelegatingMethodAccessorImpl.invoke > > (DelegatingMethodAccessorImpl.java:43) > > at java.lang.reflect.Method.invoke (Method.java:498) > > at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced > > (Launcher.java:289) > > at org.codehaus.plexus.classworlds.launcher.Launcher.launch > > (Launcher.java:229) > > at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode > > (Launcher.java:415) > > at org.codehaus.plexus.classworlds.launcher.Launcher.main > > (Launcher.java:356) > > Caused by: java.lang.ClassNotFoundException: > > org.apache.maven.feature.api.MavenFeatureContext > > at > > org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass > > (SelfFirstStrategy.java:50) > > at > > org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass > > (ClassRealm.java:271) > > at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass > > (ClassRealm.java:247) > > at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass > > (ClassRealm.java:239) > > at java.lang.Class.getDeclaredConstructors0 (Native Method) > > at java.lang.Class.privateGetDeclaredConstructors (Class.java:2671) > > at java.lang.Class.getDeclaredConstructors (Class.java:2020) > > at com.google.inject.spi.InjectionPoint.forConstructorOf > > (InjectionPoint.java:245) > > at com.google.inject.internal.ConstructorBindingImpl.create > > (ConstructorBindingImpl.java:115) > > at com.google.inject.internal.InjectorImpl.createUninitializedBinding > > (InjectorImpl.java:706) > > at com.google.inject.internal.InjectorImpl.createJustInTimeBinding > > (InjectorImpl.java:929) > > at > > com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive > > (InjectorImpl.java:852) > > at com.google.inject.internal.InjectorImpl.getJustInTimeBinding > > (InjectorImpl.java:291) > > at com.google.inject.internal.InjectorImpl.getBindingOrThrow > > (InjectorImpl.java:222) > > at com.google.inject.internal.InjectorImpl.getProviderOrThrow > > (InjectorImpl.java:1040) > > at com.google.inject.internal.InjectorImpl.getProvider > > (InjectorImpl.java:1071) > > at com.google.inject.internal.InjectorImpl.getProvider > > (InjectorImpl.java:1034) > > at com.google.inject.internal.InjectorImpl.getInstance > > (InjectorImpl.java:1086) > > at org.eclipse.sisu.space.AbstractDeferredClass.get > > (AbstractDeferredClass.java:48) > > at com.google.inject.internal.ProviderInternalFactory.provision > > (ProviderInternalFactory.java:85) > > at > > > com.google.inject.internal.InternalFactoryToInitializableAdapter.provision > > (InternalFactoryToInitializableAdapter.java:57) > > at com.google.inject.internal.ProviderInternalFactory$1.call > > (ProviderInternalFactory.java:66) > > at > > > com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision > > (ProvisionListenerStackCallback.java:112) > > at org.eclipse.sisu.bean.BeanScheduler$CycleActivator.onProvision > > (BeanScheduler.java:230) > > at > > > com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision > > (ProvisionListenerStackCallback.java:120) > > at > com.google.inject.internal.ProvisionListenerStackCallback.provision > > (ProvisionListenerStackCallback.java:66) > > at com.google.inject.internal.ProviderInternalFactory.circularGet > > (ProviderInternalFactory.java:61) > > at > > com.google.inject.internal.InternalFactoryToInitializableAdapter.get > > (InternalFactoryToInitializableAdapter.java:47) > > at com.google.inject.internal.ProviderToInternalFactoryAdapter.get > > (ProviderToInternalFactoryAdapter.java:40) > > at com.google.inject.internal.SingletonScope$1.get > > (SingletonScope.java:148) > > at com.google.inject.internal.InternalFactoryToProviderAdapter.get > > (InternalFactoryToProviderAdapter.java:39) > > at com.google.inject.internal.InjectorImpl$1.get > > (InjectorImpl.java:1050) > > at org.eclipse.sisu.inject.LazyBeanEntry.getValue > > (LazyBeanEntry.java:81) > > at org.eclipse.sisu.plexus.LazyPlexusBean.getValue > > (LazyPlexusBean.java:51) > > at org.eclipse.sisu.wire.EntryListAdapter$ValueIterator.next > > (EntryListAdapter.java:111) > > at java.util.AbstractCollection.addAll (AbstractCollection.java:343) > > at org.apache.maven.DefaultMaven.getLifecycleParticipants > > (DefaultMaven.java:377) > > at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:206) > > at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192) > > at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105) > > at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954) > > at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288) > > at org.apache.maven.cli.MavenCli.main (MavenCli.java:192) > > at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) > > at sun.reflect.NativeMethodAccessorImpl.invoke > > (NativeMethodAccessorImpl.java:62) > > at sun.reflect.DelegatingMethodAccessorImpl.invoke > > (DelegatingMethodAccessorImpl.java:43) > > at java.lang.reflect.Method.invoke (Method.java:498) > > at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced > > (Launcher.java:289) > > at org.codehaus.plexus.classworlds.launcher.Launcher.launch > > (Launcher.java:229) > > at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode > > (Launcher.java:415) > > at org.codehaus.plexus.classworlds.launcher.Launcher.main > > (Launcher.java:356) > > --------------------------------------------------- > > constituent[0]: file:/usr/local/Cellar/maven/3.5.4/libexec/conf/logging/ > > constituent[1]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-repository-metadata-3.5.4.jar > > constituent[2]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-resolver-transport-wagon-1.1.1.jar > > constituent[3]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/aopalliance-1.0.jar > > constituent[4]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-resolver-provider-3.5.4.jar > > constituent[5]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/plexus-utils-3.1.0.jar > > constituent[6]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/plexus-interpolation-1.24.jar > > constituent[7]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-artifact-3.5.4.jar > > constituent[8]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/plexus-cipher-1.7.jar > > constituent[9]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/guava-20.0.jar > > constituent[10]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-slf4j-provider-3.5.4.jar > > constituent[11]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/slf4j-api-1.7.25.jar > > constituent[12]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/cdi-api-1.0.jar > > constituent[13]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/jcl-over-slf4j-1.7.25.jar > > constituent[14]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-resolver-spi-1.1.1.jar > > constituent[15]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-compat-3.5.4.jar > > constituent[16]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-plugin-api-3.5.4.jar > > constituent[17]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/plexus-sec-dispatcher-1.4.jar > > constituent[18]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-resolver-util-1.1.1.jar > > constituent[19]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/plexus-component-annotations-1.7.1.jar > > constituent[20]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-settings-builder-3.5.4.jar > > constituent[21]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/commons-cli-1.4.jar > > constituent[22]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/commons-io-2.5.jar > > constituent[23]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/jansi-1.17.1.jar > > constituent[24]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-core-3.5.4.jar > > constituent[25]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-resolver-impl-1.1.1.jar > > constituent[26]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/guice-4.2.0-no_aop.jar > > constituent[27]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/org.eclipse.sisu.inject-0.3.3.jar > > constituent[28]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/wagon-file-3.1.0.jar > > constituent[29]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-builder-support-3.5.4.jar > > constituent[30]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-model-3.5.4.jar > > constituent[31]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-settings-3.5.4.jar > > constituent[32]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/wagon-http-3.1.0-shaded.jar > > constituent[33]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-resolver-api-1.1.1.jar > > constituent[34]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-resolver-connector-basic-1.1.1.jar > > constituent[35]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-shared-utils-3.2.1.jar > > constituent[36]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/org.eclipse.sisu.plexus-0.3.3.jar > > constituent[37]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-model-builder-3.5.4.jar > > constituent[38]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/javax.inject-1.jar > > constituent[39]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/maven-embedder-3.5.4.jar > > constituent[40]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/jsr250-api-1.0.jar > > constituent[41]: > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/commons-lang3-3.5.jar > > constituent[42]: > > > file:/usr/local/Cellar/maven/3.5.4/libexec/lib/wagon-provider-api-3.1.0.jar > > --------------------------------------------------- > > Exception in thread "main" java.lang.NoClassDefFoundError: > > org/apache/maven/feature/api/MavenFeatureContext > > at java.lang.Class.getDeclaredConstructors0(Native Method) > > at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671) > > at java.lang.Class.getDeclaredConstructors(Class.java:2020) > > at > > > com.google.inject.spi.InjectionPoint.forConstructorOf(InjectionPoint.java:245) > > at > > > com.google.inject.internal.ConstructorBindingImpl.create(ConstructorBindingImpl.java:115) > > at > > > com.google.inject.internal.InjectorImpl.createUninitializedBinding(InjectorImpl.java:706) > > at > > > com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:929) > > at > > > com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:852) > > at > > > com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:291) > > at > > > com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:222) > > at > > > com.google.inject.internal.InjectorImpl.getProviderOrThrow(InjectorImpl.java:1040) > > at > > > com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1071) > > at > > > com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1034) > > at > > > com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1086) > > at > > org.eclipse.sisu.space > .AbstractDeferredClass.get(AbstractDeferredClass.java:48) > > at > > > com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:85) > > at > > > com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:57) > > at > > > com.google.inject.internal.ProviderInternalFactory$1.call(ProviderInternalFactory.java:66) > > at > > > com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112) > > at > > > org.eclipse.sisu.bean.BeanScheduler$CycleActivator.onProvision(BeanScheduler.java:230) > > at > > > com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:120) > > at > > > com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66) > > at > > > com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61) > > at > > > com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:47) > > at > > > com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) > > at > com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:148) > > at > > > com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39) > > at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050) > > at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81) > > at > org.eclipse.sisu.plexus.LazyPlexusBean.getValue(LazyPlexusBean.java:51) > > at > > > org.eclipse.sisu.wire.EntryListAdapter$ValueIterator.next(EntryListAdapter.java:111) > > at java.util.AbstractCollection.addAll(AbstractCollection.java:343) > > at > > > org.apache.maven.DefaultMaven.getLifecycleParticipants(DefaultMaven.java:377) > > at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:206) > > at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192) > > at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105) > > at org.apache.maven.cli.MavenCli.execute(MavenCli.java:954) > > at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288) > > at org.apache.maven.cli.MavenCli.main(MavenCli.java:192) > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > > at > > > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > > at > > > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > > at java.lang.reflect.Method.invoke(Method.java:498) > > at > > > org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289) > > at > > > org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229) > > at > > > org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415) > > at > > org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356) > > Caused by: java.lang.ClassNotFoundException: > > org.apache.maven.feature.api.MavenFeatureContext > > at > > > org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50) > > at > > > org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271) > > at > > > org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247) > > at > > > org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239) > > ... 47 more > > > > I'd like to make the error message nicer, but I'll need to dig further > > into Sisu. In any case it has the desired effect of preventing building a > > project that uses the experiment with a version of Maven that does not > > support the experimental features. > > > > The main point of experiments is to provide a way for people to try out a > > feature *that requires adapting your project to use that feature* in a > safe > > way that prevents users from accidentally building with a different > version > > of Maven. My goal would be to maybe release a > > 3.7.0-alpha-rfc-dynamic-phases-1 build of Maven with this experiment > turned > > on to gather wider feedback. Anyone using the feature would then be fully > > aware that the experiment may end up different when we actually decide > what > > we want to do, but can then easily try it out without a big song and > dance. > > > > NOTE: the pom rewriting that Robert has scheduled for 3.7.0 is IMHO not > > appropriate for this kind of experiment as it doesn't affect the actual > > build behaviour. If we have implemented pom rewriting correctly, users > > should not notice and shouldn't need to update their pom. Dynamic phases > > does require the pom to be updated, hence why it needs a more > heavy-handed > > enforcement through extensions (also the enforcer plugin wouldn't > guarantee > > execution on all lifecycles, so if you did something in after:clean > > enforcer wouldn't have run) > > > > -Stephen > > > > On Fri, 15 Nov 2019 at 21:16, Stephen Connolly > > stephen.alan.conno...@gmail.com> wrote: > > > >> > >> > >> On Fri 15 Nov 2019 at 15:18, Robert Scholte > wrote: > >> > >>> I have to admit that when trying to figure out from a Maven perspective > >>> it felt like post-X should be called with pre-X too, but that opinion > has > >>> changed. > >>> Why would anybody call pre-X? I'd say to bring the system ready to do > >>> custom X stuff, so it should stop here executing any other phases. > >>> However, when pre-X fails, I can imagine that post-X should be called > >>> too, as Maven wasn't able to bring the system in the right state. > >>> > >>> The problem lies in that Maven restarts the lifecycle. If only we could > >>> do something like > >>> - run up until pre-X (pause the lifecycle execution) > >>> - do your custom stuff > >>> - finish with the post-X > >>> > >>> Thinking about some kind of pause... This way at least we won't break > >>> the lifecycle and leave it clean. > >>> > >> > >> That’s easy. Have a Maven-pause-plugin that just waits for you to press > >> enter. Bind it to integration-test in a profile and presto! > >> > >> But that removes the need for the current explicit phases of pre- and > >> post- > >> > >> TBH I think we need to lay down the plan that we want to go towards. It > >> will take a while to change existing phases, in part because removing > >> phases is a breaking change. You can have 3rd part plugins that bind > >> executions to multiple phases, expecting those phases to both exist and > >> have specific execution behaviour. > >> > >> Hence why I think we should go all the way technically, but leave the > >> lifecycle mostly as-is (modulo adding any new phases and flagging > existing > >> phases as deprecated). > >> > >> Half measures will only prolong to pain for users. > >> > >> If instead we say: “here’s where we were, here’s where we’re going and > >> this is how we get there” people can incorporate that and adapt > >> > >> Messing about with one phase, that’s just hacks. Adding the ability to > >> define phase execution guarantees... that’s where we want to go. Adding > the > >> ability to control plugin execution order within phases... that’s where > we > >> want to go... is the syntax where we want to go? Probably not, but it’s > how > >> we can get there > >> > >>> > >>> > >>> On 15-11-2019 11:07:23, Stephen Connolly > >>> stephen.alan.conno...@gmail.com> wrote: > >>> On Fri 15 Nov 2019 at 09:18, Robert Scholte wrote: > >>> > >>> > On 13-11-2019 21:46:04, Stephen Connolly > >>> > wrote: > >>> > On Wed 13 Nov 2019 at 19:29, Robert Scholte wrote: > >>> > > >>> > > The name of the branch contains MNG-5668, but it contains much > more. > >>> > > I'd likely lead to comments like "great", without being explicit > >>> saying > >>> > > which part(s). > >>> > > I am aware there's all proposals touch the same code, but can be > >>> released > >>> > > isolated from each other. > >>> > > e.g. if the enums-value are changed to "pre-" and "post-" it should > >>> work > >>> > > for the existing phases, which means we could already use it quite > >>> soon > >>> > > (still need to test it myself, though) > >>> > > I also want to provide a counter proposal, but that takes time and > >>> for me > >>> > > there are other issues more important. > >>> > > >>> > > >>> > How would you handle the use case that we’ve already had reported: > >>> > > >>> > As a user I want to test my integration tests in my IDE by running > `mvn > >>> > integration-test` so that the test environment is not torn down and I > >>> can > >>> > debug and rerun the tests until I’m ready > >>> > > >>> > Robert Scholte: > >>> > I'd say if they want to set up there environment for the integration > >>> > tests, they'd be running pre-integration-test. > >>> > Next select in the IDE the test to execute. I don't see an issue > here. > >>> > Calling pre-integration-test implies NOT running > post-integration-test. > >>> > >>> > >>> I disagree. I think if you run the pre- phase then you should have the > >>> post- also run > >>> > >>> I think we could have a differential failure mode in the pre-phases > >>> though. > >>> Iow a pre- phase failure returns a different exit code than the actual > >>> phase itself > >>> > >>> > > >>> > > >>> > Every time I explain people about how Maven works with phases, they > are > >>> > amazed it doesn't run the post-phase. I doubt we'll see issues if we > >>> switch > >>> > to expected behavior. > >>> > > >>> > Based on the different views, I hope to see more involvement of PMC > >>> > members, because this will be a turning point that probable cannot be > >>> > undone. > >>> > > >>> > > >>> > With the new phases, the existing pom will still work, and some user > >>> opting > >>> > into after:integration-test knows what they are getting > >>> > > >>> > > >>> > > > >>> > > My biggest fear is that this will result in an All-Or-Nothing, and > I > >>> like > >>> > > to prevent that. If the try-finally part works as expected we can > >>> extract > >>> > > that part and prepare for one of the next Maven releases. > >>> > > >>> > > >>> > I’d like to understand your fear better. I’ve been playing with the > >>> PoC a > >>> > bit, and TBH it just feels right. > >>> > > >>> > For sure I’d prefer a schema change to encoding in a string, but I’m > >>> also > >>> > inclined towards string encoded dependency GAVs for 5.x so that > >>> wouldn’t be > >>> > the worst if we went that way. > >>> > > >>> > With pom rewriting, I think we could do a 4.1.0 model version that > >>> moved > >>> > the execution point and priority to attributes, by writing as a 4.0.0 > >>> with > >>> > the string encoded form... iow rewriting in 4.x allows us to tidy up > >>> the > >>> > schema as long as it has a 1:1 mapping to a 4.0.0 modelVersion that > >>> gets > >>> > deployed. > >>> > > >>> > > >>> > > > >>> > > Robert > >>> > > > >>> > > > >>> > > > >>> > > > >>> > > > >>> > > On 12-11-2019 10:25:42, Stephen Connolly > >>> > > wrote: > >>> > > On Tue 12 Nov 2019 at 07:34, Robert Scholte wrote: > >>> > > > >>> > > > This is not just MNG-5668, but also contains several non-existing > >>> > issues, > >>> > > > that should be mentioned explicitly as they will have huge > impact: > >>> > > > > >>> > > > - support before:/after: prefix for phase-binding > >>> > > > > >>> > > > - introduce priority > >>> > > > - reduce phases (this one hasn't been implemented, but seems to > be > >>> the > >>> > > > reason behind before:/after:) > >>> > > > >>> > > > >>> > > All detailed in the proposal on the wiki: > >>> > > https://cwiki.apache.org/confluence/display/MAVEN/Dynamic+phases > >>> > > > >>> > > Reducing phases would be a big change and not before 4.x at least > >>> (maybe > >>> > > 5.x more realistically... at least we’d need to deprecate the > phases > >>> for > >>> > a > >>> > > good while before removing any) > >>> > > > >>> > > > >>> > > > > >>> > > > I would like see separate branches for all of them, as they all > >>> have > >>> > > their > >>> > > > own discussion. > >>> > > > >>> > > > >>> > > The whole point of a PoC is the get feedback. I don’t see utility > in > >>> > > separate branches as they are all touching the same code. > >>> > > > >>> > > Once we get feedback we can decide where we want to go from there. > >>> > > > >>> > > > >>> > > > > >>> > > > Robert > >>> > > > On 11-11-2019 20:31:44, Stephen Connolly > >>> > > > wrote: > >>> > > > https://github.com/apache/maven/tree/mng-5668-poc is my POC > >>> > > implementation > >>> > > > for anyone interested in trying it out. > >>> > > > > >>> > > > Here's a pom that builds with the PoC > >>> > > > > >>> > > > > >>> > > > 4.0.0 > >>> > > > localdomain > >>> > > > foo > >>> > > > 1.0-SNAPSHOT > >>> > > > > >>> > > > > >>> > > > > >>> > > > maven-antrun-plugin > >>> > > > > >>> > > > > >>> > > > 1 > >>> > > > before:integration-test > >>> > > > > >>> > > > run > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > 2 > >>> > > > before:integration-test[1000] > >>> > > > > >>> > > > run > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > 3 > >>> > > > after:integration-test > >>> > > > > >>> > > > run > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > 4 > >>> > > > integration-test > >>> > > > > >>> > > > run > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > > >>> > > > On Sun, 27 Oct 2019 at 10:55, Robert Scholte wrote: > >>> > > > > >>> > > > > TLDR: We can do better than, but who is in control? > >>> lifecycle-owner, > >>> > > > > plugin-owner or pom-owner? > >>> > > > > > >>> > > > > I think we all recognize the issues we're trying to solve, but > >>> to me > >>> > > this > >>> > > > > proposal is not the right solution. > >>> > > > > > >>> > > > > In general there are 2 issues: > >>> > > > > 1. provide a mechanism that makes sure some executions are > called > >>> > even > >>> > > > its > >>> > > > > matching main phase fails. > >>> > > > > 2. provide a mechanism then ensures the order of executions. > >>> > > > > > >>> > > > > The problem of issue 1 is described in MNG-5668, but not the > >>> final > >>> > > > > solution. > >>> > > > > MNG-5668 proposes to give this power to the *lifecycle-owner*, > >>> > whereas > >>> > > > > stage 2 proposes to give the power to the *pom-owner*. > >>> > > > > Both agree on the same thing: by default these post-phases > >>> should be > >>> > > > > triggered even after failure of the matching main phase. This > is > >>> > > actually > >>> > > > > already expected behavior, so I don't expect real issues when > >>> > > > implementing > >>> > > > > this adjusted behavior. > >>> > > > > To me after:integration-test is just an alias for > >>> > > post-integration-test, > >>> > > > > both should work the same way. > >>> > > > > > >>> > > > > Issue 2 is a more common problem: controlling the order of > >>> > executions. > >>> > > > > In some cases it is pretty hard or even impossible to get the > >>> > preferred > >>> > > > > order. The latter happens when 2 goals of the same plugin must > be > >>> > > > executed > >>> > > > > and a goal of another plugin are competing within the same > phase. > >>> > > > > > >>> > > > > So let's first take a look at a phase: is there a clear > >>> definition? > >>> > > > > "A phase is a step in what Maven calls a 'build lifecycle'. The > >>> build > >>> > > > > lifecycle is an ordered sequence of phases involved in > building a > >>> > > > project". > >>> > > > > "Lifecycle phases are intentionally vague, defined solely as > >>> > > > > validation, testing, or deployment, and they may mean different > >>> > things > >>> > > to > >>> > > > > different projects." > >>> > > > > Phases are intended to be called from the commandline, and > >>> within the > >>> > > pom > >>> > > > > you define you can control what should happen before or during > >>> that > >>> > > > phase. > >>> > > > > > >>> > > > > To me changing the content of the -element is a codesmell as it > >>> > > > > becomes more than just a phase, and we start programming. Why > do > >>> we > >>> > > need > >>> > > > it? > >>> > > > > In the end it is all about ensuring the order of plugin > >>> executions. > >>> > > > > Stage3+4 proposes to give the power to the *pom-owner*, > >>> > > > > whereas MPLUGIN-350[2] proposes to give this power to the > >>> > > *plugin-owner*. > >>> > > > > IIUR Gradle does not have this issue, because their plugins are > >>> aware > >>> > > of > >>> > > > > input and output. They ensure that if the output plugin X is > the > >>> > input > >>> > > of > >>> > > > > plugin Y, than X is executed before Y. > >>> > > > > And we should do the same. And this comes with benefits: we can > >>> > decide > >>> > > if > >>> > > > > executions within a project can be executed in parallel. And > the > >>> pom > >>> > > > stays > >>> > > > > as clean as it is right now. > >>> > > > > > >>> > > > > In cases when there's a better ownership than the pom-owner, I > >>> would > >>> > > > > prefer to choose that solution. I already notice how people > >>> (don't) > >>> > > build > >>> > > > > up their knowledge regarding poms. The lifecycle-owner and > >>> > plugin-owner > >>> > > > > know much better what they're doing. > >>> > > > > > >>> > > > > thanks, > >>> > > > > Robert > >>> > > > > > >>> > > > > Some food for thoughts: consider a developer that wants to run > up > >>> > until > >>> > > > > pre-integration-test, because he wants to bring his system in a > >>> > certain > >>> > > > > state so he can work with IDE to do some work.Can we say that > If > >>> And > >>> > > Only > >>> > > > > If somebody called the pre-PHASE, there's no reason to end with > >>> the > >>> > > > > post-PHASE? > >>> > > > > > >>> > > > > [1] https://issues.apache.org/jira/browse/MNG-5668 > >>> > > > > [2] https://issues.apache.org/jira/browse/MPLUGIN-350 > >>> > > > > On 26-10-2019 14:20:50, Stephen Connolly > >>> > > > > wrote: > >>> > > > > On Sat 26 Oct 2019 at 10:50, Robert Scholte wrote: > >>> > > > > > >>> > > > > > To avoid confusion, let's call it stages. > >>> > > > > > > >>> > > > > > Stage 1: Always call post-bound executions (MNG-5665[1]) > >>> > > > > > Stage 2: before and after > >>> > > > > > Stage 3: priorities (MNG-3522[2]) > >>> > > > > > Stage 4: transitional lifecycle > >>> > > > > > >>> > > > > > >>> > > > > I have a prototype of stages 1-3 nearly (80%) done... just have > >>> to > >>> > > polish > >>> > > > > up and validate the bound executions with some tests > >>> > > > > > >>> > > > > > >>> > > > > > > >>> > > > > > For both all you need to start evaluating the value of phase. > >>> > > > > > For now we can assume that after:clean is just another label > >>> for > >>> > > > > > post-clean and will have exactly the same effect. > >>> > > > > > MNG-5665 contains a proposal to change the xml, but we > >>> shouldn't do > >>> > > > that > >>> > > > > > (yet). Let's start with a hardcoded list of postphases (or in > >>> case > >>> > a > >>> > > > goal > >>> > > > > > fails, see if a post-x phase exists). Stage 1 is to make it > >>> work, > >>> > > > stage 2 > >>> > > > > > to make it configurable. > >>> > > > > > IIRC you cannot ask from inside a Mojo if is was called > >>> explicitly > >>> > or > >>> > > > > > because it was bound to a phase, nor can you ask for the > value > >>> of > >>> > > this > >>> > > > > > phase. I kind of like this, plugins shouldn't care about > this. > >>> > > > > > However, inside Maven it will become important at which phase > >>> it is > >>> > > to > >>> > > > > > know if there are more executions to call OR create blocks of > >>> > > > executions. > >>> > > > > > Now it is just a list of executions: loop and fail fast. > >>> > > > > > > >>> > > > > > thanks, > >>> > > > > > Robert > >>> > > > > > > >>> > > > > > [1] https://issues.apache.org/jira/browse/MNG-5665 > >>> > > > > > [2] https://issues.apache.org/jira/browse/MNG-3522 > >>> > > > > > On 25-10-2019 21:33:14, Stephen Connolly > >>> > > > > > wrote: > >>> > > > > > Robert, > >>> > > > > > > >>> > > > > > I would be fine splitting out into, pardon the pun, phases: > >>> > > > > > > >>> > > > > > Phase 1: before and after > >>> > > > > > Phase 2: priorities > >>> > > > > > Phase 3: transitional lifecycle > >>> > > > > > > >>> > > > > > Might have a phase 1.5 of before:* and after:* to catch the > >>> start > >>> > of > >>> > > a > >>> > > > > > lifecycle and the end of a lifecycle... > >>> > > > > > > >>> > > > > > On Fri 25 Oct 2019 at 20:30, Stephen Connolly > >>> > > > > > stephen.alan.conno...@gmail.com [mailto: > >>> > > > stephen.alan.conno...@gmail.com > >>> > > > > ]> > >>> > > > > > wrote: > >>> > > > > > > >>> > > > > > Robert, Michael, Tibor, let’s continue here (though I asked > >>> Infra > >>> > and > >>> > > > > it’s > >>> > > > > > fine that anyone in the community can join our Slack) > >>> > > > > > > >>> > > > > > On Fri 25 Oct 2019 at 20:01, Stephen Connolly > >>> > > > > > stephen.alan.conno...@gmail.com [mailto: > >>> > > > stephen.alan.conno...@gmail.com > >>> > > > > ]> > >>> > > > > > wrote: > >>> > > > > > > >>> > > > > > > >>> https://cwiki.apache.org/confluence/display/MAVEN/Dynamic+phases [ > >>> > > > > > > >>> https://cwiki.apache.org/confluence/display/MAVEN/Dynamic+phases] > >>> > > > > > > >>> > > > > > Thoughts? > >>> > > > > > -- > >>> > > > > > > >>> > > > > > Sent from my phone > >>> > > > > > -- > >>> > > > > > > >>> > > > > > Sent from my phone > >>> > > > > > -- > >>> > > > > > > >>> > > > > > Sent from my phone > >>> > > > > > >>> > > > > -- > >>> > > > > Sent from my phone > >>> > > > > > >>> > > > > >>> > > -- > >>> > > Sent from my phone > >>> > > > >>> > -- > >>> > Sent from my phone > >>> > > >>> -- > >>> Sent from my phone > >>> > >> -- > >> Sent from my phone > >> > > >