You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by Florin Vancea <fv...@maxiq.ro> on 2003/06/04 12:15:11 UTC

Classloading by property

I just noticed something regarding Maven classloading while trying to sort
out a direct JMX approach to JBoss deployment. The issue also applies to
other (maybe more common) situations, so please read on and give me some
feedback.

I am using (approximately) CVS HEAD for "normal" Maven (not maven-new).

When loading the plugins, the dependencies are conditionally attached to the
"root.maven" classloader, depending on the "classloader" property taken from
the plugin's project (via processDependencies in Project). This seems only
fair.
However, when loading the "working" project, somewhere in MavenUtils there
is a static "getProject" that adds _all_ the dependencies, without respect
to any "classloader" property. This leaves no control over what gets in the
classloader used to run things like junit (or in my case the JMX custom
tasks).

Scenario: Maven itself uses log4j-1.1.3, therefore lib/log4j-1.1.3.jar gets
in "root.maven" classloader. The project itself would like however to use
e.g. log4j-1.2.8, so it includes it in <dependencies>. Compiling works fine.
Then it comes to running junit _not_forked_ (or in my case running the JMX
client, which uses log4j through JBoss's client logging system). Then things
break, because now we have _two_different_ log4j's in "root.maven" and the
classloader does not guarantee that all classes will be loaded from the same
source. The result: Very odd exceptions, class-loading related.
The same thing happens with xerces when versions clash.

There is an obvious workaround: use only the very same versions that the
installed Maven is using. But this is not what Maven is about, is it?

The initial workaround I applied (for junit tests) was to modify the test
plugin such that some of the packages do not get passed on further. It
worked, but it's really ugly.

Now I got into the JMX issue and I cannot do that anymore since the
JMX-thingie will be a custom-defined tag backed by a bean inside a plugin. I
tried to "fake" the loading such that the only log4j was the 1.1.3 from
maven/lib. It worked. I also changed in maven/lib 1.1.3 with 1.2.8 (leaving
the loading unchanged). It worked. Both are "workbench" workarounds, not
usable in the real world.
Then I searched into the source and I found the MavenUtils getProject( issue
described at the top of this message.

Yes, there is a comment there saying something about breaking the plugins
:). Now, my question is to the good soul that wrote that and who probably
knows why he wrote that: Would it be possible to use something along the
lines of project.processDependencies() instead of the unconditional code in
MavenUtils.getProject(..) ?

The actual solution I would propose is actually checking for a property like
"classloader", acting appropriately if found and NOT appending to cl if the
name is bad (like <classloader></classloader> or
<classloader>noload</classloader>). If there is no "classloader" property
then appending should proceed as known, to avoid the impact on existing
projects.

I could try to provide a patch for MavenUtils doing that, if you think it's
a good idea.

Florin



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