5

I'm running Tomcat 7 and I need to pass my two web applications an environment variable with the same name but with a different value for each web application.

Is there any way to have application specific environment variables (the same variable has a different value per application) without using JNDI ?

I'm thinking of something like a -Dname=bob in an application specific context.

Stephane
  • 11,836
  • 25
  • 112
  • 175

1 Answers1

5

Create a file per application named like the application war file and have the file sitting in the Tomcat 7 conf/Catalina/localhost/ directory.

Each file can then contain some environment variables specific to the application.

For example, the two applications project1.war and project2.war deployed in the webapps directory.

In the file conf/Catalina/localhost/project1.xml

<Context path="" docBase="project1">
  <Environment name="product" value="one" type="java.lang.String" override="false" />
</Context>

conf/Catalina/localhost/project2.xml

<Context path="" docBase="project1">
  <Environment name="product" value="two" type="java.lang.String" override="false" />
</Context>

Also I didn't experience the double deployment.

My development server host is:

<Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true" deployOnStartup="true">

And my production server host is:

<Host name="www.learnintouch.com"  appBase="webapps" unpackWARs="true" autoDeploy="true" deployOnStartup="true">

To retrieve the value of the variable, I use the Spring condition context:

public class ProductProjectCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment().getProperty("product") == null || context.getEnvironment().getProperty("product").equals("project");
    }

}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Conditional(ProductProjectCondition.class)
public @interface ProductProject {
}

It is then possible to use the @ProductProject annotation.

Stephane
  • 11,836
  • 25
  • 112
  • 175
  • i tried this approach but neither app saw the environment variable – Justin Jan 31 '15 at 17:09
  • Your two xml files have the application name ? There are being loaded ? The Tomcat console says anything ? – Stephane Feb 01 '15 at 18:11
  • 1.) yes, two xml files. 2.) tomcat log confirms they are being loaded. 3.) it seems i would have to find these via InitialContext.lookup() and not System.getEnv() or System.getProperties() which is what i need in this circumstance – Justin Feb 01 '15 at 19:44
  • 1
    I use the Spring condition context to retrieve the value of the environmnent variable. I have edited the question. – Stephane Feb 03 '15 at 18:45
  • Are your files removed on tomcat restart? Do you have autoDeploy=true? How do you deal with this problem : http://serverfault.com/questions/192784/why-does-tomcat-like-deleting-my-context-xml-file ? – Ortomala Lokni Aug 30 '16 at 09:31
  • No, the files are not deleted on a Tomcat restart. The files sit in the conf/ directory and are left untouched there. Yes, I use the auto deploy on. I don't have any such problem. The question you refer in your comment mentions a context.xml file being removed. Note that such a file may be sitting in the Tomcat conf directory (I reckon this one is never removed) and in a web app directory (this one could be removed when redeploying the app). – Stephane Aug 30 '16 at 11:54
  • While this may be a useful technique for some needs, an _environment entry resource_ in the application context is not the same thing as an _environment variable_ as generally understood. – jmb Apr 18 '17 at 13:17
  • These are jndi environment entries, relative to "java:comp/env". They are not normal environment variables. – xing Jun 22 '22 at 14:16