Script to restart Tomcat in Windows


The first code
I was trying to implement a script to restart Tomcat Server without need to be aware if stopped.
My first Script was this:

restart_tomcat.bat

@echo off
set "CATALINA_HOME=C:\ServerWeb\Tomcat"
set "STOP=%CATALINA_HOME%\bin\shutdown.bat"
set "START=%CATALINA_HOME%\bin\startup.bat"
@echo on
call %STOP%
timeout /t 2
call %START%
timeout /t 2

restart_tomcat
But really, this script doesn’t work like I want.
The problem, is that this script doesn’t test the Tomcat state.
The call process to Stop it, and the Timeout really isn’t proper to wait if Tomcat was stopped.
This my first code and worst, because this method does not consider or take into account the speed of the computer (processor, memory and running processes) and the time it takes to execute.

Service or Process

Another thing that should be considered is how the Tomcat server is executing, like Process or like Service…
Other mistake was to considere Tomcat always is runnig like Service.

check_running.bat

@echo off
cls
setlocal enableextensions disabledelayedexpansion
set "serviceName="
set "SERVICE=Tomcat"
for /f "tokens=2" %%s in ('sc query state^= all ^| find /I "%SERVICE%"') do (
  set "serviceName=%%s"
)
 
 
sc query %serviceName%| find /i "RUNNING"> NUL
if not ERRORLEVEL 1 (
  echo %SERVICE% is running
  goto :end0
) else (
  echo %SERVICE% is not running
  goto :end0
)
:end0
 
 
sc query type= service state= inactive| find "%serviceName%"> NUL
if not ERRORLEVEL 1 (
  echo %SERVICE% is not running
  goto :end1
) else (
  echo %SERVICE% is running
  goto :end1
)
 
 
sc query type= service | find "%serviceName%"> NUL
if not ERRORLEVEL 1 (
  echo %SERVICE% is running
  goto :end2
) else (
  echo %SERVICE% is not running
  goto :end2
)
:end2
 
 
set "SERVICE=Tomcat"
tasklist /FI "SessionName eq services" | find /I "%SERVICE%" | find /I ".exe"> NUL
if not ERRORLEVEL 1 (
  echo %SERVICE% is running
  goto :end3
) else (
  echo %SERVICE% is not running
  goto :end3
)
:end3

Obviously this code is not debugged.

Only Checking Service
Acording to this, the Server Tomcat is not running, yes it is not running like Service.

Checking Port
But, as you can see the tomcat port is being used. Then the Server Tomcat is running like Process.

Checking the Tomcat port
Now, lets go to check who using the Tomcat port, I made my script:

check_running.bat

@echo off
 
