You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by Kris Nuttycombe <Kr...@noaa.gov> on 2006/03/10 22:36:05 UTC

Re: [M2] Plugin Classloaders

Brett Porter wrote:
> To add a bit of detail for a volunteer to submit as documentation... :)
>
> m2/core/boot is what is in the java classpath (ie, just classworlds,
> which constructs classloaders for the rest of the system)
>
> the top level classloader contains plexus container and plexus utils
> (see m2/core), and also has access to classworlds
>
> the next classloader has the libraries in m2/lib (a bug in beta 1
> incorporated commons-logging and -lang, sorry about that!) In general
> these are just maven libraries. We hope to further separate these in
> future to just be maven apis.
>
> after that, each plugin has its own classloader, including its
> dependencies, itself, and the libraries above. It *does not* contain
> the project dependencies like in m1, 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
> the same place as m2/lib and so available to the maven core and all
> plugins for the currnet project and subsequent projects (in future, we
> plan to remove it from subsequent projects).
>
> - Brett
So, if one is developing a plugin, what is the appropriate strategy to
take if you want to make the project's artifact (or an intermediate
stage thereof, like the target/classes directory) available to that
plugin? I've tried the following (this is in the execute() method of my
Mojo):

            URL[] urls = { classesDirectory.toURL() };
            ClassLoader originalContextClassLoader =
Thread.currentThread().getContextClassLoader();
            URLClassLoader executionClassLoader = new
URLClassLoader(urls, ClassLoader.getSystemClassLoader());
           
            //enable the new classloader, execute, then restore the old
classloader
           
Thread.currentThread().setContextClassLoader(executionClassLoader);
            this.exec();
           
Thread.currentThread().setContextClassLoader(originalContextClassLoader);

I know that I'm getting the URL to target/classes correctly, but I'm
still getting ClassNotFoundException when my exec() method goes to load
one of those classes.

Any ideas? I've also tried replacing line 3 with:

            URLClassLoader executionClassLoader = new
URLClassLoader(urls, originalContextClassLoader);

without success.

Thanks for your help,

Kris