前言

学校小组Project那些外国人啥也不会, 基本上我一个人全包了前端和后端, 说实话这些天来也感受到了写一个比较拿得出手的web确实也不是这么容易的, 特别是我没什么项目经验, 很多时候碰到问题只能自己往死里想, 一个地方一个地方的debug. 以前我一直有点看不起web开发, 觉得web开发挺简单的, 也没什么好学的, 但是再简单的东西, 如果没有经验, 也简单不起来. 这次的网页, 实际功能不需要多复杂, 逻辑也没有多复杂, 但是真的要实现起来确实不是想象中那样信手拈来. 往往问题出现的地方总是你思维的死角, 知识的盲区.

项目部署debug

从昨天下午, 我照常把自己写的网页push到服务器上, 结果, 问题来了... 无论访问什么网页, 直接404...

  1. 首先来简单介绍一下我这次的改动 : 为了开发方便, 我之前jsp一直放在web的主目录下, 然后最近差不多写完了, 于是我就采用了典型SSH框架中的目录结构(但是我没用SSH框架, 准备先自己写一个proj感受一下, 然后再用框架, 感受框架带来的不同) : 也就是将JSP全部移到WEB-INF中, 采用Servlet截获请求后转发给jsp的方式. 在我的电脑上没有任何问题, 但是一到服务器上, 就是404.
  2. 一看到404, 我的第一印象是配置文件有问题, 也就是说web.xml中Servlet的match pattern写的不对. 因为在我的mac上, proj是在IDEA中开发, 然后IDEA自动将项目目录部署, 这时候项目的根目录就是页面的根目录, 而在我的服务器这边, 我的项目放在了sixTech文件中(前面有个帖子提到了), 而这个文件所在的目录才是网页的根目录. 所以我一顿改, 但是可惜, 一直是稳稳的404.
  3. 之后的几个小时里我尝试在项目下非WEB-INF中加入jsp进行调试, 发现jsp可以正常执行, 另外我也可以通过这个jsp来引用WEB-INF中的JSP, 但是这里一引用就出问题了, 问题出在jstl, 也就是典型的This absolute uri http://java.sun.com/jsp/jstl/core cannot be resolved, 而这个问题实际上就是简单的jstl安装问题, 而我使用的是jstl-1.2, 并不需要在web.xml中添加配置, 只需要简单地在WEB-INF的lib中加入jstl-1.2jar包另外在需要使用jstl的jsp中引入即可, 但是它就是一直报这个错, 解决方法通过控制变量排查了很久, 昨天晚上日常的锻炼也耽误了, 还是没有找到问题, 我可以100%确定我这个引入是没错的. 那时候整个人都是绝望的, 弄着弄着就11点多了, 日常锻炼也耽误了, 带着不甘和痛苦我只能选择睡觉.
  4. 今天早上起来, 我脑子稍微清醒了点, 我先是尝试着写了一个小的, 相对简单的测试项目进行发布, 在里面我没有使用jstl, 发现还是不行, 这显然排除了代码或者配置文件的问题, 而且里面只有一个简单的Servlet和一个jsp. 我开始思考是不是问题出现在容器端而不是我的项目端? 但是我每次开启服务器确实没有报错. 最后我索性把我mac上的tomcat整个拷贝到服务器中, 又进行了一次测试, 仍然没有问题. 这个时候我基本上已经放弃了, 我沮丧的甚至有点蒙.
  5. 这时候估计是老天开眼了, 我突然想到去看看tomcat的log文件, 这一看不得了, 发现了新的天地, tomcat的log中发现了类似 : java.lang.UnsupportedClassVersionError: Unsupported major.minor version 51.0 (unable to load class frontend.listener.StartupListener) [duplicate]的话, 我一搜索, 发现问题了, 这是典型的编译java使用的jdk和jre版本不符的问题. 我一查, 服务器的java版本是1.7, 我的mac不用说肯定是最新版本1.8. 这个问题的最蹊跷之处也得到了解释, 为什么我写在web-inf外的jsp能够被执行而里面的不行, 因为写在外面的jsp, 是由容器(这里是tomcat)在用户第一次访问时转化为java并编译加载的, 也就是说都发生在我的服务器上, 所以编译加载用的都是1.7的jdk, 而我web-inf中的jsp是通过我的Servlet转发的, 而Servlet的编译发生在我的mac上, 在我打war包的时候就发生了, 也就是所有的Servlet是用1.8的jdk编译, 而是用1.7的jre去执行1.8的jdk编译出来的class, 显然是不兼容的, 所以这个Servlet就炸了, 莫名其妙的一堆问题突然就全解决了.
  6. 但是这时候还有一个问题, 我解决这个问题用的是我从mac上发过来的tomcat, 项目是直接写在webapps的ROOT里面的, 所以能直接访问, 然后我把这个tomcat的文件删掉, 用我之前那个, 项目仍然在sixTech中, 却发现又是404. 这时候如果读过我之前服务器部署那篇文章, 那么这个问题应该是很好解释了, 就是context中的docBase部署的是sixTech所在的目录而不是sixTech这个目录, 然后我在context中把docBase改了一下, 问题解决!
  7. 之前一直有一个小问题, 我在idea中修改一个jsp文件, 你必须重新部署项目才行, 但是明明只有web.xml才是在项目运行时读取, 像jsp虽然是一次编译多次运行, 但是一旦容器检测到jsp有变化, 会重新进行编译, 然后我在服务器上试了下, 果然, web.xml的变化需要重新部署才能看到, 但是jsp可以通过直接改动看到. 这又是为什么呢? 实际上这里又需要对IDEA的部署方式进行了解, IDEA会把你要部署的项目拷贝到某个文件下, 而你在IDEA中的修改只是你的项目目录, 你需要显示的update classes才能把这个变化反映出来. 通过这个, 我算是理解了为什么IDEA上运行按钮下会有 升级资源 升级类 重新部署 和 服务器重启 四种选项了.

8 至此, 所有的问题都完美解决了 !!!

感想

这次debug花了几乎是一天的时间, 但源头却只是一个小小的版本兼容问题, 但是我还是非常的开心, 因为这对我而言确实是十分宝贵的经验. 我也发现了自身的不足, 面对比较复杂的问题, 分析的太片面了, 思维定式到只关注代码, 种版本兼容性之类的问题我压根就想不到, 自己确实还是太缺乏经验了. 另一方面, 这次debug也让我对于IDEA和tomcat的某些特征(坑, 开启中部分失败也不会报错)有了更深的了解, 同时这也说明了看log的重要性. 这种debug, 过程很痛苦绝望, 但是一旦解决了, 无论问题大与小, 都是很有价值. 计算机专业, 基础啊什么的学习固然重要, 但是很多时候, 我感觉学校的编程环境更像是一个象牙塔, 它屏蔽了除了编程知识以外的一切问题, 这有它的好处, 但是却也是不足, 于我而言, 我更希望自己成为现实的实践者, 而不是天天死扣概念, 写一写简单的玩具代码的学生, 那确实很没意思.

posted on 2017-02-07 20:23  内脏坏了  阅读(1229)  评论(0编辑  收藏  举报