如何解决反序列化二进制类文件的内容时发生ClassNotFoundException
|| 我对Java不太了解。我正在尝试读取一个文件,该文件包含一个int以及一个名为\“ Automobile \”的类的各种实例。但是,当我对其进行反序列化时,该程序将引发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\");
}
提前致谢。
编辑:这是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)
解决方法
反序列化序列化的对象树时,所有对象的类都必须位于类路径上。在这种情况下,“ 2”很可能意味着所需的类之一不在类路径中。您必须解决此问题才能进行反序列化。
在这种情况下,
es4.Automobile
将丢失。
问题可能是由我提出的汽车引发的自定义异常引起的吗?
我能想到的唯一其他可能性是:
es4.Automobile
直接或间接依赖于缺少的某些其他类
es4.Automobile
或相关类的静态初始化引发了一个异常,该异常尚未在该类的内部捕获。
但是这两个(我认为)应该导致了不同的堆栈跟踪。
我只是注意到软件包名称是es4p2,而不是es4。为什么说es4?可能是因为保存文件的程序使用了另一个软件包名称吗?
我不知道为什么他们与众不同。您需要与编写代码/产生序列化对象的人交谈。但是,这很可能是造成问题的原因。具有不同程序包名称的类是不同的类。期。
当捕获到意外异常时,您应该始终输出(或记录日志)堆栈跟踪。这将告诉您(和我们)更多出了问题的信息,在这种情况下,这是缺少的类的名称。
, 如果您的类“ 6”不在运行时类路径中,通常会发生这种情况。
, 这是一个古老的问题,但这可能会对其他人有所帮助。我遇到了同样的问题,问题是我没有使用当前的线程类加载器。您会在我在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
}
}
}
, 您的Automobile
班是否有这样的字段?
private static final long serialVersionUID = 140605814607823206L; // some unique number
如果不是,请定义一个。让我们知道是否可以解决问题。
, 我用比其他答案更容易的方式修复它-在多个项目中使用该类时,出现了我的问题。
如果您有多个项目,请确保您要反序列化的特定类的路径完全相同!这意味着该项目中的软件包名称相同。否则,它将找不到并导致抛出ѭ2be。
所以如果它在
/myPackage/otherPackage/Test.java
然后确保该路径在您的其他项目中完全相同。
, 我有一个类似的问题与ObjectInputStream读取序列化的对象。我在运行时使用URLClassloader添加的那些对象的类。问题是ObjectInputStream没有使用我设置的Thread ClassLoader
Thread.currentThread().setContextClassLoader(cl);
但是是AppClassLoader,您无法使用Java 9对其进行自定义。因此,我将自己的ObjectInputStream设置为原始输入的子类型,并覆盖了resolveClass方法:
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException,ClassNotFoundException {
String name = desc.getName();
try {
return Class.forName(name,Thread.currentThread()
.getContextClassLoader());
} catch (ClassNotFoundException ex) {
Class<?> cl = primClasses.get(name);
if (cl != null) {
return cl;
} else {
throw ex;
}
}
}
, 您可以从ClassNotFound异常的消息中访问类名-在代码中依赖该类名是可怕的-但它应该给您一些想法。我希望有一些更好的方法来获取有关序列化对象的信息,而不必使类可用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。