if "x%1x" == "xx" goto displayUsage
set numberPort=%1
rem unusedPort flag to verify if PID was exploiter of required Port.
set "unusedPort="
rem lastPID avoid repeat PID
set "lastPID="
rem netstat -nao | find /i ":8080 " | find /i "LISTENING"
for /f "delims=" %%s in ('netstat -nao ^| find /i ":%numberPort% " ^| find /i "LISTENING"') do (
  rem Separate Connections using required port
  rem   TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       1960
  for /f "tokens=2" %%# in ("%%s") do (
    rem Separate Local Address
    rem 0.0.0.0:80
    echo.%%# | findstr /C:":%numberPort% " 1> nul
    if not ERRORLEVEL 1 (
      for /f "tokens=5" %%p in ("%%s") do (
        rem Separate PID
        rem 1960
        rem tasklist /fi "pid eq %%p"
        set "unusedPort=false"
        rem if not defined lastPID (
        rem if not "%%p"=="%lastPID%" (
        if not defined lastPID (
          set "lastPID=%%p"
          2>nul Wmic service where "ProcessId like '%%p'" get Name, PathName, ProcessId, State| findstr /i "Name"> nul
          if ERRORLEVEL 1 (
            rem echo %%p is a process using the Port %numberPort%!
            for /f "skip=3 delims=1" %%i in ('tasklist /fi "pid eq %%p"') do (
              for /f "tokens=1" %%n in ("%%i") do (
                echo The %numberPort% port is being used with PID %%p by %%n process:
              )
            )
            Wmic process where "ProcessId like '%%p'" get Name
          ) else (
            for /f "skip=3 delims=1" %%i in ('tasklist /fi "pid eq %%p"') do (
              for /f "tokens=1" %%n in ("%%i") do (
                echo The %numberPort% port is being used with PID %%p by %%n service:
              )
            )
            rem echo %%p is a service using the Port %numberPort%!
            Wmic service where "ProcessId like '%%p'" get Name, PathName, State
          )
        )
      )
    )
  )
)
 
netstat -nao | find /i ":%numberPort% "> nul
if ERRORLEVEL 1 (
  echo The %numberPort% port is not being used in Local Address.
) else (
  if not defined unusedPort (
    echo The %numberPort% port is not being used in Local Address.
  )
)
goto :end
 
:displayUsage
echo.
echo Usage: %~n0.bat [port]
 
 
:end
 
timeout /t 2

Testing my script I can see “who” is using the 8080 Port, and is javaw.exe like Process.
ExploiterPort 8080 Process

Starting Server Tomcat like Console:
StartingTomcat_Console_TS
ExploiterPort 8080 Tomcat_Console_TS

I turn off, the process manually.
ExploiterPort 8080 Unused

Starting Server Tomcat like Service manually and testing.
ExploiterPort 8080 Service

My Script is useful to check another port, like 80 for Httpd or another port.
ExploiterPort 80 Service

With this clear and after analyzing the behavior to start or stop the Tomcat server, such as service or process, I made my new script.

restart_tomcat.bat

@echo off
setlocal
set "CATALINA_HOME=C:\ServerWeb\Tomcat"
set "DELLOGS=%CATALINA_HOME%\logs\*.log"
set "DELTXTS=%CATALINA_HOME%\logs\*.txt"
set "DELALLS=%CATALINA_HOME%\logs\*.*"
rem  C:\ServerWeb\Tomcat\bin\tomcat7.exe //SS//Tomcat7.0.50
set "STOP=%CATALINA_HOME%\bin\shutdown.bat"
rem  C:\ServerWeb\Tomcat\bin\tomcat7.exe //RS//Tomcat7.0.50  (Doesn't work!)
set "START=%CATALINA_HOME%\bin\startup.bat"
 
 
set "serviceCheck=Tomcat"
rem serviceCheck: Tomcat7 or Tomcat8
set "processCheck=Tomcat"
rem processCheck: tomcat7.exe or tomcat8.exe
set "executorPort=8080"
set "shutdownPort=8005"
 
set "serviceName="
set "serviceRunning="
set "processPID="
 
if "x%1x" == "xx" goto beginRestart
set firstArg=%1
if "x%2x" == "xx" goto check_firstArg
set secndArg=%2
 
set "deleting="
set "bverbose="
 
rem Only 2 arguments are allowed
if not "x%3x" == "xx" goto displayUsage
 
if %firstArg% == %secndArg% goto displayUsage
 
:check_secndArg
if "%secndArg%" == "dellogs" (
  set deleting=%secndArg%
) else (
  if "%secndArg%" == "verbose" (
    set "bverbose=%secndArg%"
  ) else (
    goto displayUsage
  )
)
:check_firstArg
if "%firstArg%" == "dellogs" (
  set "deleting=%firstArg%"
) else (
  if "%firstArg%" == "verbose" (
    set "bverbose=%firstArg%"
  ) else (
    goto displayUsage
  )
)
 
:beginRestart
call :getServiceName
if defined serviceName (
  rem call :checkServiceRunning
  call :serviceAvailableStop
  if defined serviceRunning (
    rem the service is running, stop the service
    if defined bverbose (
      echo.
      echo Stopping %serviceCheck%, like %serviceName% service...
      echo.
    )
    call :getPID
    call :Restarting
  ) else (
    rem the service was not running, trying with the port like process
    call :getPID
    if defined processPID (
      for /f "delims=" %%i in ('netstat -nao ^| find /i ":%executorPort% " ^| find /i "LISTENING"') do (
        for /f "tokens=2" %%o in ("%%i") do (
          echo.%%o | findstr /C:":%executorPort% " 1>nul
          if not ERRORLEVEL 1 (
            for /f "tokens=5" %%u in ("%%i") do (
              if defined bverbose (
                echo.
                echo Stopping the %serviceCheck% like %%u PID process...
                echo.
              )
            )
          )
        )
      )
      call :Restarting
    ) else (
      if defined bverbose (
        echo.
        echo %serviceCheck% was not running.
        echo.
      )
      call :Starting
    )
  )
)
 
 
:getServiceName
rem To obtain the real (exact) name of service.
for /f "tokens=2" %%s in ('sc query state^= all ^| find /I "%serviceCheck%"') do (
  set "serviceName=%%s"
)
exit /b 0
 
 
:checkServiceRunning
rem To check if real service is running...
if defined serviceName (
  sc query %serviceName%| find /i "RUNNING">nul
  if not ERRORLEVEL 1 (
    rem service was found running
    set "serviceRunning=%serviceName%"
  )
)
exit /b 0
 
 
:serviceAvailableStop
tasklist /FI "SessionName eq services" | find /I "%processCheck%" | find /I ".exe">nul
if not ERRORLEVEL 1 (
  rem %processCheck% is running, is needed if shutdown port is available
  netstat -nao | find /i ":%shutdownPort% " | find /i "LISTENING">nul
  if not ERRORLEVEL 1 (
    set "serviceRunning=%serviceName%"
    exit /b 0
  ) else (
    rem service was found running, but is not available to stop
    goto :serviceAvailableStop
  )
) else (
  rem verify is starting
  sc query %serviceName%| find /i "START_PENDING">nul
  if not ERRORLEVEL 1 (
    rem service was found starting
    goto :serviceAvailableStop
  )
  rem verify is running
  sc query %serviceName%| find /i "RUNNING">nul
  if not ERRORLEVEL 1 (
    rem service was found running
    goto :serviceAvailableStop
  )
)
exit /b 0
 
:serviceIsOff
rem Wait until Service ends
tasklist /FI "SessionName eq services" | find /I "%processCheck%" | find /I ".exe">nul
if ERRORLEVEL 1 (
  sc query %serviceName%| find /i "STOPPED">nul
  if not ERRORLEVEL 1 (
    netstat -nao | find /i ":%executorPort% " | find /i "LISTENING">nul
    if ERRORLEVEL 1 (
      exit /b 0
    )
  )
)
ping 127.0.0.1 -n 1 >nul 2>&1 || PING ::1 -n 1 >nul 2>&1
goto :serviceIsOff
 
:processIsOff
netstat -nao | find /i ":%executorPort% " | find /i "LISTENING">nul
if ERRORLEVEL 1 (
  exit /b 0
)
ping 127.0.0.1 -n 1 >nul 2>&1 || PING ::1 -n 1 >nul 2>&1
goto :processIsOff
 
 
:serviceIsOn
rem Wait until service starts completely
sc query %serviceName%| find /i "RUNNING">nul
if not ERRORLEVEL 1 (
  netstat -nao | find /i ":%executorPort% " | find /i "LISTENING">nul
  if not ERRORLEVEL 1 (
    netstat -nao | find /i ":%shutdownPort% " | find /i "LISTENING">nul
    if not ERRORLEVEL 1 (
      exit /b 0
    )
  )
)
ping 127.0.0.1 -n 1 >nul 2>&1 || PING ::1 -n 1 >nul 2>&1
goto :serviceIsOn
 
 
:processIsOn
rem Wait until process starts completely
netstat -nao | find /i ":%executorPort% " | find /i "LISTENING">nul
if not ERRORLEVEL 1 (
  netstat -nao | find /i ":%shutdownPort% " | find /i "LISTENING">nul
  if not ERRORLEVEL 1 (
    exit /b 0
  )
)
ping 127.0.0.1 -n 1 >nul 2>&1 || PING ::1 -n 1 >nul 2>&1
goto :processIsOn
 
:getPID
rem Obtain the PID of process using the 8080 port
set "intPID="
for /f "delims=" %%s in ('netstat -nao ^| find /i ":%executorPort% " ^| find /i "LISTENING"') do (
  for /f "tokens=2" %%# in ("%%s") do (
    echo.%%# | findstr /C:":%executorPort% " 1>nul
    if not ERRORLEVEL 1 (
      for /f "tokens=5" %%p in ("%%s") do (
        if not defined intPID (
          set intPID=%%p
          goto stopGetPID
        )
      )
    )
  )
)
:stopGetPID
set "processPID=%intPID%"
exit /b 0
 
 
:Restarting
rem if process or services is running, then call stop
rem after wait until 8080 TIME_WAIT was finished,
rem later call process to start again
 
