Why does tomcat replace context.xml on redeploy?

亡梦爱人 提交于 2019-11-28 20:35:26
petro

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.

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.

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.

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.

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!