技术经理给我安排了一个上古时期的Tomcat项目,Tomcat中的bat批处理脚本源码分析,还好我是练过的,基础的底层知识掌握了

YuShiwen 发表于 2022/03/31 10:35:00 2022/03/31
【摘要】 前几天部门的技术经理给我分配了一个任务,叫我一个人去维护之前上古时期的Java Wbe项目,这个项目其实是一个前置机程序,负责消息的`加解密、加签验签`和消息的`转发`;这个程序部署于Servlet容器中,用的是Tomcat服务,并且这个Tomcat服务我们公司的运维人员不知道怎么操作
✨我是喜欢分享知识、喜欢写博客的YuShiwen,与大家一起学习,共同成长!
📢闻到有先后,学到了就是自己的,大家加油!

@[TOC]

前言:

前几天部门的技术经理给我分配了一个任务,叫我一个人去维护之前上古时期的Java Wbe项目,这个项目其实是一个前置机程序,负责消息的加解密、加签验签和消息的转发;这个程序部署于Servlet容器中,用的是Tomcat服务,并且这个Tomcat服务我们公司的运维人员不知道怎么操作,说配置的步骤太多了,之前有一个人配置成功了,但是离职了,写的文档也模糊不清,现在他们都不知道咋配置,1000-9999人的公司,这个运维人员不大行,算了不吐槽了(⊙﹏⊙)!
运维人员和笔者说,这个前置机程序是运行在客户那边的,最好是不需配置环境变量等其他操作,做到一键点击即可启动Tomcat服务。这样古老项目的维护难度又提高了亿丢丢。
笔者解压缩了之前项目的压缩包后,看了一下,发现启动的步骤是用的Tomcat的startup.bat批处理文件(Windows系统)进行启动的,下面会详细讲。
好了,下面进入正文:


1.idea自动反编译class文件,在idea中我们也可以查看字节码的源代码

首先之前开发的源码已经丢失了,只有编译后的class文件;
当我拿到程序编译后的class文件后,用idea打开,idea自带反编译功能,如下是小demo(公司的代码不能向外界提供,所以这里提供了一个小demo):
比如我打开JDK中的Integer类,上面说到过用idea打开是自动进行了反编译的结果,如下:
在这里插入图片描述
那么如何查看反编译前的字节码文件呢,我们在idea中也可以查看,如下操作:(点击View–>Show Bytecode)
在这里插入图片描述
字节码文件的内容如下:
在这里插入图片描述
好说到这里,咋们就打住,关于如何查看字节码的内容,这个咋们之后再聊(会写一篇关于这个的博文)。
回到主题,刚开始说了,idea自动进行的反编译,还好之前的项目写的代码不多,看了半天代码后,理清思路,然后又花费一天时间,写代码,自测,修改,又自测,终于写好了,自测通过;接下来的任务就是之前运维提到的,去掉项目启动前环境变量配置的过程,优化一系列的操作,做到点击startup.bat批处理文件即可一键启动Tomcat服务。

2.如何做到一键点击startup.bat批处理文件启动Tomcat服务

在这里插入图片描述

2.1startup.bat批处理文件

如下是Tomcat的文件目录,关于Tomcat目录的讲解,可以参考笔者之前的博文:https://blog.csdn.net/MrYushiwen/article/details/113383917
在这里插入图片描述

因为是点击startup.bat批处理文件进行启动的,我第一反应就是用文本编辑器打开startup.bat文件,点击进入bin目录下,bin目录如下,等会讲解红色框中的三个批处理文件:
在这里插入图片描述

找到startup.bat批处理文件,用文本编辑器打开,具体内容如下(嘿嘿,之前有写过批处理脚本的我还是看得懂的哈,看不懂的小伙伴可以参看下面的章节三,关于批处理文件的讲解零基础快速入门):
在这里插入图片描述

  1. 第一个红色框这条语句是检测CATALINE_HOME的值,如果不为空,就跳转到gotHome标记出执行。可以看到在这个批处理文件中,多次用到了CATALINA_HOME变量,这个变量我们可以在环境变量中进行配置,关于环境变量深入的理解,可以参考笔者这篇博文:https://blog.csdn.net/MrYushiwen/article/details/120509711,因为在批处理文件中用到了这个CATALINE_HOME变量,它可以取自环境变量,也可以用set命令给CATALINE_HOME变量赋值;所以之前我们需要设置如下环境变量才可以运行:
    在这里插入图片描述

  2. 第二个红框设置变量EXECUTABLE的值为CATALINE_HOME变量下的bin包下的catalina.bat批处理文件,这个EXECUTABLE在第三步中会用到。

  3. 第三个红框用call命令进行调用,启动EXECUTABLE环境变量所指向的程序,即catalina.bat。

