• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Tim Cooke
  • Devaka Cooray
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Rob Spoor
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
Bartenders:
  • Carey Brown
  • Roland Mueller

ClassCastException in Custom class loader

 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Bartender
Posts: 5167
11
Netbeans IDE Opera Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Abhishek Lodha
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for your answers I will try not putting the class in the classpath.
 
Abhishek Lodha
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


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
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Now I am super curious what sports would be like if we allowed drugs and tiny ads.
We need your help - Coderanch server fundraiser
https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
reply
    Bookmark Topic Watch Topic
  • New Topic