Why does this throw a ClassCastException?

Discussion in 'Java' started by Robert Paris, Feb 17, 2004.

  1. Robert Paris

    Robert Paris Guest

    I have installed my ClassLoader as the System classloader (using
    -Djava.system.class.loader). My ClassLoader extends URLClassLoader. In
    the constructor (the only one called by the bootclasspath loader is:
    YourClassLoader(ClassLoader parent) ) I call super(URL[] urls,
    ClassLoader parent) by passing it like so:
    Code:
    MyClassLoader(ClassLoader parent)
    {
    super( classPathURLS, parent );
    }
    
    When I do the above, I get a class cast exception when I try to cast a
    class that a class loader instance (in the program below) created to
    an interface that my class loader defined.
    Code:
    public Doable load()
    {
    URLClassLoader uc = new URLClassLoader( someURLNotOnClassPath
    );
    Class c = uc.loadClass( "com.something.Test" );
    
    /*
    * This cast only throws an exception if my system classloader
    * passes "parent" to the constructor of "super." If I instead
    * do the following: "super( classPathURLS, null );" then I
    * never get a ClassCastException. Does anyone know why this
    is?
    */
    return ( Doable ) c.newInstance();
    }
    
    Just to give some more information on the problem: in both cases
    (passing "parent" to "super()" and passing "null" to "super()"), the
    ClassLoader of the "Doable" class is always MyClassLoader. Also, I
    have logging in every method called (when an attempt is made to load
    or find a class) and it is called for Doable only once - whereupon I
    define and load the class.

    I'm sure I am doing something wrong, but I'm not sure what. Does
    anyone have any idea what it might be?
    Robert Paris, Feb 17, 2004
    #1
    1. Advertising

  2. Robert Paris

    Anton Spaans Guest

    "Robert Paris" <> wrote in message
    news:...
    > I have installed my ClassLoader as the System classloader (using
    > -Djava.system.class.loader). My ClassLoader extends URLClassLoader. In
    > the constructor (the only one called by the bootclasspath loader is:
    > YourClassLoader(ClassLoader parent) ) I call super(URL[] urls,
    > ClassLoader parent) by passing it like so:
    >
    Code:
    >     MyClassLoader(ClassLoader parent)
    >     {
    >         super( classPathURLS, parent );
    >     }
    > 
    > When I do the above, I get a class cast exception when I try to cast a
    > class that a class loader instance (in the program below) created to
    > an interface that my class loader defined.
    >
    Code:
    >     public Doable load()
    >     {
    >         URLClassLoader uc = new URLClassLoader( someURLNotOnClassPath
    > );
    >         Class c = uc.loadClass( "com.something.Test" );
    >
    >         /*
    >          * This cast only throws an exception if my system classloader
    >          * passes "parent" to the constructor of "super." If I instead
    >          * do the following: "super( classPathURLS, null );" then I
    >          * never get a ClassCastException. Does anyone know why this
    > is?
    >          */
    >         return ( Doable ) c.newInstance();
    >     }
    > 
    > Just to give some more information on the problem: in both cases
    > (passing "parent" to "super()" and passing "null" to "super()"), the
    > ClassLoader of the "Doable" class is always MyClassLoader. Also, I
    > have logging in every method called (when an attempt is made to load
    > or find a class) and it is called for Doable only once - whereupon I
    > define and load the class.
    >
    > I'm sure I am doing something wrong, but I'm not sure what. Does
    > anyone have any idea what it might be?


    Which class loader loaded the class Double() in your example? I assume it
    is the system's classloader?

    Two classes having the same name (fully qualified) but that are loaded by
    two different classloaders can be different. I.e. a class-cast exception may
    be thrown. E.g:

    ClassLoader cl1 = ...;
    ClassLoader cl2 = ...;

    Class klass1 = cl1.loadClass("com.something.Test");
    Class klass2 = cl2.loadClass("com.something.Test");

    Object obj1 = cl1.newInstance();
    Object obj2 = cl1.newInstance();

    Now: obj1 and obj1 are of different types: klass1.equals(klass2) will return
    false.

    In your case, the Double class is probably loaded by the system classloader.
    The instance returned by your call 'c.newInstance()' may *look* as a
    subclass of Double, but it is not, because 'c' is not loaded by the system
    classloader.

    -- Anton Spaans.
    Anton Spaans, Feb 17, 2004
    #2
    1. Advertising

  3. Robert Paris

    Anton Spaans Guest

    "Anton Spaans" <aspaans at(noSPAM) smarttime dot(noSPAM) com> wrote in
    message news:...
    >
    > "Robert Paris" <> wrote in message
    > news:...
    > > I have installed my ClassLoader as the System classloader (using
    > > -Djava.system.class.loader). My ClassLoader extends URLClassLoader. In
    > > the constructor (the only one called by the bootclasspath loader is:
    > > YourClassLoader(ClassLoader parent) ) I call super(URL[] urls,
    > > ClassLoader parent) by passing it like so:
    > >
    Code:
    > >     MyClassLoader(ClassLoader parent)
    > >     {
    > >         super( classPathURLS, parent );
    > >     }
    > > 
    > > When I do the above, I get a class cast exception when I try to cast a
    > > class that a class loader instance (in the program below) created to
    > > an interface that my class loader defined.
    > >
    Code:
    > >     public Doable load()
    > >     {
    > >         URLClassLoader uc = new URLClassLoader( someURLNotOnClassPath
    > > );
    > >         Class c = uc.loadClass( "com.something.Test" );
    > >
    > >         /*
    > >          * This cast only throws an exception if my system classloader
    > >          * passes "parent" to the constructor of "super." If I instead
    > >          * do the following: "super( classPathURLS, null );" then I
    > >          * never get a ClassCastException. Does anyone know why this
    > > is?
    > >          */
    > >         return ( Doable ) c.newInstance();
    > >     }
    > > 
    > > Just to give some more information on the problem: in both cases
    > > (passing "parent" to "super()" and passing "null" to "super()"), the
    > > ClassLoader of the "Doable" class is always MyClassLoader. Also, I
    > > have logging in every method called (when an attempt is made to load
    > > or find a class) and it is called for Doable only once - whereupon I
    > > define and load the class.
    > >
    > > I'm sure I am doing something wrong, but I'm not sure what. Does
    > > anyone have any idea what it might be?

    >
    > Which class loader loaded the class Double() in your example? I assume it
    > is the system's classloader?
    >
    > Two classes having the same name (fully qualified) but that are loaded by
    > two different classloaders can be different. I.e. a class-cast exception

    may
    > be thrown. E.g:
    >
    > ClassLoader cl1 = ...;
    > ClassLoader cl2 = ...;
    >
    > Class klass1 = cl1.loadClass("com.something.Test");
    > Class klass2 = cl2.loadClass("com.something.Test");
    >
    > Object obj1 = cl1.newInstance();
    > Object obj2 = cl1.newInstance();
    >
    > Now: obj1 and obj1 are of different types: klass1.equals(klass2) will

    return
    > false.
    >
    > In your case, the Double class is probably loaded by the system

    classloader.
    > The instance returned by your call 'c.newInstance()' may *look* as a
    > subclass of Double, but it is not, because 'c' is not loaded by the system
    > classloader.
    >
    > -- Anton Spaans.
    >
    >


    Oops.. did not read the last part of your question too well.
    But the idea of my response remains the same:

    MyClassLoader != URLClassLoader

    Try to construct a URLClassLoader whose parent is MyClassLoader.

    URLClassLoader uc = new URLClassLoader( someURLNotOnClassPath,
    myClassLoaderInstance);

    -- Anton.
    Anton Spaans, Feb 17, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kerri
    Replies:
    2
    Views:
    12,976
    Kevin Spencer
    Oct 27, 2003
  2. Jon Maz
    Replies:
    7
    Views:
    4,254
    Jon Maz
    Oct 25, 2004
  3. Replies:
    15
    Views:
    7,454
    Roedy Green
    Sep 8, 2005
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,655
    Smokey Grindel
    Dec 2, 2006
  5. Emanuele D'Arrigo

    To throw or to throw not?

    Emanuele D'Arrigo, Nov 14, 2008, in forum: Python
    Replies:
    6
    Views:
    298
    Emanuele D'Arrigo
    Nov 15, 2008
Loading...

Share This Page