What's the benefit of this approach rather than just having the user adding the dependencies directly to the plugin (execution) declaration? To me it seems as it would be the same number of xml rows in the pom and it would make the plugin coding a lot easier.
/Anders On Fri, Aug 3, 2012 at 2:56 PM, Jesse Glick <[email protected]> wrote: > On 08/02/2012 04:58 AM, Anders Hammar wrote: >> >> not have a dependency on some library in the plugin itself but rely on it >> being declared as a dependency in the Maven project where the plugin is >> bound. That made it >> totally controllable by the project. > > > If the build-time code would not normally already be a dependency of the > project - your main concern - then you could have the mojo configuration > accept a parameter typed as a list of "dependencies". > (org.apache.maven.model.Dependency[]?) These would then have to be resolved > (transitively) against pluginRepositories, and used to construct a URL[] to > pass to a URLClassLoader (possibly prepended to the project's regular > dependencies). Thus the project could declare e.g. > > <dependencies> > <dependency> > <groupId>some.framework</> > <artifactId>the-api</> > </> > <dependency> > <groupId>some.framework</> > <artifactId>the-impl</> > <scope>runtime</> > </> > </> > <build> > <plugins> > <plugin> > <groupId>some.framework</> > <artifactId>the-plugin</> > <configuration> > <toolDependencies> > <dependency> > <groupId>some.framework</> > <artifactId>the-build-tool</> > </> > </> > </> > </> > </> > </> > > Naturally you still need to be careful that a given version of the-plugin - > specifically, that part of its code which will link against classes loaded > by the URLClassLoader - is API-compatible with past, present, and > foreseeable future versions of the-build-tool. If there are known breaking > API changes, a single version of the plugin could also supply multiple > adapters tuned to different version ranges of the-build-tool, or use > reflection to try several method variants, or at least catch LinkageError > and report the problem gracefully. > > A mojo like this could be awkward to write from scratch; would be best to > have an archetype for it. In particular, if you are using direct Java > linkage between the-plugin code and the-build-tool (rather than, say, > reflection), and the-plugin does not have a direct dependency on any version > of the-build-tool (i.e. <toolDependencies> is mandatory and not just an > optional selection of an alternative version) and/or supports multiple > incompatible version ranges of the-build-tool, then to build the-plugin > itself you need a multimodule project: > > the-plugin-parent > the-build-tool-abstraction (jar) > the-build-tool-adapter-v1 (jar) -> the-build-tool-abstraction, > the-build-tool @ [1.0.0,2) > the-build-tool-adapter-v2 (jar) -> the-build-tool-abstraction, > the-build-tool @ [2.0.0,3) > the-plugin (maven-plugin) -> the-build-tool-abstraction > > Here the-plugin resolves <toolDependencies> and determines which major > version of the-build-tool is being requested ("1" or "2"). It then > constructs a URLClassLoader parented to the plugin ClassLoader (or whatever > loads classes from the-build-tool-abstraction) including everything from > <toolDependencies> (resolved from pluginRepositories) plus the appropriate > the-build-tool-adapter-v* (also from pluginRepositories), creates an > instance of an interface defined in the-build-tool-abstraction and > implemented in the-build-tool-adapter-v* (selected via > java.util.ServiceLoader, Plexus @Component, > ClassLoader.loadClass("hardcoded"), etc.), and casts to > the-build-tool-abstraction interface which the plugin can directly "see". > Then it calls methods on this instance to run the build tool. > > Even if you are sure the-build-tool will be API-compatible it is not wise to > mash everything into one project. While the-plugin could declare a > <scope>provided</> dependency on the-build-tool, as the developer of > the-plugin you would need to be careful to keep track of which > src/main/java/**/*.java are permitted to refer to types in the-build-tool > and which are not; furthermore, the URLClassLoader would then need to > override loadClass to _not_ delegate loading of these classes to its parent > (since then they would be loaded by the plugin class loader and fail to > resolve against the-build-tool). Using a multimodule project as sketched > above documents and enforces the runtime structure and means that the > URLClassLoader can use normal parent delegation. > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
