There are several ways to configure your Java Servlet-based webapp with values for deployment-specific things like the database connection or directories for data and logs. Let us take a look at the alternatives and their benefits and drawbacks.
The deployment descriptor (
web.xml) resides inside your WAR file. You can specify init parameters available using the
<context-param> <param-name>LogDirectory</param-name> <param-value>/myapp/logs</param-value> </context-param>
Accessing the parameter in your Servlet:
String logDirectory = getServletContext().getInitParameter("LogDirectory"); // do something with it
The nice thing about this solution is the self-containment of your packaged application. The price is building a customized
web.xml/WAR for each deployment instance.
Another possibility is to pass environment variables to your servlet container at startup, e.g. using
JAVA_OPTS in the case of Apache Tomcat.
... JAVA_OPTS="-DLogDirectory=/myapp/logs" ...
They can be easily accessed using
This is very easy to employ but has several drawbacks:
- you have to mess with the configuration of your servlet container/host to set the variables
- they are valid for the whole servlet container, possibly interferring with other webapps or the container itself
- the settings are harder to find than in one file that you deliver with your webapp
- need of server restart to change the values
context.xml and JNDI is our preferred way of configuring our webapps. You can ship a default context.xml in the
META-INF directory of your WAR and easily configure resources and beans:
<Context> <Environment name="LogDirectory" value="/myapp/logs" type="java.lang.String" /> <!-- Development DB --> <Resource name="jdbc/devdb" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="-1" username="sa" password="" driverClassName="org.h2.Driver" url="jdbc:h2:mem:devDB;mode=Oracle"/> </Context>
A context.xml outside of your WAR has to be copied in the context configuration directory of your servlet container, e.g.:
cp context.xml /etc/tomcat7/Catalina/localhost/myapp.xml
You can then access the configuration items using JNDI:
Context ctx = (Context) new InitialContext().lookup("java:comp/env"); String logDirectory = (String) ctx.lookup("LogDirectory"); // do something
You can of course use
context-params and the ServletContext to retrieve simple String parameters stored in the context.xml instead of web.xml, too.
The name of the context file must match the name of the deployed application. That way we can deploy the same WAR on several target machines and configure the applications separately. The context.xml not only contains the JNDI datasources (which is very common) but also configuration parameters that may change for each target system.