如上图项目目录,这是一个简易的QQ,客户端登录的时候要传输用户信息到服务器验证,所以两端都会用到User类的对象,但一开始我在Server端的包名是com.qq.server.common,两端的报名字不一致,所以server端卡在了逆序列化那里:
  1. User user=(User)ois.readObject();
  也就是说server端收到了传输过来的user对象,但是无法解析,当时报的错误有两种,(虽然当时知道了问题出在哪里,不知道为什么会报不同的错误,就在把这种迷惑记录在案的时候突然似乎明白了,在最下面有分析)
1、第一种情况是只有包1、2,没有包3,报下面的错误:(绿色线标出的是出错的代码,即User user=(User)ois.readObject(); )
  1. java.lang.ClassNotFoundException: com.qq.common.User
  2. at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
  3. at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
  4. at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
  5. at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
  6. at java.lang.Class.forName0(Native Method)
  7. at java.lang.Class.forName(Class.java:348)
  8. at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:626)
  9. at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1613)
  10. at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
  11. at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
  12. at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
  13. at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
  14. at com.qq.server.model.MyQQServer.<init>(MyQQServer.java:20)
  15. at com.qq.server.view.MyServerFrame.actionPerformed(MyServerFrame.java:37)
  16. at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
  17. at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
  18. at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
  19. at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
  20. at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
  21. at java.awt.Component.processMouseEvent(Component.java:6525)
  22. at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
  23. at java.awt.Component.processEvent(Component.java:6290)
  24. at java.awt.Container.processEvent(Container.java:2234)
  25. at java.awt.Component.dispatchEventImpl(Component.java:4881)
  26. at java.awt.Container.dispatchEventImpl(Container.java:2292)
  27. at java.awt.Component.dispatchEvent(Component.java:4703)
  28. at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
  29. at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
  30. at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
  31. at java.awt.Container.dispatchEventImpl(Container.java:2278)
  32. at java.awt.Window.dispatchEventImpl(Window.java:2750)
  33. at java.awt.Component.dispatchEvent(Component.java:4703)
  34. at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
  35. at java.awt.EventQueue.access$500(EventQueue.java:97)
  36. at java.awt.EventQueue$3.run(EventQueue.java:709)
  37. at java.awt.EventQueue$3.run(EventQueue.java:703)
  38. at java.security.AccessController.doPrivileged(Native Method)
  39. at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
  40. at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
  41. at java.awt.EventQueue$4.run(EventQueue.java:731)
  42. at java.awt.EventQueue$4.run(EventQueue.java:729)
  43. at java.security.AccessController.doPrivileged(Native Method)
  44. at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
  45. at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
  46. at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
  47. at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
  48. at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
  49. at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
  50. at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
  51. at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

  

2、第二种情况是1、2、3包共存,这时还是用的包1、2,所以肯定还是报错的,但是却报下面的错,虽然出错的地方是一样的,但是一直没搞懂为什么上面报的是ClassNotFoundException,而下面报ClassCastException。
  1. java.lang.ClassCastException: com.qq.common.User cannot be cast to com.qq.server.common.User
  2. at com.qq.server.model.MyQQServer.<init>(MyQQServer.java:20)
  3. at com.qq.server.view.MyServerFrame.actionPerformed(MyServerFrame.java:37)
  4. at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
  5. at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
  6. at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
  7. at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
  8. at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
  9. at java.awt.Component.processMouseEvent(Component.java:6525)
  10. at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
  11. at java.awt.Component.processEvent(Component.java:6290)
  12. at java.awt.Container.processEvent(Container.java:2234)
  13. at java.awt.Component.dispatchEventImpl(Component.java:4881)
  14. at java.awt.Container.dispatchEventImpl(Container.java:2292)
  15. at java.awt.Component.dispatchEvent(Component.java:4703)
  16. at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
  17. at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
  18. at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
  19. at java.awt.Container.dispatchEventImpl(Container.java:2278)
  20. at java.awt.Window.dispatchEventImpl(Window.java:2750)
  21. at java.awt.Component.dispatchEvent(Component.java:4703)
  22. at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
  23. at java.awt.EventQueue.access$500(EventQueue.java:97)
  24. at java.awt.EventQueue$3.run(EventQueue.java:709)
  25. at java.awt.EventQueue$3.run(EventQueue.java:703)
  26. at java.security.AccessController.doPrivileged(Native Method)
  27. at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
  28. at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
  29. at java.awt.EventQueue$4.run(EventQueue.java:731)
  30. at java.awt.EventQueue$4.run(EventQueue.java:729)
  31. at java.security.AccessController.doPrivileged(Native Method)
  32. at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
  33. at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
  34. at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
  35. at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
  36. at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
  37. at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
  38. at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
  39. at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

  

  通过这两个错误的不同,也对序列化有了更深的认识,对于网络中传输过来的序列化的对象,我们虽然是从外面接收过来的,但是要想逆序列化,也就是识别出来,达到像是完全在本地操作的目的,通信的两端就要有完全一样的类库(类的完整名字是包括包的名字的,所以包名也得一直)。
  1、上面第一个错误是因为,在本地没有找到com.qq.common.User这个类(错误提示的很明了,而且这个错误是在server端抛出的,虚拟机在告诉你:我没有在Server中找到这个包。但当时却忽视了“抛错地点”,当时还想呢,那不在Client端明明有一个com.qq.common.User类吗,你为什么还抛出这样的错误提示啊,窃以为这是在一个项目里,Server和Client端在视觉上的离得如此的近,当时就没有在引包这个思路上想,归根结底还是对序列化理解的不透彻啊)。
  2、理解了1以及序列化,就很容易理解为什么会报上面第二个错误了,因为Server端在本地找到了com.qq.common.User,也就是说虚拟机能识别收到的对象是com.qq.common.User,但不允许逆序列化为com.qq.server.common.User,也就是说Server端虽然收到的是Object对象,但当虚拟机进行向下转型的时候(此时应该会进行逆序列化),发现了问题,也就是说,虚拟机收到了一只兔子,你现在让它“逆序列化并向下转型”为一只猫,它不知道该怎么做了,所以报错:ClassCastException。

