重构包后反序列化时出现 ClassNotFoundException
ClassNotFoundException when deserializing after refactored package
当我尝试执行我的程序时,我 运行 遇到了问题(损坏的 class 路径?)。 .class 文件位于:
C:\...\...\...\StoreDirectorySystem4.0\bin\build\classes\system
,所以我将 class 路径指向 system
文件夹。我也试过指向 jar 文件,但无济于事,如下所示:
When specifying a path to a .zip or .jar file, you must end the path with the filename. When specifying a path to .class files, that path should end with the folder containing the .class files.
(source)
但是,当我构建项目(使用 ant)时,它会抛出 ClassNotFoundException
。这是堆栈跟踪:
[java] java.lang.ClassNotFoundException: com.company.Clerk
[java] at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
[java] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[java] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
[java] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[java] at java.lang.Class.forName0(Native Method)
[java] at java.lang.Class.forName(Class.java:348)
[java] at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java :626)
[java] at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream. java:1613)
[java] at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
[java] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
[java] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
[java] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
[java] at java.util.ArrayList.readObject(ArrayList.java:791)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[java] at java.lang.reflect.Method.invoke(Method.java:497)
[java] at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
[java] at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
[java] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
[java] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
[java] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
[java] at system.Directory.readFile(Unknown Source)
[java] at system.Directory.<init>(Unknown Source)
[java] at system.DirectoryServer.main(Unknown Source)
问题是,Clerk
class 不再存在于 com.company
中(我在 IntelliJ IDEA 中重构了包的名称)。它存在于前面提到的 system
包中。 Clerk
class 在其中声明了 package system;
。
当我尝试读取 Directory
class 中的序列化集合时出现异常,特别是此处:
public ArrayList<Employee> readFile() {
try (ObjectInputStream inputStream =
new ObjectInputStream(new FileInputStream(this.file))) {
employeeList = (ArrayList<Employee>) inputStream.readObject();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return employeeList;
}
jar 文件包含:
META-INF/
META-INF/MANIFEST.MF
system/
system/Clerk.class
system/Directory.class
system/DirectoryServer.class
system/Employee.class
system/FullTime.class
system/Manager.class
system/PartTime.class
所以我的问题是,问题是什么,如何解决?
ClassNotFoundException: com.company.Clerk
这意味着它无法找到 class com.company.Clerk
,因此您需要在 JAR com/company/Clerk.class
中找到或在 com/company/Clerk.class
上方的目录中找到 class路径。
简而言之,包必须与 class 所在的目录匹配。
he stated he REFACTORED the code and changed the package and wants to deserialize something that was serialized before the refactoring
这不会改变序列化格式,标准序列化不支持别名或重命名。您需要反序列化原始 class 并在运行时将其转换为新的 class。
文件中存储的对象具有class com.company.Clerk。 class 在您更改其名称后不再存在,因此显然无法再读取这些对象。您的选择是:将 class 的名称改回原来的名称,或者创建一个程序将文件从一种格式转换为另一种格式,或者接受您将丢失文件中的数据并继续使用您的生活,或添加将旧 class 名称解析为新 class 的代码(覆盖 resolveClass 方法)。
当我尝试执行我的程序时,我 运行 遇到了问题(损坏的 class 路径?)。 .class 文件位于:
C:\...\...\...\StoreDirectorySystem4.0\bin\build\classes\system
,所以我将 class 路径指向 system
文件夹。我也试过指向 jar 文件,但无济于事,如下所示:
When specifying a path to a .zip or .jar file, you must end the path with the filename. When specifying a path to .class files, that path should end with the folder containing the .class files. (source)
但是,当我构建项目(使用 ant)时,它会抛出 ClassNotFoundException
。这是堆栈跟踪:
[java] java.lang.ClassNotFoundException: com.company.Clerk
[java] at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
[java] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[java] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
[java] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[java] at java.lang.Class.forName0(Native Method)
[java] at java.lang.Class.forName(Class.java:348)
[java] at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java :626)
[java] at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream. java:1613)
[java] at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
[java] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
[java] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
[java] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
[java] at java.util.ArrayList.readObject(ArrayList.java:791)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[java] at java.lang.reflect.Method.invoke(Method.java:497)
[java] at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
[java] at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
[java] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
[java] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
[java] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
[java] at system.Directory.readFile(Unknown Source)
[java] at system.Directory.<init>(Unknown Source)
[java] at system.DirectoryServer.main(Unknown Source)
问题是,Clerk
class 不再存在于 com.company
中(我在 IntelliJ IDEA 中重构了包的名称)。它存在于前面提到的 system
包中。 Clerk
class 在其中声明了 package system;
。
当我尝试读取 Directory
class 中的序列化集合时出现异常,特别是此处:
public ArrayList<Employee> readFile() {
try (ObjectInputStream inputStream =
new ObjectInputStream(new FileInputStream(this.file))) {
employeeList = (ArrayList<Employee>) inputStream.readObject();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return employeeList;
}
jar 文件包含:
META-INF/
META-INF/MANIFEST.MF
system/
system/Clerk.class
system/Directory.class
system/DirectoryServer.class
system/Employee.class
system/FullTime.class
system/Manager.class
system/PartTime.class
所以我的问题是,问题是什么,如何解决?
ClassNotFoundException: com.company.Clerk
这意味着它无法找到 class com.company.Clerk
,因此您需要在 JAR com/company/Clerk.class
中找到或在 com/company/Clerk.class
上方的目录中找到 class路径。
简而言之,包必须与 class 所在的目录匹配。
he stated he REFACTORED the code and changed the package and wants to deserialize something that was serialized before the refactoring
这不会改变序列化格式,标准序列化不支持别名或重命名。您需要反序列化原始 class 并在运行时将其转换为新的 class。
文件中存储的对象具有class com.company.Clerk。 class 在您更改其名称后不再存在,因此显然无法再读取这些对象。您的选择是:将 class 的名称改回原来的名称,或者创建一个程序将文件从一种格式转换为另一种格式,或者接受您将丢失文件中的数据并继续使用您的生活,或添加将旧 class 名称解析为新 class 的代码(覆盖 resolveClass 方法)。