[ Index ] [ Individual Project ] [ Placement Presentation ] [ Timetable ]

[ Index ] [ Research ] [ Schedule ]

Can Java's classloader handle packages of the same name?

Last Updated: 4th December 2001

A potential problem that could occur is Java's classloader detecting the different versions of the library and complaining that it has found two packages of the same name. This is a simple test to see how it handles a variety of situations.

The test packages will have the package name: com.milesbarr.test with the first package containing just one class Test and the second package containing two classes, Test and Test2. The idea being to see if Java will use Test from package one, and Test2 from package two if it can't find it in package one.

Code Listings

First compile package one:

javac v1/com/milesbarr/test/Test.java
No problems.

Then compile package 2:

javac v2/com/milesbarr/test/Test.java
No problems.

Then compile the test class that imports com.milesbarr.test:

javac MultpleVersions.java -classpath v1:v2
No problems.

Execution aiming to use package one:

java -classpath .:v1:v2 MultipleVersions
v1
2: v2

Execution aiming to use package one:

java -classpath .:v2:v1 MultipleVersions
v2
2: v2

Conclusion

The standard Java classloader copes with multiple packages of the same name existing. It simply loads the first one that is in the classpath. What is more interesting is that if it can't find a class in a package but that package also appears later in the classpath and the class is in it, Java will use it.

This is potentially harmful behaviour because you might want it to be an error if Java cannot find a class in an older version. The problem is now How do we keep packages whole?

Code Listings

MultipleVersions.java:

import com.milesbarr.test.*;

/**
 * MultipleVersions imports the test class to see how Java deals
 * with multiple packages of the same name.
 *
 * @author Miles Barr
 * @version 1.0
 */
public class MultipleVersions {
    public static void main (String args[]) {
	try {
	    Test test = new Test();
	    System.out.println(test.test());
	    
	    Test2 test2 = new Test2();
	    System.out.println(test2.test());
	} catch (Exception e) {
	    System.out.println("Failed because:");
	    e.printStackTrace();
	}
    }
}

Package one: Test.java

package com.milesbarr.test;
/**
 * Test class to see how java imports multiple packages of the same name.
 *
 * @author  Miles Barr
 * @version 1.0
 * @since   04-12-2001
 */
public class Test {
    public Test () {}

    /**
     * @return a String representing the version.
     */
    public String test () {
	return "v1";
    }
}

Package two: Test.java

package com.milesbarr.test;

/**
 * Test class to see how java imports multiple packages of the same name.
 *
 * @author  Miles Barr
 * @version 1.0
 * @since   04-12-2001
 */
public class Test {
    public Test () {}

    /**
     * @return a String representing the version.
     */
    public String test () {
	return "v2";
    }
}

Package two: Test2.java

package com.milesbarr.test;

/**
 * Test class to see how java imports multiple packages of the same name.
 *
 * @author  Miles Barr
 * @version 1.0
 * @since   04-12-2001
 */
public class Test2 {
    public Test2 () {}

    /**
     * @return a String representing the version.
     */
    public String test () {
	return "2: v2";
    }
}


Miles Barr <
miles@milesbarr.com>