JAVA 中进行网络通信时,通信的程序两端要传输的对象,不仅要序列化,而且这个对象所属的类的名字要完全一样,连包的名字都得一样的更多相关文章

  1. Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制

    Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制 JAVA 中原生的 socket 通信机制 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.co ...

  2. js中JSON的解析(将json字符串转化为对象)和序列化(将对象转化为json字符串)(函数的功能一般都挺全的,需要的时候去查看完整函数)

    js中JSON的解析(将json字符串转化为对象)和序列化(将对象转化为json字符串)(函数的功能一般都挺全的,需要的时候去查看完整函数) 一.总结 1.JSON解析:JSON.parse(myJS ...

  3. java中的编译时常量与运行时常量

    常量是程序运行期间恒定不变的量,许多程序设计语言都有某种方式,向编译器告知一块数据是恒定不变的,例如C++中的const和Java中的final. 根据编译器的不同行为,常量又分为编译时常量和运行时常 ...

  4. Java中字符串比较时==和equals的区别

    ==是比较两个字符串引用的地址是否相同,即是否指向同一个对象,而equals方法则比较字符串的内容是否相同. 例如String a = "abc"; String b = &quo ...

  5. Java中string 创建对象时 “”和null的差别

    null和""的差别 问题一: null和""的差别 String s=null; string.trim()就会抛出为空的exception String s ...

  6. 在java中,异常抛出点后程序的执行情况

    1.在throw语句,即自定义的抛出异常语句后面的代码并不会执行,会提示错误,编译器并不可以正常编译. 2.若在一个条件语句中抛出一个异常,程序可以编译,但不会运行(dead code). 3.若在一 ...

  7. java中服务器启动时,执行定时任务

    package com.ripsoft.util; import java.util.Calendar; import java.util.Timer; import javax.servlet.Se ...

  8. java中关于如何运行jar格式程序的说明

    通常情况下,我们用打包工具如Eclipse的export工具制作的jar包是无法通过鼠标双击来运行的. 此时我们需要启动DOS窗体,在DOS窗体中输入java命令运行程序(前提是你的环境变量class ...

  9. Java 中 HashMap 初始化时赋值

      1.HashMap 初始化的文艺写法 HashMap 是一种常用的数据结构,一般用来做数据字典或者 Hash 查找的容器.普通青年一般会这么初始化:HashMap<String, Strin ...

随机推荐

  1. CentOS安装Nodejs-v8.11.1

    (1)到NodeJs官网(https://nodejs.org/en/download/),复制下载链接 (2)下载并解压 命令:wget https://nodejs.org/dist/v8.11. ...

  2. centos7mini版安装pyenv,ipython和jupyter环境.2090513

    第一节: 搭建centos7下pyenv,ipython,jupyter环境 pyenv:是一个python多版本管理器,在这个里面可以安装多个版本共存,然后可以安装需求选择版本. ipython:就 ...

  3. flutter 环境搭建

    环境: ladder什么的是必不可少的 win10 + Idea 2019.1.13 + Genymotion 2.12 基本可以在模拟器中运行项目,还有些许小问题,但是可以看到效果了 基本流程 下载 ...

  4. 求n!(高精度问题)

    #include <iostream> #include <stdio.h> #define MAX 10000 using namespace std; void Mul(i ...

  5. Django cookie、session使用

    一.cookie Cookie是key-value结构,类似于一个python中的字典.随着服务器端的响应发送给客户端浏览器.然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cook ...

  6. 8.mysql执行语句的顺序

    mysql执行语句的顺序     一.group by + where group by 字句和where条件语句结合在一起使用,where在前,group by 在后.即先对select xx fr ...

  7. 7.1.2 Python 内置异常类层次结构

    这一节就是拿来主义了,连接:https://blog.csdn.net/Karen_Yu_/article/details/78629918 异常名称 描述 BaseException 所有异常的基类 ...

  8. ssm 数据库连接池配置

    1.工程引入druid-1.1.2.jar包2.修改spring-common.xml文件 <!-- 1. 数据源 : DruidDataSource--> <bean id=&qu ...

  9. noip模拟赛 计数

    [问题描述] 给出m个数a[1],a[2],…,a[m] 求1~n中有多少数不是a[1],a[2],…,a[m]的倍数. [输入] 输入文件名为count.in. 第一行,包含两个整数:n,m 第二行 ...

  10. ZooKeeper环境搭建(单机/集群)(转)

    前提: 配置文件主要是在$ZOOKEEPER_HOME/conf/zoo.cfg,刚解压时为zoo_sample.cfg,重命名zoo.cfg即可. 配置文件常用项参考:http://www.cnbl ...