tomcat9使用指定的JDK版本完整步骤记录

 更新时间:2026年04月20日 11:03:41   作者:liweiweili126  
在服务器部署多个JDK版本的场景下,Tomcat默认读取系统环境变量可能导致版本冲突,下面这篇文章主要介绍了tomcat9使用指定的JDK版本的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

如果你想把JDK放到Tomcat9的根目录(CATALINA_HOME)下,通过相对路径配置专属JDK环境(不依赖系统全局JDK,实现Tomcat-JDK一体化),核心是利用Tomcat官方推荐的setenv(setclasspath)脚本配置JAVA_HOME(基于CATALINA_HOME的相对路径,避免修改原生启动脚本)。

第一步:标准化目录结构(关键)

先整理Tomcat9的目录,将解压版JDK(绿色版,非安装版)放到Tomcat根目录下的jdk子文件夹,结构如下(示例JDK8,Tomcat9推荐JDK8/JDK11,兼容最佳):

apache-tomcat-9.0.XX/  # Tomcat9根目录(即CATALINA_HOME)
├─ bin/                # Tomcat启动/停止脚本目录
├─ conf/               # 配置文件
├─ webapps/            # 项目部署目录
├─ jdk/                # 新建的JDK存放目录
│  └─ jdk1.8.0_391/    # 解压后的JDK完整目录(含bin、jre、lib等子文件夹)
├─ logs/               # 日志
└─ temp/               # 临时文件

注意:JDK目录名可自定义(如jdk11),但后续配置要对应,禁止有中文/空格/特殊字符

第二步:核心配置(分Windows/Linux/Mac,二选一)

Tomcat启动时会自动加载bin目录下的setenv.bat(Windows)/setenv.sh(Linux/Mac),这是官方推荐的自定义环境变量的专属文件(不会在Tomcat升级时被覆盖,比直接改catalina.bat/sh更安全),该文件默认不存在,需要手动新建

配置的核心:基于Tomcat内置的CATALINA_HOME(已自动指向Tomcat根目录)写相对路径,而非./../(避免启动目录不同导致路径失效)。

场景1:Windows系统(.bat脚本)

  1. 在Tomcat的bin目录下,新建文本文件,重命名为setenv.bat后缀必须是.bat,无txt后缀);
  2. 编辑setenv.bat,写入以下内容(仅配置JAVA_HOME即可,Tomcat会自动识别JDK内的JRE):
@echo off
:: 基于CATALINA_HOME(Tomcat根目录)配置相对路径的JAVA_HOME,指向jdk子目录下的JDK解压包
set "JAVA_HOME=%CATALINA_HOME%\jdk\jdk1.8.0_391"
:: 可选:设置JVM运行参数(如堆内存),按需添加
set "JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"

替换jdk1.8.0_391为你实际的JDK目录名,%CATALINA_HOME%是Tomcat内置变量,无需手动定义。

场景2:Linux/Mac系统(.sh脚本)

  1. 在Tomcat的bin目录下,新建setenv.sh文件:
touch TOMCAT_HOME/bin/setenv.sh
  1. 编辑setenv.sh,写入以下内容(语法与Windows不同,注意空格和引号):
#!/bin/sh
# 基于CATALINA_HOME配置相对路径的JAVA_HOME
export JAVA_HOME=$CATALINA_HOME/jdk/jdk1.8.0_391
# 可选:JVM运行参数
export JAVA_OPTS="-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"
  1. setenv.sh添加执行权限(Linux/Mac必须,否则Tomcat无法加载):
chmod +x TOMCAT_HOME/bin/setenv.sh

第三步:测试启动,验证JDK配置

无需配置系统全局的JAVA_HOME/JRE_HOME,直接用Tomcat原生启动脚本启动,会自动加载setenv中的专属JDK:

Windows

双击Tomcatbin目录下的startup.bat,或在CMD中执行:

cd TOMCAT_HOME/bin
startup.bat

启动窗口会显示JVM版本,且日志中会标注使用的JDK路径为Tomcat下的专属JDK。

Linux/Mac

在终端执行启动脚本:

cd TOMCAT_HOME/bin
./startup.sh

通过Tomcat日志验证JDK是否生效(核心看Java Home路径):

# 查看启动日志,搜索Java Home
grep "Java Home" TOMCAT_HOME/logs/catalina.out

正确输出示例(路径指向Tomcat下的JDK):

Java Home:         /opt/apache-tomcat-9.0.90/jdk/jdk1.8.0_391/jre

