ClassCastException when it should work anyway

J

Jimi Hullegård

Is there a way to avoid a ClassCastException when there is no real changes
made to the class, but the java-file has been compiled anyway?

I'm writing a J2ee web application, and I store a HashMap of User objects as
an attribute in the servlet context. Now, if the User class gets recompiled
(no changes has been made in the code), I get a ClassCastException when I
try to fetch an User from the HashMap.

Code:
Map<Integer, User> onlineUsers = (Map<Integer,
User>)servletContext.getAttribute("onlineUsers");
User user = onlineUsers.get(new Integer(memberId)); <--- this throws a
ClassCastException

But if I don't do "User user = ..." and just prints the object returned, the
it clearly IS a User object, because printout is something like
community.login.User@861f24

So is there a way to "Cast" an object between two classes that actually are
the SAME class, but different versions (I guess)?

/Jimi
 
C

Chris Smith

Jimi Hullegård said:
I'm writing a J2ee web application, and I store a HashMap of User objectsas
an attribute in the servlet context. Now, if the User class gets recompiled
(no changes has been made in the code), I get a ClassCastException when I
try to fetch an User from the HashMap.

Code:
Map<Integer, User> onlineUsers = (Map<Integer,
User>)servletContext.getAttribute("onlineUsers");
User user = onlineUsers.get(new Integer(memberId)); <--- this throws a
ClassCastException

But if I don't do "User user = ..." and just prints the object returned, the
it clearly IS a User object, because printout is something like
community.login.User@861f24

So is there a way to "Cast" an object between two classes that actually are
the SAME class, but different versions (I guess)?

Short answer: no.

A class in Java is identified by two pieces of information, a fully
qualified class name and a class loader. Each class loader effectively
defines its own class namespace, so that even if two classes have
exactly the same fully qualified name ("community.login.User") for
example, if they were loaded by different class loaders then they are
still not the same.

Since a class of the given name has already been loaded by your servlet
container, I suppose it's deciding to create a new class loader to load
the new class. I think that's a very poor idea, but unless you switch
servlet containers there isn't anything you can do about it. (An
alternative which is implemented by other containers is to actually
serialize all the session and application-scope state out to a file,
reload the entire application, and read it back in. Tomcat can do that,
for example.)

Is changing servlet containers an option? What container are you using
now?

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

Jimi Hullegård

Chris said:
Short answer: no.

A class in Java is identified by two pieces of information, a fully
qualified class name and a class loader. Each class loader
effectively defines its own class namespace, so that even if two
classes have
exactly the same fully qualified name ("community.login.User") for
example, if they were loaded by different class loaders then they are
still not the same.

Thank your for that clear and straight answer. I think I understand now.
Is changing servlet containers an option? What container are you
using now?

I'm using Orion (www.orionserver.com). And though changing servlet container
is possible, I would prefer not to have to go thr through that hassle.

But I'm starting to think that I should focus on the main problem, and maybe
you can help me with that?
Because the thing is, I'm having problems registering logouts on a community
I'm building (a test site, at the moment). Everything works when the logged
in user clicks on logout, and when when a regular time out happens. But if I
for instance recompile the servlet when orion is running, or make some
changes in some xml-file, then then _some_ users get logged out completely
(which is OK), while others not get logged out completely (logout time not
written to the database).
So I would like to write a function that runs every five minutes (or
whatever) and goes thrue all active sessions, retrieves the corresponding
user object, and compares the the ones who is logged in according to the
database.
But the thing is I can't find any way to get hold of all active sessions. I
have looked everywhere... Any ideas?

Regards
/Jimi
 
D

daleerwin

I'm not really sure, but I had a similar situation with a J2SE
application, and I'll tell you what happened:

I was putting ScoreObject objects on a Vector from two different
locations. In one place the instances were built from data entered by
the user and in the other place they were built from data fread from a
database. Then the paintComponent() method used this Vector to repaint
the screen. When the paintComponent() method read the Vector, the
objects built from user-data had no problem, but the objects built from
database data began to throw this exception and did it consistently
thereafter.

I tried lots of things, but finally I first tested the object on the
Vector with the "instanceof" keyword for that class and if it returned
true, then I did the Cast. All of the objects now get drawn, and it
hasn't thrown that exception since.

YMMV
 
R

Ross Bamford

Thank your for that clear and straight answer. I think I understand now.


I'm using Orion (www.orionserver.com). And though changing servlet container
is possible, I would prefer not to have to go thr through that hassle.

But I'm starting to think that I should focus on the main problem, and maybe
you can help me with that?
Because the thing is, I'm having problems registering logouts on a community
I'm building (a test site, at the moment). Everything works when the logged
in user clicks on logout, and when when a regular time out happens. But if I
for instance recompile the servlet when orion is running, or make some
changes in some xml-file, then then _some_ users get logged out completely
(which is OK), while others not get logged out completely (logout time not
written to the database).
So I would like to write a function that runs every five minutes (or
whatever) and goes thrue all active sessions, retrieves the corresponding
user object, and compares the the ones who is logged in according to the
database.
But the thing is I can't find any way to get hold of all active sessions.I
have looked everywhere... Any ideas?

You're confusing your container with running changes. Do this with a
development machine in particular circumstances *if you must* but not
ever with a production machine.

Imagine you write a program that includes all kinds of complex class
manipulation stuff to make sure that the right classes are available at
the right time. You have multiple boxes for your classes, and use clever
stuff like lazy init and bytecode caching. It'll all work transparently,
since the bytecode will be the same no matter which box loads it,
right?

Until someone changes the bytecode after the caches have started to fill
up.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top