首页 > 解决方案 > 使用 Maven 时避免损坏的罐子(无效的 LOC 标头)

问题描述

关于这个问题,stackoverflow 上有很多问题,但解决方案是在.m2Maven 文件夹中删除 jar 文件。这不是一个很好的解决方案:有时有 10 个损坏的罐子,我需要一个一个地手动搜索它们。在 Spring 中,有 65 个依赖项对项目来说是一场噩梦。

读取 ZIP 文件会出现“无效的 LOC 标头”异常

无效的 LOC 标头(错误的签名)

https://kingring.wordpress.com/2014/01/27/solve-maven-compile-error-invalid-loc-header-bad-signature/

我主要是 Eclipse 用户,但实际上使用所有主要的 IDE(Intellij 和 Netbeans)。我们在 2019 年,没有插件或工具可以检测到这种损坏的 jar 并用新的替换它们?

在 Eclipse 中,您可以尝试强制 Maven 重新下载依赖项,但不替换损坏的 jar。

这是一个非常严重的问题,因为每隔一段时间,我就会浪费 30 分钟来修复损坏的 jar。

如果有的话,请给我一些解决方案。

标签: javaeclipsemavenintellij-ideanetbeans

解决方案


我怀疑我的方法可能不是您想要的,但是创建一个尝试为Maven 存储库中的java.util.jar.JarFile()每个*.jar文件实例化的应用程序是相当简单的。

如果该实例化有问题,只需捕获 jar 文件的名称和异常并记录它。显然你不应该得到任何异常,所以为了测试,我对一个真实的 Jar 文件进行了二进制编辑,只是为了测试代码。

此代码是为 Windows 编写的。由于它访问文件系统,因此可能需要针对其他平台进行调整,但除此之外,您只需修改指定 Maven 存储库名称的字符串main()

package jarvalidator;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.jar.*;
import java.util.stream.*;

public class JarValidator {

    public static void main(String[] args) throws IOException {
        Path repositoryPath = Path.of("C:\\Users\\johndoe\\.m2");

        if (Files.exists(repositoryPath)) {
            JarValidator jv = new JarValidator();
            List<String> jarReport = new ArrayList<>();
            jarReport.add("Repository to process: " + repositoryPath.toString());
            List<Path> jarFiles = jv.getFiles(repositoryPath, ".jar");
            jarReport.add("Number of jars to process: " + jarFiles.size());
            jarReport.addAll(jv.openJars(jarFiles));
            jarReport.stream().forEach(System.out::println);
        } else {
            System.out.println("Repository path " + repositoryPath + " does not exist.");
        }
    }

    private List<Path> getFiles(Path filePath, String fileExtension) throws IOException {
        return Files.walk(filePath)
                .filter(p -> p.toString().endsWith(fileExtension))
                .collect(Collectors.toList());
    }

    private List<String> openJars(List<Path> jarFiles) {
        int badJars = 0;
        List<String> messages = new ArrayList<>();

        for (Path path : jarFiles) {
            try {
                new JarFile(path.toFile()); // Just dheck for an exception on instantiation.
            } catch (IOException ex) {
                messages.add(path.toAbsolutePath() + " threw exception: " + ex.toString());
                badJars++;
            }
        }
        messages.add("Total bad jars = " + badJars);
        return messages;
    }
}

这是运行代码的输出:

run:
Repository to process: C:\Users\johndoe\.m2
Number of jars to process: 4920
C:\Users\johndoe\.m2\repository\bouncycastle\isoparser-1.1.18.jar threw exception: java.util.zip.ZipException: zip END header not found
Total bad jars = 1
BUILD SUCCESSFUL (total time: 2 seconds)

推荐阅读