Oh if only... there is some subtleties going on here.

Classes are managed by the "plexus" / "classworlds" stuff, so you cannot
override core classes etc.

The problem is what extensions are visible and from which classloader

On 18 September 2017 at 08:42, Charles Honton <c...@honton.org> wrote:

> From a security perspective, I would expect that core classes can not be
> overridden by extensions or plugins.  Likewise, extension classes can not
> be overridden by plugins.
>
> Given the use case of defaulting resources, I would expect that the plugin
> resources are first, followed by plugin specific extensions, followed by
> global extensions, finally core maven.  (This allows resources to be
> specialized.)
>
> regards,
> chas
>
> > On Sep 18, 2017, at 3:20 AM, Stephen Connolly <
> stephen.alan.conno...@gmail.com> wrote:
> >
> > Hmmm, so I did some experiments:
> >
> > If you want to ride along, the experiments are at:
> >
> > https://github.com/stephenc/mng-6209
> >
> > So basically I have a plugin that does three different tests:
> >
> >        getLog().info("Injected by @Component:");
> >        for (Lifecycle l : lifecycles) {
> >            if (l.getId().startsWith("mng-6209-")) {
> >                getLog().info("  " + l.getId().substring(9));
> >            }
> >        }
> >        getLog().info("");
> >        getLog().info("On Plugin Class Loader:");
> >        try {
> >            ClassLoader tccl = ListMojo.class.getClassLoader();
> >            for (URL url :
> > Collections.list(tccl.getResources("META-INF/probe.txt"))) {
> >                InputStream is = url.openStream();
> >                try {
> >                    getLog().info("  " + IOUtil.toString(is).trim());
> >                } finally {
> >                    is.close();
> >                }
> >            }
> >        } catch (IOException e) {
> >            throw new MojoExecutionException(e.getMessage(), e);
> >        }
> >        getLog().info("");
> >        getLog().info("On Thread Context Class Loader:");
> >        try {
> >            ClassLoader tccl =
> > Thread.currentThread().getContextClassLoader();
> >            for (URL url :
> > Collections.list(tccl.getResources("META-INF/probe.txt"))) {
> >                InputStream is = url.openStream();
> >                try {
> >                    getLog().info("  " + IOUtil.toString(is).trim());
> >                } finally {
> >                    is.close();
> >                }
> >            }
> >        } catch (IOException e) {
> >            throw new MojoExecutionException(e.getMessage(), e);
> >        }
> >
> >
> > First off, I hijack the @Component injection with some fake "lifecycles"
> to
> > see what "plexus" exposes to the plugins.
> >
> > Second, I look at the resources visible from the plugin's classloader.
> >
> > Finally, I look at the resources visible from the TCCL.
> >
> > Here's what 3.5.0 outputs:
> >
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO] Building Both extensions. Order: plugin1, plugin2 1.0-SNAPSHOT
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO]
> > [INFO] --- plugin1:1.0-SNAPSHOT:list (default) @ probe1 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] --- plugin2:1.0-SNAPSHOT:list (default) @ probe1 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO] Building Only plugin1 extensions. Order: plugin1, plugin2
> > 1.0-SNAPSHOT
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO]
> > [INFO] --- plugin1:1.0-SNAPSHOT:list (default) @ probe2 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] --- plugin2:1.0-SNAPSHOT:list (default) @ probe2 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin2
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin2
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO] Building Both extensions. Order: plugin2, plugin1 1.0-SNAPSHOT
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO]
> > [INFO] --- plugin2:1.0-SNAPSHOT:list (default) @ probe3 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] --- plugin1:1.0-SNAPSHOT:list (default) @ probe3 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin1
> > [INFO]
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO] Building Both extensions. Order: plugin1, plugin2. Extra
> dependency
> > in plugin1 1.0-SNAPSHOT
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO]
> > [INFO] --- plugin1:1.0-SNAPSHOT:list (default) @ probe4 ---
> > [INFO] Injected by @Component:
> > [INFO]   extjar2
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]
> > [INFO] --- plugin2:1.0-SNAPSHOT:list (default) @ probe4 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > ------------------------------------------------------------------------
> >
> > Now if we run with 3.5.1 (which contains the fix for MNG-6209)
> >
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO] Building Both extensions. Order: plugin1, plugin2 1.0-SNAPSHOT
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO]
> > [INFO] --- plugin1:1.0-SNAPSHOT:list (default) @ probe1 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   extjar1
> >
> > I would have expected the sequence to be: /build/extensions in pom order
> > followed by /build/plugins/plugin[extensions=true] in pom order. This
> seems
> > to be the reverse order. Is this a bug?
> >
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin1
> >
> > We haven't changed how the plugin classloader gets instantiated in
> > MNG-6209. It seems strange to me that this excludes the
> > /build/extensions... on the other hand this could be a side-effect of how
> > the classloader gets instantiated (which would mean using the plugin's
> > classloader is probably a bad idea, perhaps we need to provide the
> ability
> > to inject the classloader as a @Component or something)
> >
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   extjar1
> > [INFO]   extjar2
> >
> > OK, we see the change vs 3.5.0 as this is now the project realm...
> though I
> > would have expected the project realm to also include the plugins that
> were
> > marked as extensions...
> >
> > [INFO]
> > [INFO] --- plugin2:1.0-SNAPSHOT:list (default) @ probe1 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   extjar1
> > [INFO]   extjar2
> > [INFO]
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO] Building Only plugin1 extensions. Order: plugin1, plugin2
> > 1.0-SNAPSHOT
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO]
> > [INFO] --- plugin1:1.0-SNAPSHOT:list (default) @ probe2 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   extjar1
> >
> > As expected, given that plugin2 is not an extension here (apart from the
> > order being reverse of what I expect)
> >
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO] --- plugin2:1.0-SNAPSHOT:list (default) @ probe2 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   extjar1
> >
> > As expected (modulo order) because a plugin should see any self-defined
> > extensions. I would expect the order to be plugin2, extjar1, extjar2,
> > plugin1 (because the plugin is not an extension, it should have its
> > extensions as priority over the project realms's)
> >
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin2
> > [INFO]   extjar2
> > [INFO]   extjar1
> >
> > WAT! ok, this I do not understand. Something is wrong somewhere, either
> > plugin1's classloader should also include extjar2 and extjar1 or this one
> > shouldn't. And since we have extjar1 and extjar2 where is plugin1? (if
> the
> > inclusion is correct here I expect plugin2, extjar1, extjar2, plugin1 as
> a
> > plugin that is not an extension plugin should have its own implementation
> > first followed then by /build/extensions in pom order and then
> > /build/plugins/plugin[extension==true]
> >
> > This is making no sense at all!
> >
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   plugin2
> > [INFO]   extjar2
> > [INFO]   extjar1
> >
> > So TCCL is the plugin classloader here as expected
> >
> > [INFO]
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO] Building Both extensions. Order: plugin2, plugin1 1.0-SNAPSHOT
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO]
> > [INFO] --- plugin2:1.0-SNAPSHOT:list (default) @ probe3 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   extjar1
> >
> > I note that the change in pom order has had no effect on the component
> > sequence. This leads me to suspect that plexus has some rule that is
> > defining the sequencing... it would be good if we could document that
> > somewhere...
> >
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO] --- plugin1:1.0-SNAPSHOT:list (default) @ probe3 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin2
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin1
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO] Building Both extensions. Order: plugin1, plugin2. Extra
> dependency
> > in plugin1 1.0-SNAPSHOT
> > [INFO]
> > ------------------------------------------------------------------------
> > [INFO]
> > [INFO] --- plugin1:1.0-SNAPSHOT:list (default) @ probe4 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   plugin2
> > [INFO]   extjar2
> > [INFO]   extjar1
> >
> > WAT! seems that @Component is somewhat in random order, in this case we
> > have modified the dependencies if plugin1 to also include extjar2, the
> > order I would expect is:
> >
> > extjar1, extjar2, plugin1, extjar2, plugin2
> >
> > Given the previous executions and the fact that changing the sequence of
> > plugin1 and plugin2 in the pom did not affect the previous executions, if
> > plexus had a deterministic ordering then I would have been somewhat OK
> with:
> >
> > plugin2, plugin1, extjar2, extjar2, extjar1
> >
> > But this seems to suggest that we have a completely non-deterministic
> > ordering... that is not good for reproducible builds...
> >
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin1
> > [INFO]   extjar2
> >
> > Now we see extjar2 but only because it has been explicitly added to the
> > plugins dependencies, IMHO it should be here twice, e.g.
> >
> > extjar1, extjar2, plugin1, extjar2, plugin2
> >
> > But it seems acceptable if this is instead plugin1, extjar2 (though it
> > makes the plugin classloader useless for discovery)
> >
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   extjar1
> > [INFO]   extjar2
> > [INFO]
> > [INFO] --- plugin2:1.0-SNAPSHOT:list (default) @ probe4 ---
> > [INFO] Injected by @Component:
> > [INFO]   plugin1
> > [INFO]   extjar2
> > [INFO]   plugin2
> > [INFO]   extjar2
> > [INFO]   extjar1
> > [INFO]
> > [INFO] On Plugin Class Loader:
> > [INFO]   plugin2
> > [INFO]
> > [INFO] On Thread Context Class Loader:
> > [INFO]   extjar1
> > [INFO]   extjar2
> > [INFO]
> > ------------------------------------------------------------------------
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
> For additional commands, e-mail: dev-h...@maven.apache.org
>
>

Reply via email to