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]
