ClassNotFoundException when deserializing the contents of a binary class file

I do not know much about Java. I am trying to read a file containing int and various instances of a class called "Car". However, when I deserialize it, the program throws a ClassNotFoundException, and I don’t understand why.

Here is the code:

try { FileInputStream fin = new FileInputStream(inputFile); ObjectInputStream input = new ObjectInputStream(fin); conto = input.readInt(); Automobile[] macchine = new Automobile[conto]; for(int i = 0; i < conto; i++) { macchine[i] = (Automobile)input.readObject(); } String targa; System.out.print("\nInserire le cifre di una targa per rintracciare l'automobile: "); targa = sc1.nextLine(); for(int i = 0; i < conto; i++) { if(macchine[i].getTarga().equals(targa)) System.out.println(macchine[i]); } } catch(IOException e) { System.out.println("Errore nella lettura del file "+inputFile); } catch(java.lang.ClassNotFoundException e) { System.out.println("Class not found"); } 

Thanks in advance.

EDIT: here is stacktrace

 java.lang.ClassNotFoundException: es4.Automobile at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:248) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:604) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1575) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) at es4p2.Main.main(Main.java:35) 
+4
source share
7 answers

When deserializing a serialized tree of objects, the classes of all objects must be in the class path. In this context, a ClassNotFoundException most likely means that one of the classes that is not required is not in the classpath. You must solve this problem for deserialization.

In this case, es4.Automobile missing.


Could the problem be caused by a special exception that I made that was launched by Automobile?

The only other possibilities that I can think of are as follows:

  • es4.Automobile is directly or indirectly dependent on some other class that is missing
  • static initialization of es4.Automobile or a dependent class raised an exception that was not detected inside the class.

But both of them should (I think) lead to a different stack trace.


I just noticed that the package name is es4p2, not es4. Why does it say es4? Maybe because the program that saves the file uses a different package name?

I have no idea why they are different. You will need to talk to the person who wrote the code / created the serialized objects. However, this is most likely the cause of your problem. A class with a different package name is a different class. Period.


You should always pop up (or, better, register) the stack when an unexpected exception occurs. This will tell you (and us) more about what went wrong, in which case the class name is missing.

+8
source

This usually happens if your Automobile class is not in the path of the runtime.

+1
source

This is an old question, but it may help someone else. I ran into the same problem and the problem was that I did not use the current thread class loader. Below you will find the serializer class that I used in the grails project should be easy enough to use in java Hope this helps

 public final class Serializer<T> { /** * Converts an Object to a byte array. * * @param object, the Object to serialize. * @return, the byte array that stores the serialized object. */ public static byte[] serialize(T object) { ByteArrayOutputStream bos = new ByteArrayOutputStream() ObjectOutput out = null try { out = new ObjectOutputStream(bos) out.writeObject(object) byte[] byteArray = bos.toByteArray() return byteArray } catch (IOException e) { e.printStackTrace() return null } finally { try { if (out != null) out.close() } catch (IOException ex) { ex.printStackTrace() return null } try { bos.close() } catch (IOException ex) { ex.printStackTrace() return null } } } /** * Converts a byte array to an Object. * * @param byteArray, a byte array that represents a serialized Object. * @return, an instance of the Object class. */ public static Object deserialize(byte[] byteArray) { ByteArrayInputStream bis = new ByteArrayInputStream(byteArray) ObjectInput input = null try { input = new ObjectInputStream(bis){ @Override protected Class<?> resolveClass(final ObjectStreamClass desc) throws IOException, ClassNotFoundException { ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (cl == null) return super.resolveClass(desc); return Class.forName(desc.getName(), false, cl); } }; Object o = input.readObject() return o } catch (ClassNotFoundException | IOException e) { e.printStackTrace() return null } finally { try { bis.close() } catch (IOException ex) { } try { if (input != null) input.close() } catch (IOException ex) { ex.printStackTrace() return null } } } 
+1
source

Does your Automobile class have such a field?

 private static final long serialVersionUID = 140605814607823206L; // some unique number 

If not, identify it. Let us know if this fixes.

0
source

I fixed it easier than the other answers - my problem arose when using the class in several projects.

If you have multiple projects, make sure that the particular class that you are deserializing is on the same path! This means that this project has the same package names, etc. Otherwise, it will not find it and will throw a ClassNotFoundException .

So, if he is in

/myPackage/otherPackage/Test.java

Then make sure that this path in your other project is exactly the same.

0
source

Ive had a similar problem with an ObjectIputStream reading serialized objects. Classes for those objects that I added at runtime using the URLClassloader. The problem was that ObjectInputStream did not use the Thread ClassLoader, which I installed with

 Thread.currentThread().setContextClassLoader(cl); 

but instead, an AppClassLoader, which you cannot configure using java 9. Therefore, I created my own ObjectInputStream as a subtype of the original and redefined the resolveClass method:

 @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { String name = desc.getName(); try { return Class.forName(name, false, Thread.currentThread() .getContextClassLoader()); } catch (ClassNotFoundException ex) { Class<?> cl = primClasses.get(name); if (cl != null) { return cl; } else { throw ex; } } } 
0
source

You can access the class name from the ClassNotFound exception message - it's terrible to depend on this in the code, but it should give you some idea. I want there to be a better way to get information about serialized objects without having an accessible class.

-1
source

All Articles