Tomcat 9.0.73中无法读取context.xml配置的Environment值
问题场景
context.xml配置项
<Environment name="environment" value="DEV" type="java.lang.String" override="false" />
对应的Servlet调用代码
try { Context initContext = new InitialContext(); environment = (String) initContext.lookup("environment"); } catch (final NamingException nx) { ERROR_RECORDER.error(nx.getMessage(), nx); }
抛出的异常信息
[Time: 16 Mar 2023 06:36:36,840][Thread: main][Log: ERROR_RECORDER.][Level: ERROR] - [File: ResponseTimeFilter.java:80] - Name [environment] is not bound in this Context. Unable to find [environment].
javax.naming.NameNotFoundException: Name [environment] is not bound in this Context. Unable to find [environment].
该配置和代码在其他容器运行正常,但Tomcat 9.0.73下出现上述异常。
解决步骤
使用完整JNDI命名空间查找
Tomcat中<Environment>默认绑定在java:comp/env命名空间下,直接用短名称查找无法定位。修改代码为以下两种方式之一:
方式一:直接使用完整路径environment = (String) initContext.lookup("java:comp/env/environment");方式二:先获取环境上下文再查找
Context initContext = new InitialContext(); Context envContext = (Context) initContext.lookup("java:comp/env"); environment = (String) envContext.lookup("environment");确认context.xml的放置位置
确保配置文件放在Tomcat能加载的目录:- 全局生效:放在
$TOMCAT_HOME/conf/context.xml - 仅当前应用生效:放在项目的
WEB-INF/META-INF/context.xml
- 全局生效:放在
排查配置冲突
检查应用内部是否存在重复名称的<Environment>配置,即使设置了override="false",如果应用内有同名配置,可能会导致全局配置不生效。可以暂时移除应用内的相关配置进行测试。验证Tomcat的JNDI配置
确认Tomcat的conf/server.xml中没有禁用JNDI相关功能,确保<GlobalNamingResources>配置正常,若使用全局资源则检查<ResourceLink>配置是否正确。
内容的提问来源于stack exchange,提问作者user4654707

