views:

10800

answers:

4

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.

Thanks in advance.

+2  A: 

You can define variables inside of the web.xml file of the web application you're deploying...

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

You can also do this in context.xml as well. See the sections titled "Context Parameters" and "Environment Entries" on this page:

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

cliff.meyers
I couldn't get my web.xml to validate using the above. Switching the order of the env-entry-value and env-entry-type entries worked, though.
Catchwa
Okay, the DTD or XSD probably specifies a precise order for those elements. I've updated my answer accordingly. Thanks.
cliff.meyers
+1  A: 

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.

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

Olaf
+2  A: 

brd6644's answer to use for system properties will not work.

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

Using brd6644's example, the following code

System.getProperty("SMTP_PASSWORD");

will return null, not the value "sevenStep7".

According to the Tomcat 6 docs, using brd6644's example, 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.

netjeff
When he asked for a cleaner way of doing it, I interpreted that to mean suggestions as to not using System properties as well. I did not intend my answer to work with: System.getProperty("SMTP_PASSWORD")
cliff.meyers
Yes, I see now what you were aiming for. In that case, my answer "clarifies" that if Markus were to use <env-entry> in context.xml, then he would have to use the slightly more complicated Context API (as in my example), rather than one-liner System.getProperty(). I hope Markus found something that worked for his needs.
netjeff
+2  A: 

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.

basicEntity