如何在启动时在 Tomcat 配置中指定系统属性?

我知道我可以通过传递带有 -D 参数的参数(例如“ - Dmy.prop = 价值”)来为 Tomcat 指定系统属性。

我想知道是否有一种更简洁的方法来实现这一点,即在 context.xml 文件或其他一些 tomcat 配置文件中指定属性值。我想这样做是因为,首先,跟踪我的属性更容易,其次,我有多个上下文运行,我不知道如何通过-D 参数指定上下文特定的属性。

我使用的是 Tomcat 5.5版。

185033 次浏览

(更新: 如果我可以删除这个答案,我会,虽然因为它被接受,我不能。我正在更新描述,以提供更好的指导,并阻止人们使用我在原始答案中概述的不良做法)。

您可以通过上下文或环境参数指定这些参数,例如 context.xml 中的参数。请参阅本页标题为“上下文参数”和“环境条目”的部分:

Http://tomcat.apache.org/tomcat-5.5-doc/config/context.html

正如@netjeff 指出的,这些值将通过 Context.lookup (String)方法而不是作为 System 参数提供。

指定这些值的另一种方法是在要部署的 Web 应用程序的 web.xml 文件中定义变量(见下文)。正如@Roberto Lo Giacco 所指出的,这通常被认为是一种糟糕的实践,因为已部署的构件不应该是特定于环境的。但是,如果您真的想这样做,下面是配置代码片段:

<env-entry>
<env-entry-name>SMTP_PASSWORD</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>abc123ftw</env-entry-value>
</env-entry>

一般来说,你不应该依赖系统属性来配置 webapp ——它们可以用来配置容器(例如 Tomcat) ,但是不能用来配置运行在 Tomcat 中的应用程序。

Meyers 已经提到了你应该使用的 web 应用程序的方式。这是标准方法,也符合通过 context.xml 或 server.xml 方法进行配置的问题。

也就是说,如果您确实需要 tomcat 中的系统属性或其他 jvm 选项(比如 max 内存设置) ,那么应该创建一个名为“ bin/setenv.sh”或“ bin/setenv.bat”的文件。这些文件不存在于您下载的标准归档文件中,但是如果它们存在,那么内容将在启动过程中执行(如果您通过 startup.sh/startup.bat 启动 tomcat)。这是一种将您自己的设置与标准 tomcat 设置分离开来的好方法,并且使更新变得非常容易。不需要调整 startup.sh 或 catalina.sh。

(如果将 tomcat 作为 Windows 服务执行,通常使用 tomcat5w.exe、 tomcat6w.exe 等来配置服务的注册表设置。)

编辑: 另一种可能性是去 JNDI 资源

Cliff.meyers 最初建议使用 <env-entry>的答案在仅使用 System.getProperty ()时没有帮助

根据 Tomcat 6.0的文档 <env-entry>代表 JNDI,这意味着它不会对 System.getProperty()产生任何影响。

对于 Cliff Meyers示例中的 <env-entry>,以下代码

System.getProperty("SMTP_PASSWORD");

将返回 null,而不是值“ abc123ftw”。

根据 Tomcat 6的文档,要使用 <env-entry>,您必须编写如下代码来使用 <env-entry>:

// Obtain our environment naming context
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");


// Look up our data source
String s = (String)envCtx.lookup("SMTP_PASSWORD");

注意: 我实际上并没有尝试上面的例子。但是,我使用 System.getProperty ()尝试了 <env-entry>,这显然不起作用。

还可以让 ServletContextListener 设置 System 属性:

import java.util.Enumeration;
import javax.servlet.*;


public class SystemPropertiesHelper implements
javax.servlet.ServletContextListener {
private ServletContext context = null;


public void contextInitialized(ServletContextEvent event) {
context = event.getServletContext();
Enumeration<String> params = context.getInitParameterNames();


while (params.hasMoreElements()) {
String param = (String) params.nextElement();
String value =
context.getInitParameter(param);
if (param.startsWith("customPrefix.")) {
System.setProperty(param, value);
}
}
}


public void contextDestroyed(ServletContextEvent event) {
}
}

然后把它放到 web.xml 中(context.xml 也应该可以)

<context-param>
<param-name>customPrefix.property</param-name>
<param-value>value</param-value>
<param-type>java.lang.String</param-type>
</context-param>


<listener>
<listener-class>servletUtils.SystemPropertiesHelper</listener-class>
</listener>

这招对我很管用。

在 tomcat 配置中设置系统属性的另一种方法是使用 CATALINA _ OPTS 环境变量

这个问题在 Apache wiki 中已经解决了。

问: “我可以为每个 webapp 设置不同的 Java 系统属性吗?”

答案是: 不。如果您可以编辑 Tomcat 的启动脚本(或者最好创建 setenv.sh 文件) ,那么您可以向 Java 添加“-D”选项。但是在 Java 中,对于同一个 JVM 中的不同类,系统属性的值是不同的。还有其他一些可用的方法,比如使用 ServletContext.getContextPath ()获取 Web 应用的上下文名称并相应地定位一些资源,或者在 Web 应用的 WEB-INF/web.xml 文件中定义元素,然后在 Tomcat 上下文文件(META-INF/context.xml)中为它们设置值。参见 http://tomcat.apache.org/tomcat-7.0-doc/config/context.html

Http://wiki.apache.org/tomcat/howto#can_i_set_java_system_properties_differently_for_each_webapp.3f

可以向 <tomcat installation directory>/conf目录中的 catalina.properties文件添加必要的属性。

参考资料: https://tomcat.apache.org/tomcat-8.0-doc/config/index.html

所有系统属性都是可用的,包括那些使用-D 设置的属性 语法,那些由 JVM 自动提供的 在 $CATALINA _ BASE/conf/CATALINA.properties 文件中配置。

如果你想根据文档在你的上下文中定义一个环境变量,你应该定义如下

<Context ...>
...
<Environment name="maxExemptions" value="10"
type="java.lang.Integer" override="false"/>
...
</Context>

也可以这样使用:

((Context)new InitialContext().lookup("java:comp/env")).lookup("maxExemptions")

您应该得到 10作为输出。