aspose file tools*
The moose likes Java in General and the fly likes ClassCastException Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "ClassCastException" Watch "ClassCastException" New topic
Author

ClassCastException

Garrett Smith
Ranch Hand

Joined: Jun 27, 2002
Posts: 401
I don't understand how this code:

can produce the following error:

But it happens every time.


comp.lang.javascript FAQ: http://jibbering.com/faq/
Ron Newman
Ranch Hand

Joined: Jun 06, 2002
Posts: 1056
What should it be doing? Since you haven't shown us Mailer.java, I can't tell whether the error message is correct or not.
Is there more than one class called Session, in different namespaces?


Ron Newman - SCJP 1.2 (100%, 7 August 2002)
Garrett Smith
Ranch Hand

Joined: Jun 27, 2002
Posts: 401
Namespaces are a likely cause, but I don't think that's what's happening.
java.lang.ClassCastException: envCtx.lookup(Mailer.url).class = javax.mail.Session
is
I do not see what possible difference it would make to look at Mailer.java. If I were to show you that file, you'd want to see FileFormatter.java, a package-private helper class. Then we would come back to look at the origin of the problem.
I'll try to remove any vagueness by being more explicit.
I got a ClassCastException trying to cast an object of type Session to an object of type Session. [b]How is that possible?

Mailer.java

[ October 25, 2002: Message edited by: Garrett Smith ]
[ October 25, 2002: Message edited by: Garrett Smith ]
Dave Landers
Ranch Hand

Joined: Jul 24, 2002
Posts: 401
Originally posted by Garrett Smith:

I got a ClassCastException trying to cast an object of type Session to an object of type Session. [b]How is that possible?

If the two classes were loaded by different ClassLoaders.
Garrett Smith
Ranch Hand

Joined: Jun 27, 2002
Posts: 401
So what if they are? What can I do about it?
I can call getClassLoader() the Object from ctxEnv, but what about javax.mail.Session session;? It's null, so it doesn't have a ClassLoader, right?
What could I do to investigate this further? Can you think of a strategy to usurp this unknown problem? What is really the best way to approach the situation?
Dave Landers
Ranch Hand

Joined: Jul 24, 2002
Posts: 401
Try comparing the class instances for the two objects - if they are not the same they can not be cast. You can also compare the ClassLoaders.

That should give you an idea of what is going on.
Anything that is in CLASSPATH should show up in the default system classloader - ClassLoader.getSystemClassLoader(). It should be something like com.sun.Launcher$AppClassLoader (I forget exactly - that's probably the wrong class name, but its close).
You might have in your system a pair of "peer" classloaders - two that are children of the system CL but not parent/child of each other. If a class is loaded by each of these two CLs, it is not actually the same class.
Normally, when someone writes a custom ClassLoader, it is supposed to delegate to its parent (and eventually the parent) to load classes and prevent this situation - so if the mail package is in your CLASSPATH then this should not happen.
Guesswork starts here:
It is possible that the implementation of JNDI you are using has loaded the Session class from the server or something. It should have looked and seen that Session was available and used that class. But maybe there is some version mismatch in the two classes and it determined that it could not serialize the object into whatever Session version you have. Or maybe its ClassLoader is broken and not delegating to the parent.
Or it could be that your code and thus your Session is loaded in one ClassLoader that the JNDI context can not see, so it loads a new Session object.
:end guesswork
These can be really difficult to diagnose, especially if you are running code in a server or something and really don't always know about the classloader architecture.
Let's see what the Class instance and ClassLoader println stuff looks like.
Also, what environment are you running this: From a main() method? Or from EJB or Servlet? ?
Garrett Smith
Ranch Hand

Joined: Jun 27, 2002
Posts: 401


[ October 26, 2002: Message edited by: Garrett Smith ]
Dave Landers
Ranch Hand

Joined: Jul 24, 2002
Posts: 401
So your Session is from the java ext classloader, which means its in some jar in <java>/jre/lib/ext directory somewhere.
And the other one is some Tomcat classloader. I see Tomcat at least has a helpful toString on their ClassLoader. Looks like it has loaded javax.mail but that's weird since it is available in your jre/lib/ext. Maybe their classloader is not delegating to the system classloader like its supposed to when loading that class.
But what I can't understand - if it is doing that then why didn't your jsp page behave the same way? Seems it should have loaded things the same way.
I wonder what "this.getClass().getClassLoader()" says (where this would be the jsp object)?.

Try taking the jar containing javax.mail (mail.jar?) out of your jre/lib/ext directory and that might trigger your jsp page to use the one that is evidently being provided by Tomcat.
I'd tag this a Tomcat bug, or maybe they'd consider it a "feature". (You can loose hours of your life trying to figure out such "features")
Garrett Smith
Ranch Hand

Joined: Jun 27, 2002
Posts: 401

But what I can't understand - if it is doing that then why didn't your jsp page behave the same way? Seems it should have loaded things the same way.

Yeh, good question.

I wonder what "this.getClass().getClassLoader()" says (where this would be the jsp object)?

jspPage.getClass().getClassLoader() =
org.apache.jasper.servlet.JasperLoader@7e0fac

Following your advice, I deleted mail.jar (and activation.jar) from lib/ext and rebooted my machine. The only jars left in lib/ext are whatever came with the os.
Session.class.getClassLoader is still WebappClassLoader (see above). Is that right?
While my project is disabled, I'll be reading up on classloader. What next?
[ October 26, 2002: Message edited by: Garrett Smith ]
Dave Landers
Ranch Hand

Joined: Jul 24, 2002
Posts: 401
I'm not familar with Tomcat, but I'd say its time to bounce this one off one of their support or user forums. Good luck.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Garret,
are you sure that the Exception isn't thrown somewhere *inside* the lookup method? (I didn't follow this thread closely, just noticed that your code seems to lose information about the original cause of the exception...)


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Garrett Smith
Ranch Hand

