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 > >