目录
- 我的学习过程
- 我的学习心路
- 热加载配置
- bug问题总结
我的学习过程
前天写的client-server聊天项目写完后,今天进行了调试。我用到的是out目录下的server.class文件和client.class文件。
先后启动两个命令行窗口来进行测试的。
使用java server启动服务端窗口。
再使用java client启动客户端窗口。
客户端发送四次信息
ni
hao
zhong
guo
客户端发给服务端的信息正常情况下,服务端接收后屏幕打印一律显示了str。
客户端打印的四次信息
str
str
str
str
我的学习心路
客户端的发送的具体信息,全是str。为什么呢?
我的操作心路
首先是服务端显示异常,所以定位到server.java的代码。定位到问题代码如下:
// 有bug的java代码
System.out.println("str");
我的操作心路
这个bug简单,就是不小心加了双引号,导致直接打印了字符串str。修正!我用的是gradle管理项目,进行了clean、build、rebuild project后,继续使用两个命令行窗口进行测试。
我的心里路程
问题没有得到解决。我想想会是什么原因呢?明明已经改过来了。该怎么解决呢?我或许可以尝试到idea里打断点进行调试,看看是不是有其他代码问题。
我的操作心路
说干就干,在idea里配置两个tomcat试试,学习了tomcat的热加载配置。
热加载配置
找到tomcat的目录下找到conf/server.xml文件,打开,
在host节点下增加Context节点。
<Host name="localhost"...
...
<Context path="项目路径" docBase="/【某目录名】" debug="0" privileged="true" reloadable="true"/>
...
</Host>
属性概念:
debug=“0”
debug是设定debug level, 0表示提供最少的信息,9表示提供最多的信息。
privileged=“true”
privileged设置为true的时候,才允许Tomcat的Web应用使用容器内的Servlet。
reloadable=“true”
会让修改生效,该选项适合调试。
我的心里路程
我发现,上面参数里【某目录名】是建在webapps目录下,目录里面需要放置项目编译后的class文件和项目的jar包。但是同样class文件在目录中存在了2个地方。
一个是out/production/classes目录下
另一个build/classes/java/main目录下
我的心里路程
老师的课程用的是out目录下的class文件,我也是使用out目录下的,是什么原因导致修正不生效呢?为什么有2个地方的class?
我的操作心路
百度一下看看:推测出,由于每次使用的是out目录下的class文件,但clean、build、rebuild project并没有修正out文件下class文件。是每次都不起作用呢?还是一定时间间隔后起作用?有待考证*1
我的操作心路
使用tomcat热加载后,问题得倒了解决。
我的心里路程
推测两种可能:
- reloadable="true"可以对out目录下的class文件修正。
- 或者热加载使用的是build目录下的class文件。
有待考证*2
标记:学习下gradle的目录结构或源网站的说明。
考证*1
我的考证结果:有待考证*1处思考有误。
我的考证思路:
在Server.java中添加打印语句,观察两处class文件是否添加该打印语句进行来验证。
两种build验证:
- idea上方导航栏build(clean project、build project、rebuild project)
- idea窗口右侧边栏Gradle-Tasks下build(clean、build)
第一种build下:针对的是out目录下的class
Server.java修改后,
- 若未进行clean project,则build project和rebuild project都未能修正out目录下的Server.class。
- 若先进行了clean project,则build project和rebuild project都能修正out目录下的Server.class。
第二种build下:针对的是build/classes/java/main目录下的class
Server.java修改后,
- clean直接会删除build/classes/java/main整个目录和Server.class文件。
- 直接build就可以修正build/classes/java/main目录下的Server.class文件。
考证*2
我的考证结果:有待考证*2处思考有误。热加载使用的是out目录下的class文件。
我的考证思路:
利用两种build的不同点使两处的class文件具备不同的打印语句。观察运行后窗口的打印语句。
out目录下的Server.class:
System.out.println("-------bad1----");
build/classes/java/main目录下的Server.class:
System.out.println("-------bad2----");
Server.java:
System.out.println("-------good----");
启动tomcat,运行Server.java,窗口打印结果:
-------good----
out目录下的Server.class内打印语句发生变化:
System.out.println("-------good----");
out目录下的class能修正,是否与reloadable="true"有关呢?
我的心里路程
把reloadable设置false试试。重复上面操作。
结果:不影响out目录下的class的修正。
百度了解:这个属性设为true,tomcat服务器在运行状态下会监视在WEB-INF/classes和WEB-INF/lib目录下class文件的改动,如果监测到有class文件被更新的,服务器会自动重新加载Web应用。
我的思考
设为false时,第一次启动tomcat也会调一次监测吗?或者说服务器重启了会重新加载更新一次,重启与这个属性无关?
设为true时,启动tomcat,运行Server.java,修改Server.java,保存重新编译(修正了out目录下的class)。Server.java并没有重新加载。啊哦!想错了。监视的是WEB-INF/classes和WEB-INF/lib目录下class文件。与out目录下的class无关。想错了,哈哈哈。
bug问题总结
我错在使用的是第二种的clean,针对的是build/classes/java/main目录下的class。未使用第一种的clean project再build project,针对的是out目录下的class。