无法创建文件[META-INF/war-tracker],Tomcat 9 Linux。

5

Tomcat日志:

java.io.IOException: Unable to create the file [/usr/local/tomcat/webapps/mywebapp/META-INF/war-tracker]
    at org.apache.catalina.startup.ExpandWar.expand(ExpandWar.java:180)
    at org.apache.catalina.startup.ContextConfig.fixDocBase(ContextConfig.java:609)
    at org.apache.catalina.startup.ContextConfig.beforeStart(ContextConfig.java:742)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:301)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:182)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:986)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1858)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
    at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:772)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:426)
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1585)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:308)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424)
    at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:367)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:972)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1432)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1422)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:944)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:261)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:801)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:695)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:350)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)

突然服务器不工作了, 没有在webapps中提取WAR文件,无法处理API请求,
上下文文件:
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
</Context>

我尝试从TOMCAT页面上的管理器部署,但仍然没有成功。
在日志中找到: 无法创建文件[/usr/local/tomcat/webapps/mywebapp/META-INF/war-tracker] 我寻找解决方案,但没有找到,有人遇到过类似问题吗?
Tomcat版本:apache-tomcat-9.0.13 openjdk版本:"1.8.0_171"

我感觉异常信息里可能还有更多内容。也许是权限被拒绝了?你能否往下看日志,看看是否有更多的信息? - stdunbar
嗨@stdunbar,没有更多关于错误的细节。 - Lior A
我删除了Tomcat并安装了另一个版本,甚至更低的版本,但是仍然出现相同的错误。 - Lior A
@stdunbar 我修改了war文件的权限,如下:chmod -R 777 mywebapp.war,但是Tomcat没有解压war文件。在日志中显示了错误信息。 - Lior A
-rw-r--r--。1 root root 15461413 Nov 15 15:43 infinidat.war - Lior A
显示剩余8条评论
3个回答

17
问题出在部署文件中的"META-INF/war-tracker"文件:
根据Tomcat文档中的主机容器
引用: unpackWARs [...] 注意:如果Tomcat展开WAR文件,它会在解压后的目录结构中添加一个文件(/META-INF/war-tracking)[sic],用于在Tomcat未运行时检测WAR文件的更改。任何此类更改都将触发删除已展开的目录并在Tomcat下次启动时部署更新的WAR文件。 [...]
(顺便说一句:文档中给出的文件名是错误的。它不是/META-INF/war-tracking,而是/META-INF/war-tracker。)
似乎您手动打包了war文件并包含了META-INF/war-tracker。在部署过程中,Tomcat(从版本8开始)会尝试创建该文件以检测变化。然而,如果存在这样的文件,Tomcat将无法创建该文件,并且会抛出您上述提到的异常。
解决方案: 在部署之前,从您的war文件中删除" META-INF/war-tracker "文件,问题就解决了。

5

我们在Windows下遇到了完全相同的问题。在我们的情况下,解释很简单,但很难找到:我们正在部署的*.war文件中已经有一个META-INF/war-tracker文件。据推测,该war文件是基于已解压缩的目录树手工制作而成,而不是由IDE创建。


0

这个有点像半个答案或者对现有答案的补充。

你的堆栈跟踪包含文件名ExpandWar.java和行号180:(ExpandWar.java:180)

抛出错误的那一行是:

throw new IOException(sm.getString("expandWar.createFileFailed", warTracker));

您看到的错误信息是 expandWar.createFileFailed
/drives/c/github.com/tomcat[main]
$ ag "expandWar.createFileFailed"
java/org/apache/catalina/startup/ExpandWar.java
178:                throw new IOException(sm.getString("expandWar.createFileFailed", warTracker));

java/org/apache/catalina/startup/LocalStrings.properties
97:expandWar.createFileFailed=Unable to create the file [{0}]

java/org/apache/catalina/startup/LocalStrings_ja.properties
97:expandWar.createFileFailed=ファイル [{0}] を作成できません

java/org/apache/catalina/startup/LocalStrings_ko.properties
97:expandWar.createFileFailed=파일 [{0}]을(를) 생성할 수 없습니다.

java/org/apache/catalina/startup/LocalStrings_fr.properties
97:expandWar.createFileFailed=Impossible de créer le fichier [{0}]

java/org/apache/catalina/startup/LocalStrings_zh_CN.properties
96:expandWar.createFileFailed=无法创建文件[{0}]

它是在2017-12-01的提交中引入的。

对这个功能的一般想法

简而言之:我不喜欢它。手动解压WAR文件,然后删除WAR文件可以避免麻烦。

我认为Tomcat应该尝试覆盖那个文件,如果它存在的话。或者也许这是一个有意识的决定,宁愿不悄无声息地失败,而是完全不展开WAR文件并给出错误消息。这样至少人们可以修复他们损坏的WAR文件。

