前言
最近做项目,测试环境出错了,需要tomcat远程调试,网上各种教程,都说要改catalina.sh或者catalina.bat。然后……反正异常麻烦,我研究了一下catalina.sh和catalina.bat,这样做完全违背了脚本开发者的初衷。
1. catalina.sh 远程调试启动讲解
在脚本的最后一段有说明如何使用,当然也可以直接./catalina.sh,看提示
echo "Usage: catalina.sh ( commands ... )"
echo "commands:"
if $os400; then
echo " debug Start Catalina in a debugger (not available on OS400)"
echo " debug -security Debug Catalina with a security manager (not available on OS400)"
else
echo " debug Start Catalina in a debugger"
echo " debug -security Debug Catalina with a security manager"
fi
echo " jpda start Start Catalina under JPDA debugger"
echo " run Start Catalina in the current window"
echo " run -security Start in the current window with security manager"
echo " start Start Catalina in a separate window"
echo " start -security Start in a separate window with security manager"
echo " stop Stop Catalina, waiting up to 5 seconds for the process to end"
echo " stop n Stop Catalina, waiting up to n seconds for the process to end"
echo " stop -force Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running"
echo " stop n -force Stop Catalina, wait up to n seconds and then use kill -KILL if still running"
echo " configtest Run a basic syntax check on server.xml - check exit code for result"
echo " version What version of tomcat are you running?"
echo "Note: Waiting for the process to end and use of the -force option require that \$CATALINA_PID is defined"
exit 1
关键在于
echo " jpda start Start Catalina under JPDA debugger"
这个就是作者告诉我们怎么用,调试模式仅需 ./catalina.sh jpda start即可
这个为什么能生效呢,关键在于
if [ "$1" = "jpda" ] ; then
if [ -z "$JPDA_TRANSPORT" ]; then
JPDA_TRANSPORT="dt_socket"
fi
if [ -z "$JPDA_ADDRESS" ]; then
JPDA_ADDRESS="localhost:8000"
fi
if [ -z "$JPDA_SUSPEND" ]; then
JPDA_SUSPEND="n"
fi
if [ -z "$JPDA_OPTS" ]; then
JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"
fi
CATALINA_OPTS="$JPDA_OPTS $CATALINA_OPTS"
shift
fi
如果第一个参数是jpda,设置一堆属性,然后
CATALINA_OPTS="$JPDA_OPTS $CATALINA_OPTS" 塞进catalina的参数中,但是这样会有一个问题
JPDA_ADDRESS与JPDA_SUSPEND等变量不能定制,只能使用默认,这个时候需要我们手写脚本修改这些变量值,但是我们不能改catalina.sh脚本,其实作者早就考虑到了。
windows系统同理
if not ""%1"" == ""jpda"" goto noJpda
set JPDA=jpda
if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport
set JPDA_TRANSPORT=dt_socket
:gotJpdaTransport
if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
set JPDA_ADDRESS=localhost:8000
:gotJpdaAddress
if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend
set JPDA_SUSPEND=n
:gotJpdaSuspend
if not "%JPDA_OPTS%" == "" goto gotJpdaOpts
set JPDA_OPTS=-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
:gotJpdaOpts
shift
:noJpda
rem Execute Java with the applicable properties
if not "%JPDA%" == "" goto doJpda
:doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda
%_EXECJAVA% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %JPDA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
2. setenv.sh初始化变量
在catalina.sh的开始就有说明
# -----------------------------------------------------------------------------
# Control Script for the CATALINA Server
#
# Environment Variable Prerequisites
#
# Do not set the variables in this script. Instead put them into a script
# setenv.sh in CATALINA_BASE/bin to keep your customizations separate.
#
# CATALINA_HOME May point at your Catalina "build" directory.
#
# CATALINA_BASE (Optional) Base directory for resolving dynamic portions
# of a Catalina installation. If not present, resolves to
# the same directory that CATALINA_HOME points to.
#
# CATALINA_OUT (Optional) Full path to a file where stdout and stderr
# will be redirected.
# Default is $CATALINA_BASE/logs/catalina.out
#
# CATALINA_OPTS (Optional) Java runtime options used when the "start",
# "run" or "debug" command is executed.
# Include here and not in JAVA_OPTS all options, that should
# only be used by Tomcat itself, not by the stop process,
# the version command etc.
# Examples are heap size, GC logging, JMX ports etc.
#............................
# JPDA_ADDRESS (Optional) Java runtime options used when the "jpda start"
# command is executed. The default is localhost:8000.
#
# JPDA_SUSPEND (Optional) Java runtime options used when the "jpda start"
# command is executed. Specifies whether JVM should suspend
# execution immediately after startup. Default is "n".
#...........................
# Do not set the variables in this script. Instead put them into a script
# setenv.sh in CATALINA_BASE/bin to keep your customizations separate.
作者让我们设置setenv.sh脚本来处理变量初始化赋值
我们来看看为什么,原来在catalina.sh脚本的开始就有if处理
if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
. "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
. "$CATALINA_HOME/bin/setenv.sh"
fi
如果存在setenv.sh脚本就执行
我们来试一下,vim setenv.sh设置远程端口吧
保存,授权sudo chmod +x setenv.sh
windows系统同理
rem Get standard environment variables
if not exist "%CATALINA_BASE%\bin\setenv.bat" goto checkSetenvHome
call "%CATALINA_BASE%\bin\setenv.bat"
goto setenvDone
:checkSetenvHome
if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat"
:setenvDone
windows仅需创建setenv.bat即可,比如
3.intellij 设置,eclipse同理
我们先启动tomcat,通过./catalina.sh jpda start
设置intellij
调试模式,默认为Attach to remote JVM
;
Attach to remote JVM
:调试服务端(运行程序的机器)启动一个端口等待调试客户端去连接;Listen to remote JVM
: 调试客户端去监听一个端口,当调试服务端(运行程序的机器)准备好了,就会进行连接。
写个接口试试
@RestController
public class HelloController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String sayHello(){
return "{\"hello\":\"ok my remote test\"}";
}
}
访问:http://localhost:8080/hello
说明生效了
总结
不需要修改catalina.sh脚本,仅需按照作者的规范即可,不需要调试即可使用startup脚本,无需修改脚本
调试参数仅需添加setenv.sh脚本即可