You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by Grzegorz SÅ‚owikowski <gs...@gmail.com> on 2014/04/10 16:20:57 UTC

Classloader cache in Maven plugin - how to avoid classloader leaks?

Hi Devs

Actual question is at the end. Some introduction first.

I'm developing two Maven plugins, where actual functionality is not
implemented in the plugin, but delegated to "providers".
This idea is taken from maven-compiler-plugin, where the plugin
delegates compilation to plexus compilers.

I've improved this in my plugins by adding provider auto-discovery
mechanism based on some project properties, etc.

In maven-compiler-plugin default "javac" compiler is added as a
dependency by default. You can add other
compilers as dependencies and set desired "compilerId". This
implementation works because plexus-javac-compiler
has no dependencies, so adding other compilers will not cause any
dependency conflict.

In both my plugins I have (for now) two providers, with conflicting
transitive dependencies (different version of the same dependency),
so I cannot add one of them by default, because when I would want to use
the other one I couldn't remove the first, default one
from dependencies, and the resulting classpath after dependency
resolution would be unpredictable.

The solution is the ability to find and resolve the right provider
without the need to add it do plugin's dependencies.
This is similar to Surefire internal (so called "well known") providers
(junit3, junit4, testng). They are never declared as Surefire dependencies,
but Surefire can resolve then in runtime.

To improve provider auto-discovery performance Surefire caches already
resolved provider dependencies. See:
https://github.com/apache/maven-surefire/blob/master/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ClasspathCache.java

I went one step further and I cache ClassLoaders because repetitive
class loading process is very timeconsuming
even when cache'ing classpaths.

My question is, when can I dispose my cached classloaders? Is there any
project build event I can add listener to?
I would like to dispose the classloaders at the end of reactor build,
not at the end of each reactor module build.

Thanks in advance.

Regards
Grzegorz Slowikowski


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org


Re: Classloader cache in Maven plugin - how to avoid classloader leaks?

Posted by Igor Fedorenko <ig...@ifedorenko.com>.
We've introduced AbstractMavenLifecycleParticipant#afterSessionEnd for
this very purpose in 3.2.1, it is called after all projects are built
and gives build extensions the chance to do any necessary cleanup. You
will have to require your plugin to have <extensions>true</extensions>
in pom.xml, because regular plugins are not guaranteed to be present for
entire duration of the build.

--
Regards,
Igor



On 2014-04-10, 18:20, Grzegorz SÅ‚owikowski wrote:
> Hi Devs
>
> Actual question is at the end. Some introduction first.
>
> I'm developing two Maven plugins, where actual functionality is not
> implemented in the plugin, but delegated to "providers".
> This idea is taken from maven-compiler-plugin, where the plugin
> delegates compilation to plexus compilers.
>
> I've improved this in my plugins by adding provider auto-discovery
> mechanism based on some project properties, etc.
>
> In maven-compiler-plugin default "javac" compiler is added as a
> dependency by default. You can add other
> compilers as dependencies and set desired "compilerId". This
> implementation works because plexus-javac-compiler
> has no dependencies, so adding other compilers will not cause any
> dependency conflict.
>
> In both my plugins I have (for now) two providers, with conflicting
> transitive dependencies (different version of the same dependency),
> so I cannot add one of them by default, because when I would want to use
> the other one I couldn't remove the first, default one
> from dependencies, and the resulting classpath after dependency
> resolution would be unpredictable.
>
> The solution is the ability to find and resolve the right provider
> without the need to add it do plugin's dependencies.
> This is similar to Surefire internal (so called "well known") providers
> (junit3, junit4, testng). They are never declared as Surefire dependencies,
> but Surefire can resolve then in runtime.
>
> To improve provider auto-discovery performance Surefire caches already
> resolved provider dependencies. See:
> https://github.com/apache/maven-surefire/blob/master/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ClasspathCache.java
>
> I went one step further and I cache ClassLoaders because repetitive
> class loading process is very timeconsuming
> even when cache'ing classpaths.
>
> My question is, when can I dispose my cached classloaders? Is there any
> project build event I can add listener to?
> I would like to dispose the classloaders at the end of reactor build,
> not at the end of each reactor module build.
>
> Thanks in advance.
>
> Regards
> Grzegorz Slowikowski
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
> For additional commands, e-mail: dev-help@maven.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org