Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat production / dev environments

In PHP development, its possible to determine whether or not the app is running in a production or a development environment from the servers 'environment' variable.

Is there a similar variable available on tomcat servers, or is there a better way of targetting applications for production and development?

like image 620
richzilla Avatar asked Dec 04 '11 20:12

richzilla


People also ask

Can Tomcat be used in production?

Tomcat can perform very well, and it is used everywhere in the production, with largest user base. Some commercial application servers use Tomcat under the hood without even telling you. Of course you should not compare Tomcat out-of-the-box performance to a well tuned web containers.

How Tomcat is used in Devops?

Tomcat is an application server designed to execute Java servlets and render web pages that use Java Server page coding. Accessible as either a binary or a source code version, Tomcat's been used to power a wide range of applications and websites across the Internet.

How do I set environment variables in Tomcat 9?

Environment variables can be set, by creating a setenv. bat (windows) or setenv.sh (unix) file in the bin folder of your tomcat installation directory. However, environment variables will not be accessabile from within your code. System properties are set by -D arguments of the java process.

Where are the environment variables stored in Tomcat?

Apart from CATALINA_HOME and CATALINA_BASE, all environment variables can be specified in the "setenv" script. The script is placed either into CATALINA_BASE/bin or into CATALINA_HOME/bin directory and is named setenv.


2 Answers

Every Tomcat instance we have has an isProduction flag defined in the GlobalNamingResources section of the server.xml file.

server.xml:

<Server ...>
  ...
  <GlobalNamingResources>
    <Environment name="isProduction" value="false" type="java.lang.Boolean" override="false" /> 
  </GlobalNamingResources>

  <Service name="Catalina">
  ... etc ...
  </Service>
</Server>

This allows the property to be available throughout the app by creating a property in the context.xml that references the resource:

context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context ...>
  <ResourceLink name="isProduction" global="isProduction" type="java.lang.Boolean" />
  ...
</Context>

To fetch the value:

public boolean isProduction() {
   Object o;
   try {
      o = (new InitialContext()).lookup("java:comp/env/isProduction");
   }  catch (NamingException e) {
      o = Boolean.FALSE; // assumes FALSE if the value isn't declared
   }
   return o == null ? Boolean.FALSE : (Boolean) o;
}
like image 72
Matt Brock Avatar answered Oct 06 '22 05:10

Matt Brock


You can't do such thing by default. In any case, do not rely on the container to determine whenever the app is in the environment X. I'd say that you should do it using one of the following methods (in order of preference):

  1. Use whatever your build tool provides. E.g.: use maven profiles. http://maven.apache.org/guides/introduction/introduction-to-profiles.html
  2. Use a property file for the app with a "mode" property.
  3. Pass a -Dmyproject.mode=XXXX property to the JVM
  4. Use an OS system property

I encourage you to use something like #1. For sure you are using some kind of tool to build your app (Ant, SBT, etc).

Imagine if by mistake somebody reinstall Tomcat, remove the OS properties or similar. Your app might run in prod mode.

like image 32
Alejandro Diaz Avatar answered Oct 06 '22 06:10

Alejandro Diaz