Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Class names don't identify a class

JavaFAQ Home » Story by Dr. Kabutz Go to all tips in Story by Dr. Kabutz


Bookmark and Share 2001-05-03 The Java Specialists' Newsletter [Issue 018] - Class names don't identify a class

2001-05-03 The Java Specialists' Newsletter [Issue 018] -

Class names don't identify a class

Author: Dr. Heinz M. Kabutz

JDK version:

Category: Language

You can subscribe from our home page: http://www.javaspecialists.co.za (which also hosts all previous issues, available free of charge Smile

Welcome to the 18th issue of "The Java(tm) Specialists' Newsletter", now sent to 38 countries on all continents of our globe. Please remember to forward the newsletter to others who might be interested.

BEFORE YOU FILE THIS NEWSLETTER ...

I have a question for you:

South Africa is a beautiful country with a relatively stable economy, compared to other developing countries. The South- Western part of South Africa, called the Western Cape, is an especially great place to live, mainly because of the stunning environment, weather, etc. For some strange reason, we are losing a lot of programmers to the land of mist and the land of abundance. There are those in the private sector willing to invest significant money to realise their dream of the Western Cape becoming another success story in the computer world.

Now the question: If you used to live in South Africa, what would entice you to come back to the Western Cape? If you are already living in South Africa, what would prevent you from leaving? Lastly, if you are an IT professional living outside of South Africa, what "things" would attact you to move to the Western Cape?

I'm very interested to hear your opinions on this question, so don't delay, answer today Smile

Class names don't identify a class

This week I want to introduce the concepts of having Class objects in the VM with the exact same name, but being completely different. I had the opportunity to question Dr. Jung, who has been using this for a while now, and at long last, my small brain has made "click" and I understand (I think). In two weeks time, he is going to write the newsletter (he wrote the piece on dynamic proxies) and he will demonstrate how you can build up a sibling hierarchy of class loaders which you can use to automatically redeploy classes and find dependencies, etc. I didn't quite follow all of his explanations, so I'm looking forward to read what he has to say about this topic. In the meantime, to prepare us all, I've written a simple example to demonstrate how it works.

In JDK 1.2, SUN added a new approach to class loading which allows you to identify classes not only by the class name, but also by the context in which it was loaded. We can set the ClassLoader for a Thread, which we can then use to load classes. By having a different classloader, you are effectively constructing a new instance of Class, which is then completely different from other instances of Class. This was, I think, also possible in JDK 1.1, but it is much easier to make an instance of a ClassLoader in JDK 1.2 as there is now a URLClassLoader which you can point to a directory where it will load the classes from.

For example, say we have two directories, a1 and a2. In each of these directories we have a class A:

//: a1/A.java
public class A {
  public String toString() { return "This is the first class"; }
}

//: a2/A.java
public class A {
  public String toString() { return "This is the second class"; }
}

As you will agree, the two classes are completely different. They can have different method definitions, data members or access control. The normal way of using these two classes is to choose at compile/run time which one you wish to use. For example, we may have a class NormalTest below:

//: NormalTest.java
public class NormalTest {
  public static void main(String[] args) {
    System.out.println(new A());
  }
}

To compile this class, we have to specify the directory where A resides, either a1 or a2. Since the signature is the same, we can compile with one class and run with the other class if we want.

javac -classpath .;a1 NormalTest.java
java -classpath .;a2 NormalTest

would result in "This is the second class" being displayed on the console.

What happens if we want to have instances of both A classes in use at the same time? Normally we cannot do that, but if we use ClassLoaders we can.

//: Loader.java

import java.net.*;
public class Loader {
  public static void main(String[] args) throws Exception {
    ClassLoader a1 = new URLClassLoader(
	new URL[] {new URL("file:a1/")}, null);
    ClassLoader a2 = new URLClassLoader(
	new URL[] {new URL("file:a2/")}, null);
    Class c1 = a1.loadClass("A");
    Class c2 = a2.loadClass("A");
    System.out.println("c1.toString(): " + c1);
    System.out.println("c2.toString(): " + c2);
    System.out.println("c1.equals(c2): " + c1.equals(c2));
    System.out.println("c1.newInstance(): " + c1.newInstance());
    System.out.println("c2.newInstance(): " + c2.newInstance());
  }
}

