处理Maven无效的LOC标头错误

2023/05/24

1. 概述

有时,当我们本地Maven仓库中的jar损坏时,我们会看到错误:Invalid LOC Header。

在本教程中,我们将了解它何时发生以及如何处理甚至有时防止它

2. “Invalid LOC Header”什么时候出现?

Maven将项目的依赖项下载到我们文件系统上称为本地仓库的已知位置,Maven下载的每个工件还附带其SHA1和MD5校验和文件:

这些校验和的目的是确保相关工件的完整性,由于网络和文件系统可能会出现故障,就像其他任何事情一样,有时工件会被损坏,从而使工件内容与签名不匹配。

在这些情况下,Maven构建会抛出“invalid LOC header”错误。

解决方案是从仓库中删除损坏的jar,让我们看看几种方法。

3. 删除本地仓库

该错误的快速修复是删除整个Maven本地仓库并重新构建项目

rm -rf ${LOCAL_REPOSITORY}

这将清除本地缓存并重新下载所有项目依赖项,但效率不高

请注意,默认本地仓库位于${user.home}/.m2/repository,除非我们在settings.xml中的<localRepository>标签中指定它。我们也可以通过命令找到本地仓库:mvn help:evaluate -Dexpression=settings.localRepository

4. 找到损坏的jar

另一种解决方案是识别特定的损坏jar并将其从本地仓库中删除

当我们使用Maven输出堆栈跟踪命令时,它会在处理失败时包含损坏的jar详细信息。

我们可以通过在构建命令中添加-X来启用调试级别的日志记录:

mvn -X package

生成的堆栈跟踪将在日志末尾指示损坏的jar,识别出损坏的jar后,我们就可以在本地仓库中找到并删除它。现在在构建时,Maven将重新尝试下载jar。

此外,我们可以使用zip -T命令测试存档的完整性:

find ${LOCAL_REPOSITORY} -name "*.jar" | xargs -L 1 zip -T | grep error

5. 验证校验和

前面提到的两种解决方案只会强制Maven重新下载jar,当然,这个问题可能会在以后的下载中再次出现,我们可以通过配置Maven在从远程仓库下载工件时验证校验和来防止这种情况发生

我们可以在Maven命令中添加–strict-checksums或-C选项,如果计算的校验和与校验和文件中的值不匹配,这将导致Maven构建失败。

有两个选项,如果校验和不匹配则构建失败:

-C,--strict-checksums

或警告哪个是默认选项:

-c,--lax-checksums

如今,Maven在将工件上传到中央仓库时需要签名文件,但是中央仓库中可能存在没有签名文件的工件,尤其是历史文件,这就是默认选项为warn的原因。

对于更永久的解决方案,我们可以在Maven的settings.xml文件中配置checksumPolicy,此属性指定工件校验和验证失败时的行为。为了避免将来出现问题,让我们编辑settings.xml文件以在校验和失败时下载失败:

<profiles>
    <profile>
        <repositories>
            <repository>
                <id>codehausSnapshots</id>
                <name>Codehaus Snapshots</name>
                <releases>
                    <enabled>false</enabled>
                    <updatePolicy>always</updatePolicy>
                    <checksumPolicy>fail</checksumPolicy>
                </releases>
            </repository>
        </repositories>
    </profile>
</profiles>

当然,我们需要为每个配置的仓库执行此操作。

6. 总结

在这篇简短的文章中,我们了解了何时会出现”invalid LOC header“错误以及如何处理它的选项。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章