然而,我认为错误消息应该更清晰一些。"createFileFailed"可能有很多原因。但我认为这个特定原因"在WAR文件中发现了意外的跟踪器文件!?"应该有自己的错误消息。-- 不确定这是否使得WAR文件违法或与WAR文件标准不一致。(如果有的话。)

但作为一般评论:整个"unpackWARs"功能对我来说一直显得非常可疑和奇怪。

我特意强调从不使用它。因为我真的不理解它,也不信任它。而且在Tomcat文档中有一堆我不理解的决胜负的if-then-else子句。
具体来说:“unpackWARs”文档将其推迟到“自动应用部署”部分。 我不明白这个。(尽管我真的努力过。)所以我尤其不指望那些不经常处理Tomcat的人能够理解这个。--例如我的同事、外部承包商或其他人。
我不明白人们如何弄清楚如果在“webapps/”下既有WAR文件又有“exploded directory”/“expanded directory”会发生什么。
以下是我处理这种情况的方法:

我特别注意确保这一点发生。我将进行一个合理性检查,验证扩展是否成功,然后关闭Tomcat、删除WAR文件,启动Tomcat,检查是否仍然正常工作。然后记录这个变化。

我发现一个特定的问题是,这个文件似乎被视为可选的,但有时也被视为强制性的。

因此,当既有打包的WAR文件又有解压目录,并且解压目录中不存在/META-INF/war-tracker时,就不会进行检查。这个条件会被静默忽略,并被视为“无需重新部署”。

换句话说,如果条件中有这样一句:!warTracker.exists(),那么如果没有追踪器,就不会重新部署。

这个上下文中的代码如下:

// Check to see of the WAR has been expanded previously
if (docBase.exists()) {
    // A WAR was expanded. Tomcat will have set the last modified
    // time of warTracker file to the last modified time of the WAR so
    // changes to the WAR while Tomcat is stopped can be detected
    if (!warTracker.exists() || warTracker.lastModified() == warLastModified) {
        // No (detectable) changes to the WAR
        success = true;
        return docBase.getAbsolutePath();
    }

    // WAR must have been modified. Remove expanded directory.
    log.info(sm.getString("expandWar.deleteOld", docBase));
    if (!delete(docBase)) {
        throw new IOException(sm.getString("expandWar.deleteFailed", docBase));
    }
}

$ ag expandWar.deleteOld
java/org/apache/catalina/startup/ExpandWar.java
109:            log.info(sm.getString("expandWar.deleteOld", docBase));

java/org/apache/catalina/startup/LocalStrings.properties
99:expandWar.deleteOld=An expanded directory [{0}] was found with a last modified time that did not match the associated WAR. It will be deleted.

java/org/apache/catalina/startup/LocalStrings_ja.properties
99:expandWar.deleteOld=関連付けられた WAR ファイルと最終更新日時の異なる展開先ディレクトリ [{0}] が見つかりました。削除します。

java/org/apache/catalina/startup/LocalStrings_fr.properties
99:expandWar.deleteOld=Un répertoire décompressé [{0}] a été trouvé avec une date de dernière modification qui ne correspond pas au WAR associé, il sera effacé

java/org/apache/catalina/startup/LocalStrings_ko.properties
99:expandWar.deleteOld=압축이 풀려진 디렉토리 [{0}]의 최종 변경 시간이, 연관된 WAR의 최종 변경 시간과 부합하지 않습니다. 해당 디렉토리는 삭제될 것입니다.

java/org/apache/catalina/startup/LocalStrings_zh_CN.properties
98:expandWar.deleteOld=发现一个展开的目录[{0}],它的最后修改时间与关联的WAR不一致.它将被删除.
✓

一个有效的架构选择可能是拒绝启动:如果跟踪器很重要,而在扩展目录中不存在,则这可能意味着旧的自动部署在中途中止。

跟踪文件曾经在实际解压之前创建。然后有一个错误报告,基本上说:“在解压之后创建它,这样我们就可以将其用作完成消息”:

因此,创建被移至解压之后。然而,如果我们仍然使用!warTracker.exists()这个东西,那么我们实际上并没有将其存在用作完成消息,对吗?我们也没有将其不存在用作未完成标记。

一种解决方法是强制要求其存在:Tomcat拒绝启动,除非扩展目录中存在该标记。这将导致如此多的Web应用程序出现问题。所以这行不通。

另一种方法是拒绝在这些边缘情况下启动:当你既有未展开的WAR文件,又有展开的目录,并且没有标记文件时。这也是一个破坏性的改变。但或许这可以作为一个重大发布版本的内容。至少这样可以消除歧义。(而且你可以将此更改作为警告逐步引入一年,然后在下一个重大发布版本中将其设为错误。)

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