2011-06-09 67 views
4

我對Java沒有太多瞭解。我試圖讀取一個包含int和一個名爲「Automobile」的類的各種實例的文件。但是,當我反序列化它時,程序拋出一個ClassNotFoundException,我似乎無法理解爲什麼。對二進制類文件的內容進行反序列化時的ClassNotFoundException

下面的代碼:

 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"); 
    } 

在此先感謝。

編輯:這裏的堆棧跟蹤

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) 
+1

請顯示例外的詳細信息。 – 2011-06-09 22:33:04

+1

你能否提供更多的細節,理想的堆棧跟蹤? – 2011-06-09 22:33:15

+0

你是否正在反序列化與編寫的完全相同的類? 'es4'軟件包中的'Automobile'類型是否在您的反序列化代碼中? – McDowell 2011-06-09 22:46:41

回答

8

當您反序列化一個序列化對象樹時,所有對象的類必須位於類路徑上。在這種情況下,ClassNotFoundException很可能意味着所需的類之一不在類路徑上。你必須解決這個反序列化的問題。

在這種情況下,es4.Automobile丟失。


能的問題,通過我做了一個自定義異常,這是由汽車發射引起的?

我能想到的唯一的其他可能性:

  • es4.Automobile有缺失
  • es4.Automobile靜態初始化或依賴類已拋出一些其他類的直接或間接依賴這是一個在班級內部尚未發現的例外情況。

但這兩個應該(我認爲)導致了不同的堆棧跟蹤。


我只注意到包名是es4p2,不ES4。爲什麼說es4?難道是因爲保存該文件的程序使用了另一個軟件包名稱?

我不知道他們爲什麼不同。您需要與編寫代碼/生成序列化對象的人進行交談。但是,這很可能是問題的原因。具有不同包名的類是不同的類。期。


當捕獲到意外異常時,您應該始終輸出(或更好地記錄)堆棧跟蹤。這會告訴你(和我們)更多的錯誤信息,在這種情況下,失去的類名稱。

+1

「在類路徑中」是什麼意思? Automobile.java文件與Main.java在同一個包中,它引發異常。 – 2011-06-09 22:40:26

+0

問題可能是由汽車發起的自定義異常引起的嗎? – 2011-06-09 22:40:56

+0

我剛注意到包名是es4p2,而不是es4。爲什麼說es4?難道是因爲保存該文件的程序使用了另一個軟件包名稱? – 2011-06-09 22:43:42

0

Automobile類有一個字段這樣嗎?

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

如果沒有,則定義一個。讓我們知道是否修復它。

+0

我補充說,我仍然遇到這個問題。 – 2011-06-09 22:36:19

+0

省略它不會導致此問題。 – EJP 2015-12-05 22:47:11

1

如果您的類Automobile不在運行時類路徑中,通常會發生這種情況。

-1

您可以從ClassNotFound異常的消息中訪問類名 - 在代碼中依賴此類代碼非常糟糕 - 但它應該給您一些想法。我希望有一些更好的方法可以獲得有關序列化對象的信息,而無需使用該類。

+0

你不必'在代碼中依賴這個'。您只需正確部署您的應用程序。不知道你在最後一句話中究竟希望什麼。 – EJP 2015-12-05 22:48:23

1

這是老問題,但這可能會幫助別人。我面臨同樣的問題,問題是我沒有使用當前的線程類加載器。你會發現,我在一個Grails項目中使用的序列化器類以下,應該是很簡單的使用這個在java中 希望這有助於

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 
     } 
    } 
} 
+0

爲什麼他們不使用currentThread類加載器?!感謝您的靈感。 – Kuronashi 2018-01-15 14:34:16

0

我固定它比其他的答案更簡單的方法 - 發生在我的問題當在多個項目中使用

如果您有多個項目,請確保您要反序列化的特定類位於完全相同的路徑中!這意味着,該項目內的相同包名等。否則它不會找到它並導致ClassNotFoundException被拋出。

因此,如果在

是/myPackage/otherPackage/Test.java

然後確定,這條道路是完全在你的其他項目一樣。

0

我有一個ObjectInputStream讀取序列化對象的類似問題。這些對象是我在運行時使用URLClassloader添加的對象。問題是,ObjectInputStream中沒有使用線程的ClassLoader我設定

Thread.currentThread().setContextClassLoader(cl); 

而是在AppClassLoader,其中9所以我做我自己的ObjectInputStream你不能用java定義爲原來的亞型提供解決方案方法:

@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; 
     } 
    } 
} 
相關問題