【问题标题】:How can I specify system properties in Tomcat configuration on startup?如何在启动时在 Tomcat 配置中指定系统属性?
【发布时间】:2010-09-27 05:25:06
【问题描述】:

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

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

我使用的是 Tomcat 5.5 版。

【问题讨论】:

  • 将“property=value”作为纯文本附加到 catalina.properties。 (在 linux 中它位于 /etc/tomcat 中)

标签: tomcat properties system-properties context.xml


【解决方案1】:

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

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

也可以像下面这样使用它们:

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

你应该得到10 作为输出。

【讨论】:

    【解决方案2】:

    您可以在&lt;tomcat installation directory&gt;/conf 目录中的catalina.properties 文件中添加必要的属性。

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

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

    【讨论】:

      【解决方案3】:

      cliff.meyers 建议使用&lt;env-entry&gt; 的原始答案在仅使用 System.getProperty() 时无济于事

      根据 Tomcat 6.0 文档&lt;env-entry&gt; is for JNDI。所以这意味着它不会对System.getProperty()产生任何影响。

      使用 cliff.meyers 示例中的&lt;env-entry&gt;,以下代码

      System.getProperty("SMTP_PASSWORD");
      

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

      根据 Tomcat 6 文档,要使用 &lt;env-entry&gt;,您必须编写这样的代码才能使用 &lt;env-entry&gt;

      // 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() 尝试了 &lt;env-entry&gt;,但那肯定行不通。

      【讨论】:

      • 当他要求一种更简洁的方法时,我将其解释为不使用系统属性的建议。我不打算使用我的答案:System.getProperty("SMTP_PASSWORD")
      • 是的,我现在明白你的目标了。在那种情况下,我的回答“澄清”了如果 Markus 要在 context.xml 中使用 ,那么他将不得不使用稍微复杂的 Context API(如我的示例),而不是单线系统.getProperty()。我希望 Markus 能找到适合他需要的东西。
      【解决方案4】:

      这个问题在 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

      【讨论】:

        【解决方案5】:

        (更新:如果我可以删除此答案,我会删除,尽管它已被接受,但我不能。我正在更新描述以提供更好的指导并阻止人们使用我在原始答案中概述的不良做法) .

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

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

        正如@netjeff 指出的那样,这些值将通过 Context.lookup(String) 方法获得,而不是作为系统参数。

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

        <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>
        

        【讨论】:

        • 我无法让我的 web.xml 使用上述方法进行验证。不过,切换 env-entry-value 和 env-entry-type 条目的顺序是可行的。
        • 好的,DTD 或 XSD 可能为这些元素指定了精确的顺序。我已经相应地更新了我的答案。谢谢。
        • 仅供参考,正如我在下面的回答中所述, 值不会出现在 System.getProperty() 中。
        • 请不要将此建议应用于 web.xml 文件:您的可部署将是特定于环境的,因此,您正在实现反模式。上下文和环境参数是这些设置的好地方。
        • 如果您喜欢硬编码在每个环境(如日志目录)中会发生变化的内容,那就太好了。 ;-) 它也没有回答被问到的问题。
        【解决方案6】:

        也可以让 ServletContextListener 设置系统属性:

        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>
        

        它对我有用。

        【讨论】:

          【解决方案7】:

          在 tomcat 配置上设置系统属性的另一种方法是使用 CATALINA_OPTS 环境变量

          【讨论】:

            【解决方案8】:

            通常,您不应依赖系统属性来配置 web 应用程序 - 它们可能用于配置容器(例如 Tomcat),但不能用于配置在 tomcat 中运行的应用程序。

            cliff.meyers 已经提到了您应该将其用于 Web 应用程序的方式。这是标准方式,也适合您通过 context.xml 或 server.xml 方式进行配置的问题。

            也就是说,如果您真的需要在 tomcat 中使用系统属性或其他 jvm 选项(如最大内存设置),您应该创建一个名为“bin/setenv.sh”或“bin/setenv.bat”的文件。这些文件在您下载的标准存档中不存在,但如果它们存在,则内容会在启动期间执行(如果您通过 startup.sh/startup.bat 启动 tomcat)。这是将您自己的设置与标准 tomcat 设置分开的好方法,并使更新变得更加容易。无需调整 startup.sh 或 catalina.sh。

            (如果以windows servive方式执行tomcat,一般使用tomcat5w.exe、tomcat6w.exe等配置服务的注册表设置。)

            编辑:另外,另一种可能性是选择JNDI Resources

            【讨论】:

              猜你喜欢
              • 2012-01-24
              • 1970-01-01
              • 1970-01-01
              • 2011-12-02
              • 1970-01-01
              • 1970-01-01
              • 2011-01-31
              • 1970-01-01
              • 2011-02-13
              相关资源
              最近更新 更多