好了,startup.bat批处理文件讲解完了,如果我们不想配置环境变量CATALINE_HOME的值,根据上面提到的我们只需要在startup.bat批处理文件头部加上set CATALINE_HOME=xxx(注意等号后面不允许有空格,本人踩过坑)即可,这样就不会从环境变量值获取该值了,直接在批处理文件中就有定义,如下(笔者的路径就是本项目的Tomcat,即就是解压缩之后的文件所在的路径):
在这里插入图片描述

2.2catalina.bat批处理文件

上面提到过startup.bat批处理文件会用call命令调用catalina.bat批处理文件,我们用文本编辑器打开catalina.bat批处理文件,如下:
在这里插入图片描述

  1. 第一个红色框,可以看到在catalina.bat批处理文件中也同样用到了CATALINE_HOME这个变量,如果我们不想配置环境变量,同样也可以在文件的开始处加上set CATALINE_HOME=xxx即可。

  2. 第二个红色框,用call命令调用了setclasspath.bat批处理文件

同样我们不想配置环境变量,在文件的开始处加上set CATALINE_HOME=xxx即可,如下:
在这里插入图片描述

2.3setclasspath.bat批处理文件

接下来我们点进setclasspath.bat批处理文件中查看,如下:
在这里插入图片描述
第一个红框中可以看到setclasspath.bat批处理文件用到了JAVA_HOME和JRE_HOME这两个变量,如果们配置了环境变量,可以从环境变量中取,我们也可以用set命令在文件头部指定(如下图一),我们指定了就不需要配置Java的环境变量了,当然JDK需要放到Tomcat的目录中去(如下图二),虽然文件大了点,但是方便了用户。这样就做到了不需要配置环境变量,通过startup.bat批处理文件一键启动Tomcat服务。

<image src=https://img-blog.csdnimg.cn/ffc9fc72cbbf43d88184f302119217a4.png > </image>
图一
<image src=https://img-blog.csdnimg.cn/224af50a00b14161ae3f0ebc85a17aad.png > </image>
图二

2.4复盘

根据上面的2.1 、2.2、2.3的分析,我们现在总结一下:
bin目录下的startup.bat—调用—>catalina.bat—调用—>setclasspath.bat
说明:

  1. tomcat的startup.bat脚本主要用来判断环境,找到catalina.bat脚本源路径,将启动命令参数传递给catalina.bat执行;
  2. setclasspath.bat检查各种变量是否赋值,验证tomcat启动停止需要涉及到的文件,保障tomcat顺利启动停止;
  3. catalina.bat脚本使用了大量的判断,使用if作为参数的输入判断,核心的启动命令其实就是java命令。

我们在startup.bat、catalina.bat和setclasspath.bat这三个批处理文件中用set操作对需要用到的变量进行赋值,这样就不需要再去配置环境变量了。


3.bat批处理文件零基础快速入门

我们以Tomcat中的startup.bat为例进行讲解:(其中rem为注释,大部分rem已被笔者删掉),文件内容如下:
在这里插入图片描述

