You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by "Ward, Bradley (MAN-Corporate)" <Br...@cox.com> on 2005/09/07 19:25:49 UTC

Why Is Maven Using Different Class Loaders?

I've got a really strange thing going on with Maven (v. 1.0.2). It seems to
be using totally different class loaders depending on how I invoke Maven.

 

I have this debug code in my junit test case code:

 

        Class thisClass = this.getClass();

        System.err.println("The Class of the test suite is: " + thisClass); 

        ClassLoader classLoader = thisClass.getClassLoader();

        System.err.println("The class loader is: " + classLoader);

        Package thisPackage = thisClass.getPackage();

        String tmsg = "The " + thisClass.getName()

        + ".getPackage() method returned: " + thisPackage;

        System.err.println(tmsg);

 

 

When I run "maven site", I get this output, and my unit tests work:

 

[junit] The Class of the test suite is: class
com.manheim.PriceBookData.PriceBookDataTestSuite

[junit] The class loader is: sun.misc.Launcher$AppClassLoader@53ba3d

[junit] The com.manheim.PriceBookData.PriceBookDataTestSuite.getPackage()
method returned: package com.manheim.PriceBookData

 

When I run "maven jar:jar", I get this output, and my unit tests fail
because of the null:

 

[junit] The Class of the test suite is: class
com.manheim.PriceBookData.PriceBookDataTestSuite

[junit] The class loader is: org.apache.tools.ant.AntClassLoader@1c18a4c

[junit] The com.manheim.PriceBookData.PriceBookDataTestSuite.getPackage()
method returned: null

 

In both cases, the unit tests are being run as a part of the test:test goal.

 

Note that a totally different class loader is being used in the two
different invocations of maven...

 

Even weirder is that the getPackage() method is returning a null!

 

Why are there two different class loaders being used depending on the way
maven is run?

 

Any help would be most appreciated!

 

Thanks,

 

Brad


Re: Why Is Maven Using Different Class Loaders?

Posted by Andy Glick <an...@acm.org>.
Ward, Bradley (MAN-Corporate) wrote:
> I've got a really strange thing going on with Maven (v. 1.0.2). It seems to
> be using totally different class loaders depending on how I invoke Maven.
> 

Are you familiar with the concepts of classloader parent-child hierarchies or of the classLoader class loading strategies used by JVM's? There are actually different policies used by different classloaders which can lead to a situation such as you have described that isn't necessarily a bug. 

Have you set the property "maven.junit.fork=yes" in your project.properties or build.properties file? 

I ask this because I have often experienced situations in which testcases fail using "maven jar:jar" when maven.junit.fork is not set to yes, which then succeed when it is. 

Looking more closely at the debugging lines that you have included, I would bet that you haven't set maven.junit.fork=yes, and I'll explain why. In the failing case, the classloader is the Ant classloader. That would be consistent with the following scenario: Maven is invoking JUnit via the JUnit Ant task, so the Ant classloader is active, therefore the testcase is running in the same JVM as Maven. In "maven site" case, it appears to follow a different scenario: the JUnit tests have been forked from the original process, so they are running in a new JVM. classloader that would be loaded and active in a newly forked process in a Sun JVM is quite likely to be sun.misc.Launcher$AppClassLoader, which your getClassLoader() invocation returned. 

So again, if you haven't set "maven.junit.fork=yes" please try that. If on the off chance that you have already set it and are still seeing this problem, then I've gone off on a wild goose chase, and you should probably write back providing more configuration information as well as the captured output from a failing run with the -X flag set. But as I said, the evidence that you've presented suggests a scenario similar to the one I've described.

Here is the URL of Liang and Bracha's 1998 paper "Dynamic Classloading in the Java Virtual Machine". It isn't an easy read, but it is thorough. 

http://www.cs.purdue.edu/homes/jv/smc/pubs/liang-oopsla98.pdf


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