wood burning stoves*
The moose likes Java in General and the fly likes ClassCastException in Custom class loader Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "ClassCastException in Custom class loader" Watch "ClassCastException in Custom class loader" New topic
Author

ClassCastException in Custom class loader

Abhishek Lodha
Greenhorn

Joined: Sep 23, 2012
Posts: 8
1.
I have created a custom class loder.

ClassLoaderDemo ccl = new ClassLoaderDemo(); //assume it is working fine
Class clas = ccl.loadClass( "com.MyObject" );

com.MyObjectSuperClass o1 = (com.MyObjectSuperClass)clas.newInstance(); //MyObjectSuperClass is super class of MyObject

Now I want to cast the loaded object to MyObjectSuperClass which is super class if MyObject. But I am getting the following exception

Exception in thread "main" java.lang.ClassCastException: com.MyObject cannot be cast to com.MyObjectSuperClass

2.
Object o = ccl.loadClass( "com.MyObject" ).newInstance();
SOP(o.getClass().getClassLoader()); //This statement returns my custom class loader as excpected.

but

SOP(MyObject.class.getClassLoader()); //This return system class loader Why? when this class has already been loaded by my custom class loader.

Please help.
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14114
    
  16

It's a long time ago since I did things with custom classloaders, but...:

Every classloader has its own "space" of classes. Classes loaded by different classloaders are completely separate. You can load some class "MyObject" using the system classloader, and using your own custom classloader, and then you'd have to classes named "MyObject" that are different - if you'd assign an object from one "MyObject" to a variable of the other "MyObject", you'd get an exception.

What happens in your application is that you've loaded MyObject using your own custom classloader, but the superclass MyObjectSuperClass has been loaded with the system classloader. Since they are loaded with different classloaders, MyObjectSuperClass is not seen as the superclass of MyObject.

Abhishek Lodha wrote:SOP(MyObject.class.getClassLoader()); //This return system class loader Why? when this class has already been loaded by my custom class loader.

It doesn't work like that. Java doesn't keep a single list of loaded classes; every classloader has its own list. If you use "MyObject" literally in your source code like this, it will be loaded by the system classloader. It's not going to use the MyObject loaded by your own custom classloader.

Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Here's an example. Note that in order for your class to be loaded by your classloader, that class cannot be on the classpath, else it will be picked up by the System classloader.


Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Abhishek Lodha wrote:
SOP(MyObject.class.getClassLoader()); //This return system class loader Why? when this class has already been loaded by my custom class loader.


MyObject is on your classpath, so the your classloader delegates up to the System classloader to load it. Any class to be loaded by your classloader must NOT be in your classpath.
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4530
    
    5

Abhishek, please BeForthrightWhenCrossPostingToOtherSites
http://www.java-forums.org/new-java/63223-classcastexception-custom-class-loader.html
https://forums.oracle.com/forums/thread.jspa?threadID=2441792


luck, db
There are no new questions, but there may be new answers.
Abhishek Lodha
Greenhorn

Joined: Sep 23, 2012
Posts: 8
Thanks for your answers I will try not putting the class in the classpath.
Abhishek Lodha
Greenhorn

Joined: Sep 23, 2012
Posts: 8
I need some more help

1.
We say that a class is loaded only once by system classloader.

Create any random Object and then get the system class loader from this object.

AnyClass obj = new AnyClass; //This class will be loaded by system class loader.

ClassLoader cl = obj.getClass().getClassLoader(); //getting the system class loader.

cl.loadClass("AnyClass"); // changing the AnyClass.class and reloading it.

This way we can reload a class using system class loader.

2.
We also say that we that custom classes are used to load a class whose contents are dynamically generated.
This thing we can do from system class as well. loading the contents to class file and loading that class file using above method.

cl.loadClass("dynamicClass");

Thanks
Abhishek Lodha
Greenhorn

Joined: Sep 23, 2012
Posts: 8
Jeff Verdegan wrote:
Abhishek Lodha wrote:
SOP(MyObject.class.getClassLoader()); //This return system class loader Why? when this class has already been loaded by my custom class loader.


MyObject is on your classpath, so the your classloader delegates up to the System classloader to load it. Any class to be loaded by your classloader must NOT be in your classpath.


MyObject is in classpath but I am overriding the default way classloaders are created. I am not delegating the request to load the class system class loader but I am loading it from my classloader.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Abhishek Lodha wrote:
MyObject is in classpath but I am overriding the default way classloaders are created. I am not delegating the request to load the class system class loader but I am loading it from my classloader.


Note that the right way to think about a type in Java is as a [ClassLoader,Class] pair. If the same Class is loaded by two different ClassLoaders, then they are two different types (as has already been pointed out.)

Anyway, I suspect that what I quoted above is exactly the problem. If your classloader is not delegating to the system classloader, then it is probably loading its own version of MyObjectSuperClass. Your MyObject class extends [YourClassLoader:MyObjectSuperClass], and you're trying to cast to [SystemClassLoader:MyObjectSuperClass], which is a different type, so the cast is illegal. You need to modify your classloader to properly delegate to the system classloader.


[Jess in Action][AskingGoodQuestions]
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Abhishek Lodha wrote:
Jeff Verdegan wrote:
Abhishek Lodha wrote:
SOP(MyObject.class.getClassLoader()); //This return system class loader Why? when this class has already been loaded by my custom class loader.



Presumably calling loadClass() on an already loaded class does nothing.

[quuote]
MyObject is on your classpath, so the your classloader delegates up to the System classloader to load it. Any class to be loaded by your classloader must NOT be in your classpath.


MyObject is in classpath but I am overriding the default way classloaders are created. I am not delegating the request to load the class system class loader but I am loading it from my classloader.

Oops, my bad. If you wrote your own classloader, then, as EFH points out, the problem is likely the opposite of what I assumed--namely, that it's not delegating when it should be, but you've written code that assumes it is.

Is there any particular reason you wrote your own classloader, rather than simply using URLClassLoader?
Abhishek Lodha
Greenhorn

Joined: Sep 23, 2012
Posts: 8

Is there any particular reason you wrote your own classloader, rather than simply using URLClassLoader?


Just wanted to learn how class loader works that's why I dont want to use URLClass Loader.

My requirement is
Load MyObject class using custom class loader and cast it to its superclass(MySuperObjectClass).

Here is what I understood from the above replies.

let MyObject class not be in the classpath and let its superclass be in the classpath. This way MyObject will be loaded by custom class loader and superclass(MySuperObjectClass) will be loaded by system class loader. This way will I be able to cast?
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Abhishek Lodha wrote:
let MyObject class not be in the classpath and let its superclass be in the classpath. This way MyObject will be loaded by custom class loader and superclass(MySuperObjectClass) will be loaded by system class loader. This way will I be able to cast?


That is correct, if your classloader properly delegates to the system class loader.
Abhishek Lodha
Greenhorn

Joined: Sep 23, 2012
Posts: 8
Ernest Friedman-Hill wrote:
Abhishek Lodha wrote:
let MyObject class not be in the classpath and let its superclass be in the classpath. This way MyObject will be loaded by custom class loader and superclass(MySuperObjectClass) will be loaded by system class loader. This way will I be able to cast?


That is correct, if your classloader properly delegates to the system class loader.


Thanks a lot. I got the point now.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: ClassCastException in Custom class loader