对上述的脚本一行行的分析(大家耐心看完,绝对会有很大的收获,如果对命令不是很了解的话,可以看下该篇文章进行学习:批处理命令教程;然后在过来看笔者这里写的,妥妥地保姆级别分析源码):

  1. @echo off
    默认情况下,批处理文件将在运行时显示其命令。 这第一个命令的目的是关闭这个显示。 “echo off”命令会关闭整个脚本的显示,除了“echo off”命令本身之外。前面的“@”符号使命令也适用于自己。
  2. if "%OS%"=="Windows_NT" setlocal
    这是个if语句。在命令行中执行help if就可以打印出if语句的使用帮助,大家可以多看下手册。
    这里这条语句的作用是检查OS环境变量的值是否是Windows_NT,如果条件成立,则执行setlocal。setlocal这是开始批处理文件中环境改动的本地化操作。在执行SETLOCAL之后所做的环境改动只限于批处理文件。要还原原先的设置,必须执行ENDLOCAL。达到批处理文件结尾时,对于该批处理文件的每个尚未执行的SETLOCAL命令,都会有一个隐含的ENDLOCAL被执行。
  3. set CURRENT_DIR = %cd%
    这条语句是设置变量CURRENT_DIR 的值为当前目录(两个百分号可以取变量的值),比如C:\Users\yushiwen
  4. if not "%CATALINE_HOME%"=="" goto gotHome
    这条语句是检测CATALINE_HOME的值,如果不为空,就跳转到gotHome标记(标签)处执行。(用冒号+字符表示标记,比如第8条的 :gotHome
  5. set CATALINA_HOME=%CURRENT_DIR%
    把CATALINA_HOME的值设置为CURRENT_DIR变量的值,两个百分号可以取变量的值。
  6. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
  7. cd ..
  8. set CATALINA_HOME=%cd%
  9. cd %CURRENT_DIR%
    6、7、8、9一起讲:
    如果catalina.bat是存在的,就跳转到okHome标记处开始往下继续执行,
    如果catalina.bat不存在,先cd到当前目录的上级目录,然后设置CATALINA_HOME变量为cd变量所对应的值(注意上一步已经执行了cd …,返回了上级目录,此时的目录是之前目前的上级目录)。
  10. :gotHome
    标记,goto命令用来跳转,上面的第4条语句用到了该标记。
  11. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
    判断指定的文件是否存在,存在就跳转到okHome
  12. echo The CATALINA_HOME environment variable is not defined correctly
    echo命令用于在命令行中显示echo后面的字符内容
  13. echo This .....
    echo命令用于在命令行中显示echo后面的字符内容
  14. goto end
    和上面的11.if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome一起看,如果if条件不成立,就跳转到end标记处,继续往下执行,其实就是结束了此次批处理命令。
  15. :okHome
    标记,goto命令用来跳转,上面的第11条语句用到了该标记。
  16. set EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat
    设置EXECUTABLE变量的值
  17. if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
  18. echo Cannot find ......
  19. eco This file ......
  20. goto end
  21. :okExec
    17、18、19、20、21一起看:
    如果catalina.bat还是不存在的话,就在命令行窗口回显两句话,然后跳转到end标记处,继续往下执行,其实就是结束了此次批处理命令。
    如果catalina.bat存在,就跳转到okExec标记(标签)处,继续往下执行。
  22. set CMD_LINE_ARGS=
    清空CMD_LINE_ARGS变量的值
  23. :setArgs
    标记,goto命令用来跳转,下面的第27条语句用到了该标记,起到了循环的作用。
  24. if ""%1""=="""" goto doneSetArgs
    检查%1是否为空,如果为空就表示没有参数了,设置参数结束,跳转至doneSetArgs标记处;如果不为空就把%1指向的参数追加到CMD_LINE_ARGS这个环境变量中。
知识点:关于这里的%1 还有下面的第26条命令shift
比如有如下的文件:demo.bat
demo.bat文件的内容为:echo %0 %1 %2 %3 ,(如下图图A)
demo.bat这个批处理文件只有一条语句,在命令行中执行这条语句:demo.bat a b c d e
那么结果就会打印出如下内容:(如下图图BC:\Users\yclw060\Desktop>demo.bat a b c d e

C:\Users\yclw060\Desktop>echo demo.bat a b c
demo.bat a b c

说明:%0 %1 %2 %3都表示变量
%0表示这个批处理文件的文件名,%1表示传递给该批处理文件的第一个参数,%2表示传递给该批处理文件的第二个参数,%3表示传递给该批处理文件的第三个参数,一直可以用这个方法传递9个参数,即使用到%9,但是如果参数再多了,应该如何处理呢?
这时候shift命令就派上用场了
现在我们来更改demot.bat的内容,更改后的内容如下:(如下图图C)
shift
echo %0 %1 %2
做了这些更改之后,同样执行上面的命令:demo.bat a b c d e
shift这个命令的作用就是把传递的参数依次前移,这样%0就代表了a,%1代表b,%2代表c,%3代表d了。(如下图图D)
如果让e显示出来,就需要用两次shift,那么此时%0就代表了b,%1代表c,%2代表d,%3代表e。

在这里插入图片描述
图A
在这里插入图片描述
图B
在这里插入图片描述
图C
在这里插入图片描述

图D

  1. set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
    把%1指向的参数追加到CMD_LINE_ARGS这个环境变量中
  2. shift
    shift指令是移位参数,使%1指向了下个参数
  3. goto setArgs
    跳转到setArgs,检查%1是否为空,如果不空,继续追加参数。
  4. :doneSetArgs
    标记(标签),goto命令用来跳转,上面的第24条语句用到了该标记,起到了结束循环的作用。
  5. call "%EXECUTABLE%" start %CMD_LINE_ARGS%
    调用EXECUTABLE环境变量所指向的程序,即catalina.bat,其后跟的第一个参数是start,表示启动Tomcat,如果是stop,则停掉Tomcat,第二个参数是把CMD_LINE_ARGS作为参数传递进去;
  6. :end
    标记,可以用goto命令跳转到此处,直接结束此处批处理命令。

能坚持到这里,相信大家一定会有所收获,另外,如果觉得笔者写得还八错,期待后续的博文可以点波关注哈!

知我所能,我所能者,尽善尽美; 知我所不能,我所不能者,虚怀若谷!

我是喜欢分享知识、喜欢写博客的YuShiwen,与大家一起学习,共同成长!咋们下篇博文见。


已完结
author:YuShiwen
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。