Getting Class Cast Exception Where Both Classes Are Exactly the Same

Getting class cast exception where both classes are exactly the same

This happens when two different ClassLoader objects load classes with the same name. The equality of two classes in Java depends on the fully qualified name and the class loader that loaded it.

So if two independent class loaders load classes from the same location, then objects of those types will not be able to be cast to each others type, even if their classes are called the same.

ClassCastException from exact same class

It looks like you have 2 ClassLoaders involved. You can check the classloaders with

Customer.class.getClassLoader();

em.createNamedQuery("Customer.findByEmail").setParameter("email", user).getSingleResult().getClass().getClassLoader();

Then you can try to find more information.

ClassCastException when casting to the same class

I am not quite following your description of the program flow, but usually when you get ClassCastExceptions you cannot explain you have loaded the class with one classloader then try to cast it to the same class loaded by another classloader. This will not work - they are represented by two different Class objects inside the JVM and the cast will fail.

There is an article about classloading in WebSphere. I cannot say how it applies to your application, but there are a number of possible solutions. I can think of at least:

  1. Change the context class loader manually. Requires that you can actually get a reference to an appropriate class loader, which may not be possible in your case.

    Thread.currentThread().setContextClassLoader(...);
  2. Make sure the class is loaded by a class loader higher in the hierarchy.

  3. Serialize and deserialize the object. (Yuck!)

There is probably a more appropriate way for your particular situation though.

Spring Boot App. running with Intellij leads to ClassCastException on the same classes

This is happening because spring-boot-devtools has a class loader, but IntelliJ has it's own class loader. Removing spring-boot-devtools from pom.xml solved this for me.
Also you can just remove it from the libraries list in your project:

Project Settings -> Libraries -> find spring-boot-devtools -> delete

Java ClassCastException with two identical classes in different packages, sent over the network

When you declare two classes with the same name in different packages, they are fundamentally different classes. That is why you are getting the exception when you attempt to cast from one type to the other.

The problem is that i cannot put the client package to the server or vice versa.

There is no way you can convince the Java type system that the two classes are the same. They are different.

The simplest solution is to create a third package that contains the classes that are needed on both the client and server side. Put the common package (or packages) into a JAR file, and add it to the classpath on the client and server sides.

There are other alternatives such as:

  • using a different marshalling / unmarshalling mechanism (JSON, XML, custom), or

  • using the available hooks in the Java serialization library to translate types (see @EJP's answer),

but (to mind) this problem is down to a design mistake, and the best approach is to fix that mistake soon rather than papering over it.

If you are passing objects from a java client to a java server via Java serialization, then you should be using the same classes on both sides. If that is not possible for a sound technical reason (as distinct from a design mistake), then that is most likely a good reason NOT to use Java serialization.


To answer your "real" questions:

Q: Can i determine the type of the class without importing the Package class from the package (client / server)?

Strictly yes, but it won't help you.

  • You can refer to a class by its fully qualified name; e.g.

    if (o instanceof com.acme.WeaselTrap)
  • You can get the actual type's Class object.

    Class<?> clazz = o.getClass();

But once you have gotten there, you still have the issue that the two types with the same names in different packages are fundamentally different.

(Of course, if your code can cope with the classes being different, you could make your life simpler by changing the class names so that the simple names are different.)

Q: Or is there a possibility to send the Object over the network without class information ?

Not using Java serialization.

ClassCastException occurs while trying to deserialize the serialized object

Your 2 User classes are not the same, they are in different packages. The exception message is telling you this: serialization.serialize.User is a different class than serialization.deSerialize.User.

Using "default" binary serialization as you are, the class being deserialized into must be the exact same as the original object that was serialized. Even though your 2 User classes have the same structure, they are not compatible as far as serialization goes.

The simplest solution is to use the same User class for both serialization and deserialization. If you must serialize one class and deserialize into a different class, I suggest you use a different form for the serialization, such as JSON. The Jackson library makes this easy to do, and you can have different classes.

It's also possible you could override writeObject() and readObject() methods to achieve this, but I'm not certain it will work with binary serialization.



Related Topics



Leave a reply



Submit