rem avoid call STOP if server is starting then wait...
 
if defined serviceRunning (
  call :serviceIsOn
  if defined bverbose (
    net session>nul 2>&1
    if not ERRORLEVEL 1 (
      net stop %serviceName%
    ) else (
      call %STOP%
    )
  ) else (
    call %STOP%>nul
  )
  call :serviceIsOff
  call :processIsOff
  if defined bverbose (
    echo.
    echo The %serviceCheck% like %serviceName% service was stopped.
    echo.
  )
) else (
  call :processIsOn
  if defined bverbose (
    call %STOP%
  ) else (
    call %STOP%>nul
  )
  call :serviceIsOff
  call :processIsOff
  if defined bverbose (
    echo.
    echo The %serviceCheck% with %processPID% PID was stopped.
    echo.
  )
)
 
call :Starting
goto:eof
 
 
:Starting
rem The Start process or service take a time, this in charge to do it.
rem before check if deleted logs file is requested
if not defined deleting goto nodellogs
if defined bverbose (
  echo Deleting the log files...
  echo.
)
del %DELALLS% /q
:nodellogs
net session>nul 2>&1
if not ERRORLEVEL 1 (
  if defined bverbose (
    echo Starting the %serviceCheck% service...
    echo.
    net start %serviceName%
  ) else (
    net start %serviceName%>nul
  )
  call :serviceIsOn
  if defined bverbose (
    echo.
    echo The %serviceCheck% was started like %serviceName% service.
  )
) else (
  if defined bverbose (
    echo Starting the %serviceCheck% process...
    echo.
    call %START%
  ) else (
    call %START%>nul
  )
  call :processIsOn
  set "processPID="
  call :getPID
  if defined bverbose (
    echo.
    echo The %serviceCheck% was started like process with %processPID% PID.
  )
)
goto:eof
 
 
:displayUsage
echo.
echo Usage: %~n0.bat [dellogs] [verbose]
 
 
:end

I included two optional arguments:
[dellogs] to delete all files of \logs subdirectory of Tomcat’s folder, useful when you want to see clean start or stop of Tomcat.
[verbose] to show greater information of process stop and start of Tomcat.

Testing my code:

RestartingTomcat

Now lets go make test in quietly manner.

RestartingTomcatAndCheckingPort

Running my script like Administrator, I can Stop and Start Tomcat like Service:
RestartingTomcat_Service

After of Stop Tomcat manually, I run this Script without Delete log files:
StartingTomcat_ServiceLikeAdministrator_NoDeleting
Now, with this We finished with my post of Tomcat’s restart.

I like your comments about this post.

Bye.

Anuncios

Acerca de joseluisbz

Hasta ahora, espero actualizarlo después, ahora no.
Esta entrada fue publicada en Scripts, Server, Software, Tomcat, Web Server, Windows y etiquetada , , , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s