关键避坑点

  1. JDK必须是解压版:不能用安装版JDK(安装版会写入系统注册表,无法通过相对路径独立使用),直接从Oracle/OpenJDK官网下载解压版JDK即可;
  2. 禁止修改原生脚本:不要直接改catalina.bat/sh/startup.bat/sh,这些是Tomcat原生文件,升级时会被覆盖,setenv是官方预留的自定义入口;
  3. 无中文/空格路径:Tomcat根目录、JDK目录全程禁止中文、空格、特殊字符(如*#),否则会报“路径找不到”错误;
  4. 相对路径基于CATALINA_HOME:不要用./jdk/xxx../jdk/xxx,因为如果在非Tomcat目录启动脚本,这类相对路径会失效,而%CATALINA_HOME%/$CATALINA_HOME是Tomcat内置的绝对路径变量,永远指向根目录;
  5. Tomcat9的JDK兼容:最低支持JDK8,推荐JDK8/JDK11,不建议用JDK17+(部分特性兼容不佳)。

第四步:停止Tomcat(原生脚本即可)

无需额外配置,直接用Tomcatbin目录下的停止脚本,会自动使用同一JDK环境:

  • Windows:shutdown.bat
  • Linux/Mac:./shutdown.sh

总结

  1. 核心目录结构:Tomcat根目录下新建jdk文件夹,放入解压版JDK,实现一体化;
  2. 专属配置文件:在bin目录新建setenv.bat/sh,利用Tomcat内置的CATALINA_HOME配置相对路径的JAVA_HOME,无需系统全局JDK;
  3. 跨目录启动无忧:基于CATALINA_HOME的相对路径,无论在哪个目录执行Tomcat启动脚本,JDK路径都不会失效;
  4. 升级友好:setenv文件不会被Tomcat升级覆盖,后续换JDK只需修改该文件的JDK目录名即可。

这种配置方式的优势是Tomcat-JDK一体化,可直接拷贝整个Tomcat目录到其他同系统服务器,无需重新配置JDK环境,直接启动即可使用。

另外如果你发现Tomcat9的bin目录里有setclasspath.sh(Linux/Mac)/setclasspath.bat(Windows),这个文件是Tomcat原生的核心脚本,启动时会被catalina.sh/bat自动加载,作用是检测并设置JDK/JRE的类路径、验证JAVA_HOME/JRE_HOME的有效性——这和我们之前配置setenv.sh的方案完全兼容,甚至可以说setclasspath.sh正是我们用setenv.sh配置相对路径JDK的“底层支撑”,不用修改这个原生文件,继续按之前的方法配置即可。

下面给你讲清楚这个文件的核心逻辑、和setenv.sh的加载顺序,以及为什么绝对不要修改它,同时补充验证细节,让你彻底放心配置。

一、setclasspath.sh 核心作用(Tomcat原生,无需改动)

这个文件是Tomcat官方写的JDK路径检测脚本,核心逻辑只有2点:

  1. 优先读取已设置的JAVA_HOME/JRE_HOME:如果我们在setenv.sh里提前设置了JAVA_HOME(Tomcat下的专属JDK),setclasspath.sh会直接复用这个变量,不会再去检测系统全局的JDK;
  2. 若未设置,则自动查找系统JDK:如果没配JAVA_HOME,它会遍历系统路径找jdk/jre,找不到就直接报错启动失败(这也是Tomcat默认需要系统全局JDK的原因)。

简单说:setclasspath.sh是“JDK路径检测器”,而setenv.sh是“JDK路径配置器”,我们的配置会被检测器优先读取,完美契合Tomcat的原生启动逻辑。

二、Tomcat启动脚本的加载顺序(关键,解释为什么setenv.sh生效)

Tomcat9的启动脚本执行流程是层层加载的,setenv.sh的配置会提前于setclasspath.sh生效,确保JDK路径被优先设置,顺序如下(Linux/Mac为例,Windows逻辑完全一致):

startup.sh → catalina.sh → setenv.sh(自定义,优先加载)→ setclasspath.sh(原生,检测JDK)→ 启动Tomcat

✅ 结论:你之前按我给的方法新建setenv.sh配置相对路径JAVA_HOME,完全不会和setclasspath.sh冲突,反而会被它优先使用,无需对这个原生文件做任何修改(改了会被Tomcat升级覆盖,还可能导致启动逻辑出错)。

三、补充:利用setclasspath.sh验证JDK配置(可选)

如果想快速验证setenv.sh里的JAVA_HOME是否被正确读取,可以直接执行setclasspath.sh,它会输出JDK检测结果:

Linux/Mac执行命令

# 进入Tomcat的bin目录
cd CATALINA_HOME/bin
# 执行setclasspath.sh(会输出JDK检测日志,无报错即配置成功)
./setclasspath.sh
  • 配置成功:无任何报错,直接返回命令行;
  • 配置失败(如JDK目录写错):会明确报错JAVA_HOME is not defined correctly,提示找不到JDK,此时检查setenv.sh里的JDK相对路径即可。

Windows(对应setclasspath.bat)

cd CATALINA_HOME\bin
setclasspath.bat

同理,无报错即成功,报错则检查setenv.bat的路径。

四、再次强调:绝对不要修改setclasspath.sh/bat的3个原因

  1. 原生文件,升级会覆盖:Tomcat升级时,bin目录下的原生脚本(包括setclasspath.sh)会被新版本替换,你的修改会全部丢失;
  2. 逻辑复杂,易改崩:这个文件包含跨平台的JDK检测逻辑(兼容不同JDK版本、不同系统),新手修改容易破坏原有逻辑,导致Tomcat无法启动;
  3. 官方有预留入口:Tomcat官方明确推荐用setenv.sh/bat做自定义环境配置,这是专门为用户预留的“安全入口”,完全能满足JDK、JVM参数的配置需求。

总结

  1. bin目录下的setclasspath.sh是Tomcat原生的JDK路径检测脚本,无需修改、无需删除,我们的配置会被它优先读取;
  2. 继续按之前的方法在bin目录新建setenv.sh(Linux/Mac),用$CATALINA_HOME/jdk/你的JDK目录配置相对路径JAVA_HOME即可,完全兼容;
  3. Tomcat启动脚本的加载顺序是setenv.sh → setclasspath.sh,确保自定义JDK路径优先生效,实现Tomcat-JDK一体化(无需系统全局JDK);
  4. 可直接执行setclasspath.sh快速验证JDK配置是否正确,无报错即代表路径有效。

你现在直接按之前的步骤配置setenv.sh就行,这个原生的setclasspath.sh只会帮你“验证并使用”配置的JDK,不会有任何冲突~

到此这篇关于tomcat9使用指定的JDK版本的文章就介绍到这了,更多相关tomcat9使用指定JDK版本内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 内部类的定义与范例

    Java 内部类的定义与范例

    说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉。原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法。今天我们就来一探究竟
    2021-11-11
  • 从零开始手写JDBC连接数据库的详细指南

    从零开始手写JDBC连接数据库的详细指南

    在 Java 开发中,数据库是存储和管理数据的核心组件,JDBC是 Java 程序与数据库交互的标准 API,本文将带大家手写一个完整的 JDBC 连接数据库的示例,希望对大家有所帮助
    2025-07-07
  • SpringBoot内置tomcat调优测试优化

    SpringBoot内置tomcat调优测试优化

    这篇文章主要介绍了SpringBoot内置tomcat调优测试优化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • java集合类源码分析之Set详解

    java集合类源码分析之Set详解

    下面小编就为大家带来一篇java集合类源码分析之Set详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 详解Java虚拟机(JVM)运行时

    详解Java虚拟机(JVM)运行时

    JVM(Java虚拟机)是一个抽象的计算模型。这篇文章主要介绍了Java虚拟机(JVM)运行时的相关知识,需要的朋友可以参考下
    2018-10-10
  • Java 参数值传递机制的实现

    Java 参数值传递机制的实现

    本文主要介绍了Java 参数值传递机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-05-05
  • Java多态到底都有啥好处

    Java多态到底都有啥好处

    Java中的多态性有两种类型:编译时多态(静态绑定)和运行时多态(动态绑定)。方法重载是静态多态的一个例子,而方法重写是动态多态的一个例子,接下来通过本文给大家分享Java多态到底教了我干啥?有啥好处,一起了解下吧
    2021-05-05
  • Spring Security权限控制的实现接口

    Spring Security权限控制的实现接口

    这篇文章主要介绍了Spring Security的很多功能,在这些众多功能中,我们知道其核心功能其实就是认证+授权。Spring教程之Spring Security的四种权限控制方式
    2023-03-03
  • Spring注解@Qualifier的详细用法你知道几种

    Spring注解@Qualifier的详细用法你知道几种

    本文给大家分享Spring注解@Qualifier的详细用法,包括@Autowired和@Resource区别介绍,本文通过示例代码给大家详细介绍,感兴趣的朋友跟随小编一起看看吧
    2021-07-07
  • Java面向对象编程(封装/继承/多态)实例解析

    Java面向对象编程(封装/继承/多态)实例解析

    这篇文章主要介绍了Java面向对象编程(封装/继承/多态)实例解析的相关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10

最新评论