Author: bentmann Date: Tue Dec 9 04:26:28 2008 New Revision: 724671 URL: http://svn.apache.org/viewvc?rev=724671&view=rev Log: [MNG-2384] document how plugin classloaders work Submitted by: Anders Kr. Andersen
o Applied with modifications Modified: maven/site/trunk/src/site/apt/guides/mini/guide-maven-classloading.apt Modified: maven/site/trunk/src/site/apt/guides/mini/guide-maven-classloading.apt URL: http://svn.apache.org/viewvc/maven/site/trunk/src/site/apt/guides/mini/guide-maven-classloading.apt?rev=724671&r1=724670&r2=724671&view=diff ============================================================================== --- maven/site/trunk/src/site/apt/guides/mini/guide-maven-classloading.apt (original) +++ maven/site/trunk/src/site/apt/guides/mini/guide-maven-classloading.apt Tue Dec 9 04:26:28 2008 @@ -2,44 +2,107 @@ Guide to Maven Classloading ------ Jason van Zyl + Anders Kristian Andersen ------ - 12 October 2005 + 2008-12-10 ------ - -How Maven's classloaders work + + +Guide to Maven Classloading + + This is a description of the classloader hierarchy in Maven 2.0.6+. + +* Overview + + * System Classloader + + * Core Classloader + + * Plugin Classloaders + + * Custom Classloaders + + [] + + +* 1. {System Classloader} Maven uses the {{{http://classworlds.codehaus.org}Classworlds}} classloading framework with which we - create our classloader graph. If you look in your <<<$\{maven.home\}/m2/core>>> directory you will see a single JAR - which is the classworlds JAR we use to boot the classloader graph. The Classworlds JAR is the only element of - the Java $CLASSPATH and Classworlds then builds the following graph of classloaders where the <<<plexus.core>>> classloader, - or Realm in Classworlds, is the parent in the context of Maven. - -+----+ - -[plexus.core] -${maven.home}/core/*.jar - ^ - | - | -[plexus.core.maven] -${maven.home}/lib/*.jar - ^ - | - | -[per plugin] - -+----+ - - The top level classloader contains plexus container and plexus utils, and also has access to Classworlds. - - The next classloader down the graph contain the core requirements of Maven. In general these are just Maven libraries. - We hope to further separate these in the future to just be Maven APIs and have the implementations selected at - runtime as required by the system. - - After that, each plugin has its own classloader, including its dependencies, itself, and the libraries above. - It <does not> contain the project dependencies as in Maven 1.x, but instead has access to a list of JAR files in case - they are needed. - - In addition, a project can list <extensions>. These are loaded into <<<[plexus.maven.core]>>> classloader and - so available to the Maven core and all plug-ins for the current project and subsequent projects (in the future, - we plan to remove it from subsequent projects). + create our classloader graph. If you look in your <<<$\{maven.home\}/boot>>> directory you will see a single JAR + which is the Classworlds JAR we use to boot the classloader graph. The Classworlds JAR is the only element of + the Java <<<CLASSPATH>>> and Classworlds then builds the other classloaders or realms in Classworlds terminology. + + An Ant script like this will show the contents of the system classloader: + +--- + <target name="info"> + <echo>java.class.path=${java.class.path}</echo> + </target> +--- + + +* 2. {Core Classloader} + + The second classloader down the graph contains the core requirements of Maven. More precisely, the core classloader + has the libraries in <<<$\{maven.home\}/lib>>>. In general these are just Maven libraries, e.g. instances of + <<<{{{http://maven.apache.org/ref/current/maven-project/apidocs/org/apache/maven/project/MavenProject.html}MavenProject}}>>> + belong to this classloader. + We hope to further separate these in the future to just be Maven APIs and have + the implementations selected at runtime as required by the system. + + You can add elements to this classloader by {{{http://maven.apache.org/ref/current/maven-model/maven.html#class_extension}extensions}}. + These are loaded into the same place as <<<$\{maven.home\}/lib>>> and hence are available + to the Maven core and all plugins for the current project and subsequent projects (in future, we + plan to remove it from subsequent projects). + + +* 3. {Plugin Classloaders} + + After that, each plugin has its own classloader that is a child of Maven's core classloader. + The classes in this classloader are taken from the dependencies in the plugin's dependency list. + + Users can add dependencies to this classloader by adding dependencies + to a plugin in the <<<{{{http://maven.apache.org/ref/current/maven-model/maven.html#class_plugin}plugins/plugin}}>>> + section of their project <<<pom.xml>>>. + Here is a sample of adding <<<ant-nodeps>>> to the plugin classloader of the Antrun Plugin and hereby enabling the use + of additional/optional Ant tasks: + +--- + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.3</version> + <dependencies> + <dependency> + <groupId>org.apache.ant</groupId> + <artifactId>ant-nodeps</artifactId> + <version>1.7.1</version> + </dependency> + </dependencies> + ... + </plugin> +--- + + Plugins can inspect their effective runtime class path via the expressions <<<$\{plugin.artifacts\}>>> or + <<<$\{plugin.artifactMap\}>>> to have a list or map, respectively, of resolved artifacts injected from the + <<<{{{http://maven.apache.org/ref/current/maven-plugin-descriptor/apidocs/org/apache/maven/plugin/descriptor/PluginDescriptor.html}PluginDescriptor}}>>>. + + Please note that the plugin classloader does not contain the + {{{http://maven.apache.org/ref/current/maven-model/maven.html#class_dependency}dependencies}} + of the current project. Instead, plugins can query the project's compile, runtime and test class path from the + <<<{{{http://maven.apache.org/ref/current/maven-project/apidocs/org/apache/maven/project/MavenProject.html}MavenProject}}>>> + in combination with the mojo annotation <<<requiresDependencyResolution>>> from the + {{{http://maven.apache.org/developers/mojo-api-specification.html}Mojo API Specification}}. For instance, flagging a + mojo with <<<@requiresDependencyResolution runtime>>> enables it to query the runtime class path of the current project + from which it could create further classloaders. + + When a build plugin is executed, the thread's context classloader is set to the plugin classloader. + + +* 4. {Custom Classloaders} + + Plugins are free to create further classloaders on their discretion. For example, a plugin might want to create a + classloader that combines the plugin class path and the project class path. + + It is important to understand that the plugin classloader cannot load classes from any of those custom classloaders. + Some factory patterns require that. Here you must add the classes to the plugin classloader as shown before.