为什么Tomcat在重新部署时会替换context.xml文件?

19

官方文档指出如果你在这里有一个上下文文件:

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

这里不会被上下文文件替换:

mywebapp.war/META-INF/context.xml

在这里写明了:http://tomcat.apache.org/tomcat-6.0-doc/config/context.html

仅当$CATALINA_BASE/conf/[enginename]/[hostname]/中不存在应用程序的上下文文件,并且不存在应用程序文件夹内的/META-INF/context.xml时,才需要。

但是每次重新部署WAR文件时,它都会将myapp.xml替换为/META-INF/context.xml!

为什么会这样做,我该如何避免?

谢谢


1
我正在手动部署,将mywebapp.war放入$CATALINA_HOME/webapps中。我保留WAR中的默认设置,但我希望能够在不修改WAR本身的情况下按实例更改这些设置 - 这就是为什么我希望我的上下文在conf目录中保持不变的原因。 - artemb
1
请查看邮件列表上最近的这个链接:http://www.mail-archive.com/users@tomcat.apache.org/msg81854.html。 - JoseK
1
最近在SF上也有类似的问题:http://serverfault.com/questions/192784/why-does-tomcat-like-deleting-my-context-xml-file/192810#192810 - JoseK
可能有点晚了,但您可以查看此问题以查看解决此问题的可能方法:https://dev59.com/RGw05IYBdhLWcg3wmC-_ - n0rm1e
这种问题实际上应该被点赞。 - shabunc
显示剩余3条评论
6个回答

6

2
对于在家跟进的朋友们:mvn tomcat7:deploy-only -Dmaven.tomcat.update=true -Dmaven.tomcat.mode=both -Dmaven.tomcat.contextFile=/foo/context.xml 可以解决问题。虽然有点遗憾,但在tomcat7中还是有效的。 - Joseph Lust

5

简短回答:

只需将 TOMCATHOME/conf/Catalina/localhost 目录设置为只读,并继续阅读以获取更多详细信息:

  • 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.

详细解释

  • 由于历史原因,Tomcat允许你在四个不同的位置(即四个不同的文件)中定义Web资源(JDBC数据源和其他资源),如果你意外地多次定义了相同的资源,则按照非常特定的优先顺序处理。上面提到的那些是现在更适合每个目的的,虽然你仍然可以使用其他方法(噢...你可能不想这样做)。我不会在这里讨论其他方法,除非有人要求。

当Tomcat的autodeploy被打开并且您使用tomcat7:undeploy时,这将无法工作,它会抱怨无法删除上下文描述符文件。 - Chad
通过这个选项,我的部署失败了,并且出现了错误信息“无法调用Tomcat Manager:连接重置”,原因在Chad的评论中提到。相反,我使用了从WEB-INF和server.xml中的(外部)jndi资源使用context.xml的选项,如第一篇答案所述 这里 - ulrich

0

正如标题所述,一般问题已经在不删除上下文的重新部署中得到了涵盖,这仍然是一个未解决的问题。

重新部署和卸载后部署之间有一个公认的区别,卸载会删除上下文。文档已经过时,管理GUI仍不支持重新部署。


0
在tomcat7上,即使autoDeploy=false,文件在取消部署时也会被删除。这是有文档记录的,并不是一个bug(尽管它避免了具有服务器端固定配置的良好自动化部署)。
我找到了一个解决方法,解决了我的问题:
- 在您的webapp中创建一个包含以下内容的META-INF/context.xml文件 - 在服务器上,在server.xml中创建第二个上下文"/config-context",并将所有服务器端配置参数放在那里 - 在应用程序中使用context.getContext("/config-context").getInitParameter(...)来访问配置信息
这样可以实现与部署的war文件无关的每个主机的配置。
还可以通过添加类似"/config-context-MYPATH"的上下文来添加每个上下文的配置。在您的应用程序中,您可以使用应用程序的上下文路径来计算配置应用程序的上下文路径。

4
为什么核心Tomcat开发人员对最佳实践部署如此无知?我花费了一整晚的时间来解决这个问题,但所有的解决办法都是反模式,但是TC开发人员却否认并不承认在主机上安装JNDI属性和源代码是一个合理的方法,而不是将它们编译到SCM和war中。https://issues.apache.org/bugzilla/show_bug.cgi?id=34840 - Joseph Lust

0
根据文档(http://tomcat.apache.org/tomcat-8.0-doc/config/automatic-deployment.html#Deleted_files),在重新部署时,Tomcat会检测应用程序的删除(卸载)。因此,它将启动一个清理过程,删除目录和XML文件。这与自动部署无关 - 因此,它将在通过管理器重新部署和修改WAR时发生。有三个例外:
  • 全局资源永远不会被删除
  • 外部资源永远不会被删除
  • 如果WAR或DIR已被修改,则仅在copyXML为true且deployXML为true时才会删除XML文件

我不知道为什么,但copyXML="false" deployXML="false"是没有帮助的。

其次:将目录设置为只读只会使Tomcat抛出异常并且无法启动。

您可以尝试将 $CATALINA_BASE/conf/Catalina/localhost/myapp-1.xml、$CATALINA_BASE/conf/Catalina/localhost/myapp-2.xml 等文件合并到 $CATALINA_BASE/conf/context.xml 中(仅当您确保应用程序不会部署自己的上下文配置,如 myapp-1.xml)。

如果有人能告诉我那些“外部资源”是什么,通常就可以解决问题了。


-1

重新部署意味着两个部分:卸载和部署。

卸载会删除 conf/Catalina/yourhost/yourapp.xml,因为

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

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

 </Host>

更改autoDeploy="false",Tomcat就不再有顺序了,以删除conf/Catalina/yourhost/yourapp.xml

有一个功能可以让我们将这些步骤(undeploy/deploy)作为一个单一的步骤(redeploy)来完成,而不会删除context.xml。该功能可通过manager-text-interface使用,但在manager-html-interface中不可用。您可能需要等待tomcat中的错误被修复。您可以使用本答案中描述的方法作为解决方法。


卸载会删除上下文。重新部署不应该删除上下文,因为这与逻辑上的卸载应用程序无关,因为这不是操作的意图,正如所反映的那样。很遗憾,这种区别没有被明确说明。简单地说,重新部署是一个具有自己含义的词。 - user250343
@user250343 已更改答案,请查看。 - Grim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接