根本原因是tomcat启动时未读取系统环境变量,而优先加载$catalina_home/bin/setenv.sh(linux/macos)或setenv.bat(windows)中的配置;该文件必须存在、路径正确、权限可执行(linux/macos)或命名规范(windows),且内容仅设java_home和jre_home,不设catalina_home。

为什么改了环境变量 Tomcat 还报错
根本原因不是没配,而是 Tomcat 启动时压根没读到你设的变量。Windows 下双击 startup.bat 或从资源管理器打开命令行,会继承系统变量;但如果你用 VS Code 终端、Git Bash、或宝塔面板后台执行脚本,它们往往不加载系统级环境变量,尤其宝塔默认只认 $CATALINA_HOME/bin/setenv.sh 里的定义。
setenv.sh 是 Tomcat 真正认的“权威配置”
无论系统变量是否正确,Tomcat 启动脚本(catalina.sh)会优先读取同目录下的 setenv.sh。它不存在就新建,存在就追加,比改系统变量更直接可靠。
-
setenv.sh必须放在$CATALINA_HOME/bin/目录下,且文件权限为可执行(Linux/macOS 执行chmod +x setenv.sh) - 内容只需两行(路径按实际替换):
export JAVA_HOME=/www/server/jdk<br>export JRE_HOME=$JAVA_HOME/jre
- 不要写
export CATALINA_HOME=...—— 这个变量由启动脚本自动推导,硬写反而可能出错 - 修改后不用重启系统,但必须用
./startup.sh(而非双击)重新触发脚本加载
echo $JAVA_HOME 显示正确 ≠ Tomcat 能用
你在终端里 echo $JAVA_HOME 出来是 OK 的,不代表 Tomcat 进程里也一样。因为 Tomcat 可能以另一个用户(如 www)运行,而该用户 shell 并未 source 你的 ~/.bashrc。
- 验证方式不是看当前终端,而是进
$CATALINA_HOME/logs/catalina.out,搜索JAVA_HOME或Using Java行,那里显示的才是 Tomcat 实际用的值 - 宝塔环境下,
source $CATALINA_HOME/bin/setenv.sh && echo $JAVA_HOME必须在www用户上下文里执行(比如用宝塔终端切到 www 用户,或用sudo -u www bash -c "source ...") - 如果
catalina.out里出现The JRE_HOME environment variable is not defined correctly,90% 是setenv.sh里JRE_HOME指向了不存在的路径,或路径含空格没加引号
Windows 上 setenv.bat 容易被忽略的细节
很多人只配了系统变量,却忘了 Windows 版 Tomcat 同样依赖 setenv.bat,而且它比系统变量优先级更高。
-
setenv.bat文件名不能带空格或中文,必须放在%CATALINA_HOME%\bin\下 - 内容格式严格:用
set JAVA_HOME=C:\Program Files\Java\jdk-17,但路径含空格时必须加英文双引号:set JAVA_HOME="C:\Program Files\Java\jdk-17" - 不要用
setx命令写入注册表式变量——startup.bat不读那种 - 改完后务必关闭所有 CMD/PowerShell 窗口再重开,否则旧进程缓存还在











