简略描述发生了什么 :在 Tomcat 软件和项目工件完全一样的情况下 ,使用 Idea 运行一切正常 ,而手动使用 Tomcat 运行就会出现错误 。
这时 ,你可能马上就准备打字告诉我 “还以为啥呢 ,八成是因为你的这两个 Tomcat 版本不一致引起的” 。
如果真的只是这样 ,我就不会说 “灵异事件” 了 。下面请看我的详细描述 。
----------------------------------------------------------------------------------
1)电脑上只安装了 Tomcat 10 ,给 Idea 配置的 Tomcat 也正是这个(这点我确定过很多次了)。
2)使用 Idea 启动 Tomcat ,配置的 JDK 版本是 10 。启动后 ,访问项目一切正常(具体指 ,@WebServlet 等等注解都生效 ,后台也不会报 500 错误)。
3)把 Idea 构建好的工件原封不动粘贴到 Tomcat 的 Webapps 文件夹 ,CMD 使用 startup.bat 启动 。访问项目 ,此时灵异事件来了 :
一)首先是 500 错误 ,报错信息为 “.class 文件版本过高 ,请使用更低版本的 JDK” 。
二)其次是 404 ,也就是说 ,@WebServlet 等等注解全部失效了 。
显然 ,灵异之处有二 :
一)同样是 Tomcat 10 ,为什么被 Idea 代理的时候可以支持 JDK 10 编译出来的 .class ,而我们亲自操作 Tomcat 10 的话它就不支持 JDK 10 的版本了 。
二)在 Idea 代理的时候 @WebServlet 等等注解是完全可以正常生效的 ,而我们亲自操作 Tomcat 10 的时候 ,Tomcat 进程就不再识别注解了 。
----------------------------------------------------------------------------------
我再强调一次 ,我可是把 Idea 构建的工件原封不动地复制粘贴到 Webapps 文件夹 。唯一的差别就是没有使用 Idea 代理 Tomcat ,结果却引发了无法解释的现象 。
本人经过及其漫长的摸索 ,终于解决了问题 。根本原因是 ,文中两次启动 Tomcat 进程所使用的 java 指令的版本是不同的 。Idea 代理 Tomcat 的话 ,会临时指定一个用于运行 Tomcat 进程的 JDK ,而我们亲自使用 startup.bat 的时候默认是使用 环境变量 JRE_HOME 指向的 JDK 。在 Idea 的 Tomcat 的运行配置中可以看到 Idea 临时设置的 JDK 版本 ,我们只要把 JRE_HOME 设置成和它一样 ,问题就完美解决了 。