The two classes, both called "A", are loaded with different ClassLoader objects, and are thus, as far as the VM is concerned, different classes altogether. We can print the names of the classes, compare the two classes (even though their names are the same, the classes are not equal, you should therefore never compare just the class names if you want to compare classes, rather use the Class.equals() method), and make instances of them by calling the newInstance() method.

The output if we run Loader is:

c1.toString(): class A
c2.toString(): class A
c1.equals(c2): false
c1.newInstance(): This is the first class
c2.newInstance(): This is the second class

We can also let these two "A" classes have a common superclass. For example, say we have a superclass called Parent.java located in the root directory:

//: Parent.java
public class Parent {
  public String toString() {
    return "Thanks for caring... but what do you want??? ";
  }
}

And our A.java classes are now written as:

//: a1/A.java
public class A extends Parent {
  public String toString() {
    return super.toString() + "This is the first class";
  }
}

//: a2/A.java
public class A extends Parent {
  public String toString() {
    return super.toString() + "This is the second class";
  }
}

We then need to have a common parent ClassLoader which we use to load the Parent.class file. We have to specify the location to start looking for Parent.class, and the locations are searched in a hierarchical fasion. Note that the compile-time Parent class is loaded with a different ClassLoader to the one loaded with the URLClassLoader called "parent" so they refer to a different class altogether, which means we cannot type-cast an instance of "A" to a Parent. Also, if we load the class "Parent" without using the classloader, we will see that it is not equal to the superclass of "c1".

//: Loader.java
import java.net.*;
public class Loader {
  public static void main(String[] args) throws Exception {
    ClassLoader parent = new URLClassLoader(
	new URL[] {new URL("file:./")}, null);
    ClassLoader a1 = new URLClassLoader(
	new URL[] {new URL("file:a1/")}, parent);
    ClassLoader a2 = new URLClassLoader(
	new URL[] {new URL("file:a2/")}, parent);
    Class c1 = a1.loadClass("A");
    Class c2 = a2.loadClass("A");
    System.out.println(c1.newInstance());
    System.out.println(c2.newInstance());
    System.out.println(
	c1.getSuperclass().equals(c2.getSuperclass()));
    System.out.println(
	Class.forName("Parent").equals(c1.getSuperclass()));
    try {
	Parent p = (Parent)c1.newInstance();
    } catch(ClassCastException ex) {
	ex.printStackTrace();
    }
    System.out.println("We expected to get ClassCastException");
  }
}

Thanks for caring... but what do you want??? This is the first class
Thanks for caring... but what do you want??? This is the second class
true
false
java.lang.ClassCastException: A
        at Loader.main(Loader.java:1Cool
We expected to get ClassCastException

Note that the super classes of both "A" classes are equal.

Where is this all this useful? It is very useful when you have an application server into which you want to deploy business objects written by different people. It is entirely feasible that you have two developers with different versions of classes deploying their applications onto the same server. You don't necessarily want to start a new VM for each deployment, and so with ClassLoaders it is possible to have lots of classes with the same name running in the same memory space but not conflicting with one another. They would also share the common JDK classes with one another, so we would not have to have a java.util.ArrayList class loaded for each of the ClassLoaders.

Until next week, and please remember to forward this newsletter in its entirety to as many Java users as you know who would be interested.

Heinz


Copyright 2000-2004 Maximum Solutions, South Africa

Reprint Rights. Copyright subsists in all the material included in this email, but you may freely share the entire email with anyone you feel may be interested, and you may reprint excerpts both online and offline provided that you acknowledge the source as follows: This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please contact Maximum Solutions for more information.

Java and Sun are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Maximum Solutions is independent of Sun Microsystems, Inc.

 Printer Friendly Page  Printer Friendly Page
 Send to a Friend  Send to a Friend

.. Bookmark and Share

Search here again if you need more info!
Custom Search



Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy