Explanation of ClassCastException in Java
Straight from the API Specifications for the ClassCastException
:
Thrown to indicate that the code has
attempted to cast an object to a
subclass of which it is not an
instance.
So, for example, when one tries to cast an Integer
to a String
, String
is not an subclass of Integer
, so a ClassCastException
will be thrown.
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.
java.lang.ClassCastException
According to the documentation:
Thrown to indicate that the code has attempted to cast an Object
to a subclass
of which it is not an instance. For example, the following code generates a ClassCastException
:
Object x = new Integer(0);
System.out.println((String)x);
What else can throw a ClassCastException in java?
One reason could be that the part of the code inserting the object uses a different classloader than the code retrieving it.
An instance of a class can not be cast to the same class loaded by a different classloader.
Response to the edit:
What would you do if this happened in production?
This generally happens when the reading and inserting modules each include the same jar containing C1
.
Since most containers try the parent classloader first, and then the local classloader (the Parent first strategy), the common solution to the problem is to instead load the class in the closest common parent to the inserting and reading modules.
If you move the module containing the C1
class to the parent module, you force both submodules to get the class from the parent, removing any classloader differences.
Java Socket ClassCast Exception
Please, see the row 20 of the ServidorTCP class.
You can't cast the value that is returned by "getObjectFromByte" method to an "Archivio", because it is not of a compatible type. In particular, it is an Integer.
It happens because the read method of the ObjectInputStream returns an int (See Javadoc).
Why a ClassCastException but not a compilation error?
Why don't I get a compilation error in the code below?
Because the compiler only cares about the static type of the expression you're trying to cast.
Look at these two lines:
BlackInk blackInk = new BlackInk();
printable = (Printable)blackInk;
You know that in the second line, the value blackInk
only refers to an object of type BlackInk
due to the first line, but the compiler doesn't. For all the compiler knows (when compiling the second line) it could actually have been:
BlackInk blackInk = new PrintableBlackInk();
printable = (Printable)blackInk;
... where PrintableBlackInk
is a class extending BlackInk
and implementing Printable
. Therefore it's valid (at compile-time) to cast from an expression of type BlackInk
to Printable
. If you make BlackInk
a final
class, then the compiler knows that there's no way that it will work (unless the value is null) and will fail at compile-time, like this:
error: inconvertible types
printable = (Printable)blackInk;
^
required: Printable
found: BlackInk
The details for this are in JLS 5.5.1.
Otherwise, we have to wait until execution time to see the failure, because the cast is valid at compile-time.
Java inheritance downcast ClassCastException
All B's are A's, by inheritance. But not all A's are B's. This particular instance isn't, hence the runtime exception.
Meaning of java.lang.ClassCastException: someClass incompatible with someClass
Philippe Riand explaned this by email:
This class cast happens because the same class had been loaded twice by 2 different class loaders. Thus, from a Java standpoint, they are different and the cast fails.
Now, each XPages application is having its own classloader. But this class loader is discarded each time a design change happens to the application, through Domino Designer for example. This is required as a change to an XPages generates a new Java class that should then be loaded instead of the previous one. When this happens, the classloader is discarded and a new is created. Then all the application related classes are reloaded, as they are needed, even though they didn't change.This is a common behavior implemented by J2EE servers.
That said, if your code is caching an object in a scope that is not discarded when a design change occurs, then this is likely to happen. For example, the applicationScope & sessionScope are currently not discarded when a design change happens, which might lead to this problem. This was a design choice as discarding the scopes sometimes provides a bad developer experience, but with this drawback.Finally, saving faces-config.xml works as a workaround. When this file is saved, then the entire module is discarded from memory, including the scopes, This explains why it works. Making a change to your custom Java class should reload the module and remove the issue.
So it seems putting beans (even indirectly) into sessionScope or applicationScope is the cause.
Related Topics
How to Style the Progressbar Component in Javafx
How to Fix 'Android.Os.Networkonmainthread
exception'
Json Array Iteration in Android/Java
Running Code in Main Thread from Another Thread
How to Use an Existing Database With an Android Application
How to Check Internet Access on Android? Inetaddress Never Times Out
What Is a Stringindexoutofboundsexception - How to Fix It
How to Discover Memory Usage of My Application in Android
Android.Content.Res.Resources$Notfoundexception: String Resource Id #0X0
How to Call a Soap Web Service on Android
Broadcast Receiver For Checking Internet Connection in Android App
How to Write Files to External Public Storage in Android So That They Are Visible from Windows
Fast Bitmap Blur For Android Sdk
Showing Firebase Data in Listview
Recommendations For a Heap Analysis Tool For Java
Why Are Integer Literals With Leading Zeroes Interpreted Strangely