diff --git a/bin/as-service.bat b/bin/as-service.bat index c7ca6c1fc..4dd8dc266 100755 --- a/bin/as-service.bat +++ b/bin/as-service.bat @@ -1,33 +1,34 @@ @echo off REM DON'T CHANGE THE FIRST LINE OF THE FILE, WINDOWS SERVICE RUN BAT NEED IT! (@echo off) -REM specify JAVA_HOME here -REM set PRE_JAVA_HOME=C:\Program Files\Java\jdk1.8.0_131 -REM set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_201 +REM don't call 'echo' before 'start as.bat' +REM You can specify Java Home via AS_JAVA_HOME here or Windows System Environment, but not in cmd.exe +REM set AS_JAVA_HOME=C:\Program Files\Java\jdk1.8.0_131 set basedir=%~dp0 set filename=%~nx0 -set srv_name=arthas_srv -set srv_interact=false +set srv_name=arthas set telnet_port=3658 set http_port=8563 REM parse extend args set arg1=%1 -set arg2=%2 -set AS_ARGS= -set AS_WAIT=/wait +set pid= +set port= +set ignoreTools=0 +set as_remove_srv=0 +set as_service=0 +set srv_interact=0 for %%a in (%*) do ( - if "%%a"=="--ignore-tools" set AS_ARGS=%AS_ARGS% --ignore-tools - if "%%a"=="--interact" ( - set AS_WAIT= - set AS_ARGS=%AS_ARGS% --interact - set srv_interact=true - ) + if "%%a"=="--remove" set as_remove_srv=1 + if "%%a"=="--service" set as_service=1 + if "%%a"=="--interact" set srv_interact=1 + if "%%a"=="--ignore-tools" set ignoreTools=1 ) -REM from https://stackoverflow.com/a/35445653 + +REM Parse command line args (https://stackoverflow.com/a/35445653) :read_params if not %1/==/ ( if not "%__var%"=="" ( @@ -45,54 +46,63 @@ if not %1/==/ ( if not "%telnet-port%"=="" set telnet_port=%telnet-port% if not "%http-port%"=="" set http_port=%http-port% -REM decode path: '@' -> ' ' -if not "%my_java_home%"=="" set JAVA_HOME=%my_java_home:@= % REM Setup JAVA_HOME -REM set JAVA_HOME=%JAVA_HOME:"=% -if "%JAVA_HOME%" == "" goto noJavaHome +REM Decode -java-home: '@' -> ' ' +if not "%java-home%"=="" set JAVA_HOME=%java-home:@= % +REM If has AS_JAVA_HOME, overriding JAVA_HOME +if not "%AS_JAVA_HOME%" == "" set JAVA_HOME=%AS_JAVA_HOME% +REM use defined is better then "%var%" == "", avoid trouble of "" +if not defined JAVA_HOME goto noJavaHome +REM Remove "" in path +set JAVA_HOME=%JAVA_HOME:"=% if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome +if %ignoreTools% == 1 ( + echo Ignore tools.jar, make sure the java version ^>^= 9 +) else ( + if not exist "%JAVA_HOME%\lib\tools.jar" ( + echo Can not find lib\tools.jar under %JAVA_HOME%! + echo If java version ^<^= 1.8, please make sure JAVA_HOME point to a JDK not a JRE. + echo If java version ^>^= 9, try to run %filename% ^ --ignore-tools + goto :end + ) +) set JAVACMD="%JAVA_HOME%\bin\java" -REM Runas Service, do not call 'echo' before this line -if ["%arg1%"] == ["-service"] ( - set AS_ARGS=%AS_ARGS% -telnet-port %telnet_port% -http-port %http_port% - start %AS_WAIT% %basedir%\as.bat %arg2% %AS_ARGS% - exit 0 +REM Runas Service, don't call 'echo' before 'start as.bat' +set as_args=-telnet-port %telnet_port% -http-port %http_port% +if %srv_interact%==0 set as_args=%as_args% --no-interact +if %ignoreTools%==1 set as_args=%as_args% --ignore-tools +if %as_service%==1 ( + REM run as.bat + start /wait %basedir%\as.bat %pid% %as_args% + exit 0 + + REM DEBUG run args + REM echo as_args: %as_args% + REM echo start /wait %basedir%\as.bat %pid% %as_args% + REM exit /b 0 ) -if ["%arg1%"] == ["-port"] ( - set port=%arg2% - if "%port%" == "" goto :usage - goto :find_port -) -if ["%arg1%"] == ["-pid"] ( - set pid=%arg2% - if "%pid%" == "" goto :usage +REM If the first arg is a number, then set it as pid +echo %arg1%| findstr /r "^[1-9][0-9]*$">nul +if %errorlevel% equ 0 set pid=%arg1% + +echo pid: %pid% +echo port: %port% + +if not ["%pid%"] == [""] ( goto :prepare_srv ) -if ["%arg1%"] == ["-remove"] ( +if not ["%port%"] == [""] ( + goto :find_port +) +if %as_remove_srv%==1 ( goto :remove_srv ) goto :usage -:usage -echo Example: -echo %filename% -port java_port -echo %filename% -pid java_pid -echo %filename% -port 8080 -echo %filename% -pid 2351 -echo %filename% -remove ;remove arthas service -echo Need the port or pid argument. -exit /b -1 - -:noJavaHome -echo JAVA_HOME: %JAVA_HOME% -echo The JAVA_HOME environment variable is not defined correctly. -echo It is needed to run this program. -echo NB: JAVA_HOME should point to a JDK not a JRE. -exit /b -1 :remove_srv echo Removing service: %srv_name% ... @@ -102,6 +112,11 @@ exit /b 0 :find_port +netstat -nao |findstr LIST |findstr :%telnet_port% +IF %ERRORLEVEL% EQU 0 ( + echo Arthas agent already running, just connect to it! + goto :attachSuccess +) @rem find pid by port echo %port%| findstr /r "^[1-9][0-9]*$">nul if %errorlevel% neq 0 ( @@ -123,6 +138,14 @@ echo Target process pid is %pid% :prepare_srv +REM check telnet port +netstat -nao |findstr LIST |findstr :%telnet_port% +IF %ERRORLEVEL% EQU 0 ( + echo Arthas agent already running, just connect to it! + goto :attachSuccess +) + +REM validate pid echo %pid%| findstr /r "^[1-9][0-9]*$">nul if %errorlevel% neq 0 ( echo PID is not valid number! @@ -130,22 +153,36 @@ if %errorlevel% neq 0 ( ) echo Preparing arthas service and injecting arthas agent to process: %pid% ... -REM encode path: ' ' -> '@' -set srv_java_home=-my_java_home %JAVA_HOME: =@% -set srv_port=-telnet-port %telnet_port% -http-port %http_port% -set srv_type=type= own -set srv_binpath=binPath= "%basedir%\%filename% -service %pid% %srv_port% %srv_java_home% --no-interact" -if "%srv_interact%" == "true" ( +REM encode java path, avoid space in service args: ' ' -> '@' +set srv_java_home=-java-home %JAVA_HOME: =@% +set srv_args=-pid %pid% -telnet-port %telnet_port% -http-port %http_port% %srv_java_home% +if %srv_interact%==1 ( + sc start UI0Detect set srv_type=type= interact type= own - set srv_binpath=binPath= "%basedir%\%filename% -service %pid% %srv_port% %srv_java_home%" + set srv_binpath=binPath= "%basedir%\%filename% %srv_args% --service --interact" +) else ( + set srv_type=type= own + set srv_binpath=binPath= "%basedir%\%filename% %srv_args% --service" ) +echo arthas srv type: %srv_type% echo arthas srv binPath: %srv_binpath% -sc start UI0Detect + sc create %srv_name% start= demand %srv_type% %srv_binpath% sc config %srv_name% start= demand %srv_type% %srv_binpath% -sc stop %srv_name% -sc start %srv_name% +if %errorlevel% NEQ 0 ( + echo Config Arthas service failed + exit /b -1 +) +sc stop %srv_name% +REM fork start Arthas service, avoid blocking +if %srv_interact%==1 ( + start /B sc start %srv_name% +)else ( + start /B sc start %srv_name% > nul 2>&1 +) + +REM check and connect arthas .. echo Waitting for arthas agent ... set count=0 @@ -154,7 +191,7 @@ echo checking netstat -nao |findstr LIST |findstr :%telnet_port% IF %ERRORLEVEL% NEQ 0 ( set /a count+=1 - if %count% geq 4 ( + if %count% geq 8 ( echo Arthas agent telnet port is not ready, maybe inject failed. goto :end ) @@ -174,7 +211,7 @@ IF %ERRORLEVEL% NEQ 0 ( telnet 127.0.0.1 %telnet_port% ) -echo +echo( echo Checking arthas telnet port [:%telnet_port%] ... netstat -nao |findstr LIST |findstr :%telnet_port% IF %ERRORLEVEL% EQU 0 ( @@ -205,5 +242,40 @@ IF %ERRORLEVEL% EQU 0 ( ) else ( echo Arthas shutdown successfully. ) +goto :end + + + +:usage +echo Arthas for Windows Service. +echo Usage: +echo %filename% java_pid [option] .. +echo %filename% [-pid java_pid] [option] .. +echo %filename% [-port java_port] [option] .. +echo( +echo Options: +echo -pid java_pid : Attach by java process pid +echo -port java_port : Attach by java process listen port +echo -telnet-port port : Change arthas telnet port +echo -http-port port : Change arthas http/websocket port +echo --interact : Enable windows service interactive UI, useful for debug +echo --remove : Remove Arthas windows service +echo --ignore-tools : Ignore checking JAVA_HOME\lib\tools.jar for jdk 9/10/11 +echo( +echo Example: +echo %filename% 2351 +echo %filename% 2351 -telnet-port 2000 -http-port 2001 +echo %filename% -pid 2351 +echo %filename% -port 8080 --interact +echo %filename% --remove #remove arthas service +exit /b -1 + + +:noJavaHome +echo JAVA_HOME: %JAVA_HOME% +echo The JAVA_HOME environment variable is not defined correctly. +echo It is needed to run this program. +echo NB: JAVA_HOME should point to a JDK not a JRE. +exit /b -1 :end diff --git a/bin/as.bat b/bin/as.bat index 55853ecfa..ec028440e 100755 --- a/bin/as.bat +++ b/bin/as.bat @@ -101,7 +101,7 @@ set JAVACMD="%JAVA_HOME%"\bin\java %JAVACMD% -Dfile.encoding=UTF-8 %BOOT_CLASSPATH% -jar "%CORE_JAR%" -pid "%PID%" -target-ip 127.0.0.1 -telnet-port %TELNET_PORT% -http-port %HTTP_PORT% -core "%CORE_JAR%" -agent "%AGENT_JAR%" if %ERRORLEVEL% NEQ 0 goto exit_bat -if "%exitProcess%" == "true" goto :exit_bat +if %exitProcess%==1 goto exit_bat goto attachSuccess @@ -116,5 +116,5 @@ IF %ERRORLEVEL% NEQ 0 ( ) :exit_bat -if "%exitProcess%" == "true" exit %ERROR_CODE% +if %exitProcess%==1 exit %ERROR_CODE% exit /B %ERROR_CODE%