Joined: Jun 27, 2002
Posts: 401
If it were only so simple...

I have removed mail.jar from my classpath and I have the same problem. I don't see how Ant can even compile. This is getting very strange.
I'd like to know where the class is being read from.
After that, I want to know why WebappClassLoader does not delegate to its parent, StandardClassLoader.
Dave Landers
Ranch Hand

Joined: Jul 24, 2002
Posts: 401
Originally posted by Garrett Smith:
I don't see how Ant can even compile. This is getting very strange.

ClassLoader problems are always strange, especially when they involve somebody else's code (so you are left with dealing with the wreckage).
Note that compile and runtime are very different in this case. As long as the compiler can find a class you reference (Session), and it sees that the cast could be possible, it'll do it. It is compiling for the same reason you are saying "why won't this run - it looks OK". What happens at runtime is a completely different story, as you are discovering....
Garrett Smith
Ranch Hand

Joined: Jun 27, 2002
Posts: 401
Is there a way to see where the compiler has found classes (jars, et c.). Where is mail.jar found?
Perhaps mail.jar is "conveniently" repackaged in another jar. Could this cause such an error?
I have a strange problem; I don't know how to best approach debugging it.
Dave Landers
Ranch Hand

Joined: Jul 24, 2002
Posts: 401
There is not a general way to make this query. Some ClassLoaders might have internal methods to let you do this, but it is not in the base ClassLoader.
I have a thing that I use from the command line, but it only knows about normal stuff in CLASSPATH, lib/ext, etc. It would tell you where the compiler might find stuff, but it wouldn't help you for your runtime problem.
Garrett Smith
Ranch Hand

Joined: Jun 27, 2002
Posts: 401
I found where mail.jar was: inside googleapi.jar. I had surmised a case like this, but did not investigate googleapi.jar. Sitting in front of my computer that much was literally a pain in the ass.
I got a page from Steve on the ant user group mailing list (co-author of Java Development with Ant). In case anyone else has such problem, here's the page.

Thanks for pointing me in the right direction, Dave.
Tthanks to Steve for making this great page.
[ October 29, 2002: Message edited by: Garrett Smith ]
Carlos Conti
Ranch Hand

Joined: Apr 21, 2010
Posts: 114
wow! thanks Garret for your post!
I have been delaying this issue for months now, until I found your post and the jsp page, which together with your explanation clued me out. Had exactly the same problem. I had another library which provided the mail package which was of a different version than the one stored in the Apache lib folder. Modifed the jar and voila!

Many many thanks man. You made a man happy today!
Congrats!
Carlos.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: ClassCastException