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 
> <[email protected]> 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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to