The solution is simple: don't put configuration in your context.xml.
Here is a solution that we use (which works well for a number of diverse external customers):
We have a single war which will be used in multiple environments, webapp.war. We have three environments, development, integration and production. Integration and production are at the customer site. We don't know passwords and file paths for the client integration and production sites.
We use a combination of two things: JNDI lookup for database stuff and external properties files.
In the context.xml
that is delivered in the war, we have a ResourceLink
<ResourceLink name="jdbc/webapp"
global="uk.co.farwell.webapp.datasource.MySqlDataSource" />
This gives a reference to a globally defined data source, which is defined in the server.xml
for Tomcat.
<Resource auth="Container"
driverClassName="com.mysql.jdbc.Driver"
name="uk.co.farwell.webapp.datasource.MySqlDataSource"
password="xxx" url="xxx" username="fff" />
So the database details can be changed by editing the server.xml
without changing the webapp.war
. Crucially, this only needs to be done once for each server, not at redeploy.
In our spring configuration, to define the dataSource
we have:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/webapp" />
For other properties, we have a global application.properties file which is delivered along with the webapp.war, but is not part of the war. This is referenced by a -D
on the command line to start Tomcat. -Duk.co.farwell.webapp.applicationDir="/usr/xxx/fff"
. We pick up the definition and read the properties file. The database stuff could be done this way as well, but we'd lose the pooling done by Tomcat.
Another thing: we don't have to rebuild if servers are moved, or if machines are changed for some reason. This is a matter for the customer and their infrastructure people.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…