How can I specify system properties in Tomcat configuration on startup?

TomcatPropertiesSystem Propertiescontext.xml

Tomcat Problem Overview


I understand that I can specify system properties to Tomcat by passing arguments with the -D parameter, for example "-Dmy.prop=value".

I am wondering if there is a cleaner way of doing this by specifying the property values in the context.xml file or some other tomcat configuration file. I would like to do this because, first, it is easier to keep track of my properties, and second, I have multiple contexts running and I don't know how I would specify context-specific properties through the -D parameter.

I am using Tomcat version 5.5.

Tomcat Solutions


Solution 1 - Tomcat

cliff.meyers's original answer that suggested using <env-entry> will not help when using only System.getProperty()

According to the Tomcat 6.0 docs <env-entry> is for JNDI. So that means it won't have any effect on System.getProperty().

With the <env-entry> from cliff.meyers's example, the following code

System.getProperty("SMTP_PASSWORD");

will return null, not the value "abc123ftw".

According to the Tomcat 6 docs, to use <env-entry> you'd have to write code like this to use <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");

Caveat: I have not actually tried the example above. But I have tried <env-entry> with System.getProperty(), and that definitely does not work.

Solution 2 - Tomcat

(Update: If I could delete this answer I would, although since it's accepted, I can't. I'm updating the description to provide better guidance and discourage folks from using the poor practice I outlined in the original answer).

You can specify these parameters via context or environment parameters, such as in context.xml. See the sections titled "Context Parameters" and "Environment Entries" on this page:

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

As @netjeff points out, these values will be available via the Context.lookup(String) method and not as System parameters.

Another way to do specify these values is to define variables inside of the web.xml file of the web application you're deploying (see below). As @Roberto Lo Giacco points out, this is generally considered a poor practice since a deployed artifact should not be environment specific. However, below is the configuration snippet if you really want to do this:

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

Solution 3 - Tomcat

Generally you shouldn't rely on system properties to configure a webapp - they may be used to configure the container (e.g. Tomcat) but not an application running inside tomcat.

cliff.meyers has already mentioned the way you should rather use for your webapplication. That's the standard way, that also fits your question of being configurable through context.xml or server.xml means.

That said, should you really need system properties or other jvm options (like max memory settings) in tomcat, you should create a file named "bin/setenv.sh" or "bin/setenv.bat". These files do not exist in the standard archive that you download, but if they are present, the content is executed during startup (if you start tomcat via startup.sh/startup.bat). This is a nice way to separate your own settings from the standard tomcat settings and makes updates so much easier. No need to tweak startup.sh or catalina.sh.

(If you execute tomcat as windows servive, you usually use tomcat5w.exe, tomcat6w.exe etc. to configure the registry settings for the service.)

EDIT: Also, another possibility is to go for JNDI Resources.

Solution 4 - Tomcat

It's also possible letting a ServletContextListener set the System properties:

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) {
	}
}

And then put this into your web.xml (should be possible for context.xml too)

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

It worked for me.

Solution 5 - Tomcat

An alternative to setting the system property on tomcat configuration is to use CATALINA_OPTS environment variable

Solution 6 - Tomcat

This question is addressed in the Apache wiki.

Question: "Can I set Java system properties differently for each webapp?"

Answer: No. If you can edit Tomcat's startup scripts (or better create a setenv.sh file), you can add "-D" options to Java. But there is no way in Java to have different values of system properties for different classes in the same JVM. There are some other methods available, like using ServletContext.getContextPath() to get the context name of your web application and locate some resources accordingly, or to define elements in WEB-INF/web.xml file of your web application and then set the values for them in Tomcat context file (META-INF/context.xml). See 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

Solution 7 - Tomcat

You could add necessary properties to catalina.properties file in <tomcat installation directory>/conf directory.

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

> All system properties are available including those set using the -D > syntax, those automatically made available by the JVM and those > configured in the $CATALINA_BASE/conf/catalina.properties file.

Solution 8 - Tomcat

If you want to define an environment variable in your context base on documentation you shod define them as below

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

Also use them as below:

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

You should get 10 as output.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarkusView Question on Stackoverflow
Solution 1 - TomcatnetjeffView Answer on Stackoverflow
Solution 2 - Tomcatcliff.meyersView Answer on Stackoverflow
Solution 3 - TomcatOlaf KockView Answer on Stackoverflow
Solution 4 - TomcatbasicEntityView Answer on Stackoverflow
Solution 5 - TomcatgerrytanView Answer on Stackoverflow
Solution 6 - Tomcatuser64141View Answer on Stackoverflow
Solution 7 - TomcatzenduView Answer on Stackoverflow
Solution 8 - TomcatAlireza AlallahView Answer on Stackoverflow