18
votes

Documentation says if you have a context file here:

$CATALINA_HOME/conf/Catalina/localhost/myapp.xml

it will NOT be replaced by a context file here:

mywebapp.war/META-INF/context.xml

It is written here: http://tomcat.apache.org/tomcat-6.0-doc/config/context.html

Only if a context file does not exist for the application in the $CATALINA_BASE/conf/[enginename]/[hostname]/, in an individual file at /META-INF/context.xml inside the application files.

But everytime I re-deploy the war it replaces this myapp.xml with the /META-INF/context.xml!

Why does it do it and how can I avoid it?

Thanx

6
Are you deploying manually or by an IDE plugin?BalusC
Personally, I wouldn't put a context.xml on the app server. I don't because I can seldom depend on having access to that file. I usually keep it local to my WAR file.duffymo
I am deploying manually by putting mywebapp.war into $CATALINA_HOME/webapps. I keep my default settings in the WAR, but I want to be able to change those settings on a per-instance basis without modifying the war itself - that is why I want my context in the conf directory unchangedartemb
See this recent chain on the mailing list mail-archive.com/[email protected]/msg81854.htmlJoseK
and recently on SF as well serverfault.com/questions/192784/…JoseK

6 Answers

6
votes

Undeploy part of redeploy deletes app and the associated context.xml.

If you use maven tomcat plugin you can avoid deleting context.xml if you deploy your app with command like this:

mvn tomcat:deploy-only -Dmaven.tomcat.update=true

More info here: https://tomcat.apache.org/maven-plugin-2.0-beta-1/tomcat7-maven-plugin/deploy-only-mojo.html

You can use deploy-only with parameter mode to deploy the context.xml too.

4
votes

The short answer:

Just make the TOMCATHOME/conf/Catalina/localhost dir read-only, and keep reading for more details:

  • For quick deployment mode (Eclipse dynamic web project, direct Tomcat connection, etc.) on a local/non-shared Tomcat server you can just define your JDBC datasource (or any other 'web resource') using the META-INF/context.xml file inside the WAR file. Easy and fast in your local environment, but not suitable for staging, QA, or production.
  • For build deployment mode (usually for staging, QA, or prod), JDBC datasources and other 'web resources' details are defined by the QA/production team, not the development team anymore. Therefore, they must be specified in the Tomcat server, not inside the WAR file anymore. In this case, specify them in the file TOMCATHOME/conf/Catalina/localhost/CONTEXT.xml (change Catalina by the engine, and localhost by the host, and CONTEXT by your context accordingly). However, Tomcat will delete this file on each deployment. To prevent this deletion, just make this dir read-only; in Linux you can type:

       chmod a-w TOMCATHOME/conf/Catalina/localhost
    

    Voila! Your welcome.

The long answer

  • For historical reasons Tomcat allows you to define web resources (JDBC datasources, and others) in four different places (read four different files) in a very specific order of precedence, if you happen to define the same resource multiple times. The ones named in the short answer above are the more suitable nowadays for each purpose, though you could still use the others (nah... you probably don't want to). I'm not going to discuss the other ones here unless someone asks for it.
0
votes

On tomcat7, also woth autoDeploy=false the file will be deleted on undeploy. This is documented and not a bug (althought it avoids good automated deployments with server-side fixed configuration).

I found a workaround which solved the problem for me:

  • create a META-INF/context.xml file in your webapp that contains
  • on the Server create a second context "/config-context" in server.xml and put all your server-side configuration parameters there
  • on the application use context.getContext("/config-context").getInitParameter(...) to access the configuration there.

This allows a per-host configuration that is independent of the deployed war.

It should also be possible to add per-context configurations by adding contexts like "/config-context-MYPATH". In your app you can use the context path oth the app to calculate the context path of the config app.

0
votes

According to the documentation (http://tomcat.apache.org/tomcat-8.0-doc/config/automatic-deployment.html#Deleted_files) upon redeploy tomcat detects the deletion (undeploy) of your application. So it will start a cleanup process deleting the directory and xml also. This is independent of auto deployment - so it will happen upon redeployment through manager and modification of war also. There are 3 exceptions:

  • global resources are never deleted
  • external resources are never deleted
  • if the WAR or DIR has been modified then the XML file is only deleted if copyXML is true and deployXML is true

I don't know why, but copyXML="false" deployXML="false" won't help.

Secondly: Making the directory read only just makes tomcat throwing an exception and won't start.

You can try merging your $CATALINA_BASE/conf/Catalina/localhost/myapp-1.xml, $CATALINA_BASE/conf/Catalina/localhost/myapp-2.xml, etc files into $CATALINA_BASE/conf/context.xml (that works only if you make sure your application won't deploy its own context configuration, like myapp-1.xml)

If someone could tell what is that "external resources" that would generally solve the problem.

0
votes

The general issue as described by the title is covered by Re-deploy from war without deleting context which is still an open issue at this time.

There is an acknowledged distinction between re-deploy which does not delete the context, and deploy after un-deploy where the un-deploy deletes the context. The documentation was out of date, and the manager GUI still does not support re-deploy.

-1
votes

Redeployment means two parts: undeployment and deployment.

Undeployment removes the conf/Catalina/yourhost/yourapp.xml because the

 <Host name="localhost" appBase="webapps" unpackWARs="true" 

           autoDeploy="true">      <!-- means autoUndeploy too!!! -->

 </Host>

Change the autoDeploy="false" and Tomcat has no order anymore to remove the conf/Catalina/yourhost/yourapp.xml.

There is an feature that allowes us to make those steps (undeploy/deploy) as one single step (redeploy) that do not remove the context.xml. This feature is available via the manager-text-interface, but the option is not available using the manager-html-interface. You might have to wait until the bug in tomcat is fixed. You can use the method described in this answer as an workaround.