部署Maven项目时出现java.util.zip.ZipException: invalid LOC header(错误签名)的问题

181
当我运行mvn install时,我遇到了以下异常。我甚至已经删除了本地库并再次运行,仍然得到相同的异常。

[ERROR] 无法执行目标org.apache.maven.plugins:maven-shade-plugin:2.1:shade (default) onproject cores-batch: 创建阴影jar时出错: invalid LOC header(bad signature) -> [Help 1]

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-shade-plugin</artifactId>
   <version>2.1</version>
   <configuration>
      <skipTests>true</skipTests>
   </configuration>
   <executions>
      <execution>
         <phase>package</phase>
         <goals>
            <goal>shade</goal>
         </goals>
         <configuration>
            <artifactSet>
               <excludes>
                  <exclude>commons-logging:commons-logging:jar:*</exclude>
               </excludes>
            </artifactSet>
            <filters>
               <filter>
                  <artifact>*:*</artifact>
                  <excludes>
                     <!-- workaround for a spring issues -->
                     <exclude>META-INF/*.SF</exclude>
                     <exclude>META-INF/*.DSA</exclude>
                     <exclude>META-INF/*.RSA</exclude>
                     <!-- don't want to pick up any other log4j.xml -->
                     <exclude>log4j.xml</exclude>
                  </excludes>
               </filter>
            </filters>
            <!-- May be needed to work around another issue in Spring -->
            <transformers>
               <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                  <resource>META-INF/spring.handlers</resource>
               </transformer>
               <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                  <resource>META-INF/spring.schemas</resource>
               </transformer>
            </transformers>
         </configuration>
      </execution>
   </executions>
</plugin>

错误:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:2.1:shade (default) on project cores-batch: Error creating shaded jar: invalid LOC header (bad signature) -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:2.1:shade (default) on project cores-batch: Error creating shaded jar: invalid LOC header (bad signature)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException: Error creating shaded jar: invalid LOC header (bad signature)
    at org.apache.maven.plugins.shade.mojo.ShadeMojo.execute(ShadeMojo.java:528)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
Caused by: java.util.zip.ZipException: invalid LOC header (bad signature)
    at java.util.zip.ZipFile.read(Native Method)
    at java.util.zip.ZipFile.access$1400(ZipFile.java:56)
    at java.util.zip.ZipFile$ZipFileInputStream.read(ZipFile.java:679)
    at java.util.zip.ZipFile$ZipFileInflaterInputStream.fill(ZipFile.java:415)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
    at java.io.FilterInputStream.read(FilterInputStream.java:107)
    at org.codehaus.plexus.util.IOUtil.copy(IOUtil.java:189)
    at org.codehaus.plexus.util.IOUtil.copy(IOUtil.java:175)
    at org.apache.maven.plugins.shade.DefaultShader.addResource(DefaultShader.java:427)
    at org.apache.maven.plugins.shade.DefaultShader.shade(DefaultShader.java:186)
    at org.apache.maven.plugins.shade.mojo.ShadeMojo.execute(ShadeMojo.java:458)
    ... 21 more
[ERROR] 
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

1
制作了一个针对此问题的插件 -> https://github.com/goxr3plus/CorruptedJarsDetector - GOXR3PLUS
1
@GOXR3PLUS,那个仓库里实际上没有真正的代码(除了 README 中的类),更不用说 Maven 插件的代码了。我认为一个 Maven 插件会是最好的解决方案,或者只是现有插件的扩展,允许执行类似 mvn dependencies validate 的操作... - Marco13
马可,代码库的代码是在类lol中的 :) - GOXR3PLUS
15个回答

237

该 jar 文件可能已损坏。尝试删除以下文件夹的内容:

 C:\Users\[username]\.m2\repository

然后右键点击您的项目,选择Maven,更新项目,在“Force Update of Snapshots/Releases”上勾选。


解决方案是修复Maven,以便它至少重新加载一次来自存储库的文件。查看堆栈跟踪,此时可能为时已晚,但也许Maven在解析依赖项时可以选择验证存档。由于这种情况经常发生 - 也许我在一个糟糕的网络上或其他原因,这将有所帮助。这也可能修复仅下载pom而未下载某个jar的情况,而Maven没有注意到... - KarlP
1
非常好!我花了7个小时才找到解决方案...向你致敬,伙计... - Sufiyan Ansari
7
这个方法可以解决问题,但是删除整个Maven本地仓库并不是最佳选择。只需删除相关的jar文件即可。 - Levent Divilioglu
3
不必删除所有依赖项,在顶部您可以找到具有错误LOC标题的依赖项。 - umar faraz
有什么办法可以在出现这些错误的情况下使构建失败吗?现在即使存在这些无效的LOC头错误,mvn clean package也会成功。 - leokom
3
只是一件显而易见的事情:当某人在 Gradle 构建中遇到“无效的 LOC header”时,只需删除 ~/.gradle/caches 文件夹(Linux)。 - MartyIX

116

主要的问题是损坏的jar包。

为了找到损坏的jar包,你需要在Eclipse或你喜欢的IDE的断点视图中添加一个Java异常断点,选择java.util.zip.ZipException类,并重新启动Tomcat实例。

当JVM在ZipException断点处暂停时,你必须转到堆栈跟踪中的JarFile.getManifestFromReference()并检查属性name以查看文件名。

之后,你应该从文件系统中删除该文件,然后右键单击项目,选择Maven,更新项目,并选中强制更新快照/发布。


15
我认为这应该是被接受的答案。仅仅删除数百个JAR文件并重新下载它们并不是一种有效的解决方法。 - Mohsen
11
rm -rf .m2 = 有效 - Jeryl Cook
2
真棒的调试技巧。节省了我浪费带宽下载整个依赖项或构件的时间。谢谢。 - Thariq Nugrohotomo
3
好的技巧!我找不到JarFile框架,但在ZipFile $ ZipFileInputStream.read框架上发现了它作为表达式ZipFile.this.name。 - rlpatrao
2
这是一个损坏的jar包的简单示例:https://dev59.com/AJvga4cB1Zd3GeqP68bd#46623719花了2个小时才理解问题所在。顺便说一下,只需删除相关的jar文件即可,而不必清除整个maven本地缓存。 - Levent Divilioglu
显示剩余7条评论

85

您需要检查哪个jar包有问题,它可能已经损坏了。删除该jar包并再次运行mvn spring-boot:run命令。可能有多个jar包已经损坏,因此每次都需要运行该命令来删除那些jar包。在我的情况下,mysql、jackson和aspect的jar包已经损坏了,我运行了3次mvn spring-boot:run命令并找到了这个问题,并从.m2文件夹中删除了这些jar包。现在问题已经解决。


44

gsitgithub/find-currupt-jars.txt中,以下命令列出存储库中所有已损坏的jar文件:

find  /home/me/.m2/repository/ -name "*jar" | xargs -L 1 zip -T | grep error | grep invalid

你可以删除损坏的jar文件,重新编译项目。
示例输出:
warning [/cygdrive/J/repo/net/java/dev/jna/jna/4.1.0/jna-4.1.0.jar]:  98304 extra bytes at beginning or within zipfile
  (attempting to process anyway)
file #1:  bad zipfile offset (local header sig):  98304
  (attempting to re-compensate)
zip error: Zip file invalid, could not spawn unzip, or wrong unzip (original files unmodified)

1
sudo find ./repository/ -name "*jar" | sudo xargs -L 1 zip -T | grep error | grep invalid 给出了 xargs: zip: No such file or directory。这是在 Ubuntu on Windows 的 Bash 中使用的,供参考。 - liltitus27
1
@liltitus27 这个命令行在repository下的每个jar文件上执行zip -T命令(测试),然后过滤出哪些jar是无效的压缩文件。你是否有可用的zip命令? - Javier
似乎在Bash中,我没有安装zip。我确实发现你发布的确切命令在Cygwin中运行得非常好。而且,它也成功地找到了坏的JAR文件,谢谢! - liltitus27
这个想法是在.m2/repository下的每个jar上运行zip -T。 在Windows中,您可以在Cygwin(/cygdrive/C/Users/torno/.m2/repository)上运行它,就像我一样, 我认为您也可以在Windows 10上使用Bash运行它(/mnt/c/Users/torno/.m2/repository)。 我没有研究如何使用PowerShell编写等效脚本,而且我认为在cmd提示符下不可能实现。 - Javier
2
非常好的答案,删除.m2内的数千个库会失去很多东西。谢谢。 - Qussay Najjar

13

我想分享我的实践经验。

使用您偏爱的IDE,这里以Eclipse为例:

  1. 在异常堆栈中找到合适的位置
  2. 设置条件断点
  3. 进行调试
  4. 它会在异常之前打印出受损的jar文件

输入图像描述


1
这是一个比清除整个m2存储库更好的解决方案,在我的情况下,重新下载需要很长时间。 - Martin Cassidy
简单而易用。 - Ajay Takur

6
我的解决方案是使用带有 -Xmvn 命令来运行:
$ mvn package -X

然后从输出中向后查找,直到看到失败的地方,然后继续查找,直到看到mvn尝试处理的最后一个jar文件:

...
... <<output ommitted>>
...
[DEBUG] Processing JAR /Users/snowch/.m2/repository/org/eclipse/jetty/jetty-server/9.2.15.v20160210/jetty-server-9.2.15.v20160210.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.607 s
[INFO] Finished at: 2017-10-04T14:30:13+01:00
[INFO] Final Memory: 23M/370M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:3.1.0:shade (default) on project kafka-connect-on-cloud-foundry: Error creating shaded jar: invalid LOC header (bad signature) -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:3.1.0:shade (default) on project kafka-connect-on-cloud-foundry: Error creating shaded jar: invalid LOC header (bad signature)

查看最后一个失败的存储库并从本地存储库中删除它,即:

$ rm -rf /Users/snowch/.m2/repository/org/eclipse/jetty/jetty-server/9.2.15.v20160210/

2

看起来你的pom文件中maven编译器的配置有问题。默认的java源代码和目标版本是1.5,即使使用的JDK版本更高。

要解决这个问题,需要添加maven编译器插件的配置部分,并使用更高的java版本,例如:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.6.1</version>
  <configuration>
    <source>1.6</source>
    <target>1.6</target>
  </configuration>
</plugin>

更多信息请查看以下链接:

Maven编译器

缺陷报告


1
我们可以通过至少两种选项在Maven中强制进行校验和验证:
1. 在我们的Maven命令中添加--strict-checksums
2. 在我们的Maven设置文件中添加以下配置:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
    <!--...-->
    <profiles>
        <profile>
            <!--...-->
            <repositories>
                <repository>
                    <id>codehausSnapshots</id>
                    <name>Codehaus Snapshots</name>
                    <releases>
                        <enabled>false</enabled>
                        <updatePolicy>always</updatePolicy>
                        <checksumPolicy>fail</checksumPolicy>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                        <updatePolicy>never</updatePolicy>
                        <checksumPolicy>fail</checksumPolicy>
                    </snapshots>
                    <url>
                        <!--...-->
                    </url>
                </repository>
            </repositories>
            <pluginRepositories>
                <!--...-->
            </pluginRepositories>
            <!--...-->
        </profile>
    </profiles>
    <!--...-->
</settings>

这篇文章中有更多细节:https://dzone.com/articles/maven-artifact-checksums-what


1

这是一个用Java编写的小型探测器,只需复制并运行即可 :)

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarFile;
import java.util.stream.Collectors;

public class JarValidator {

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

        // Check if the main Repository Exists
        if (Files.exists(repositoryPath)) {

            // Create a class instance
            JarValidator jv = new JarValidator();

            List<String> jarReport = new ArrayList<>();
            jarReport.add("Repository to process: " + repositoryPath.toString());

            // Get all the directory files
            List<Path> jarFiles = jv.getFiles(repositoryPath, ".jar");
            jarReport.add("Number of jars to process: " + jarFiles.size());
            jarReport.addAll(jv.openJars(jarFiles, true));

            // Print the report
            jarReport.stream().forEach(System.out::println);

        } else {
            System.out.println("Repository path " + repositoryPath + " does not exist.");
        }
    }

    /**
     * Get all the files from the given directory matching the specified extension
     * 
     * @param filePath      Absolute File Path
     * @param fileExtension File extension
     * @return A list of all the files contained in the directory
     * @throws IOException
     */
    private List<Path> getFiles(Path filePath, String fileExtension) throws IOException {
        return Files.walk(filePath).filter(p -> p.toString().endsWith(fileExtension)).collect(Collectors.toList());
    }

    /**
     * Try to open all the jar files
     * 
     * @param jarFiles
     * @return A List of Messages for Corrupted Jars
     */
    private List<String> openJars(List<Path> jarFiles, boolean showOkayJars) {
        int[] badJars = { 0 };
        List<String> messages = new ArrayList<>();

        // For Each Jar
        jarFiles.forEach(path -> {

            try (JarFile file = new JarFile(path.toFile())) {
                if (showOkayJars)
                    messages.add("OK : " + path.toString());
            } catch (IOException ex) {
                messages.add(path.toAbsolutePath() + " threw exception: " + ex.toString());
                badJars[0]++;
            }
        });

        messages.add("Total bad jars = " + badJars[0]);
        return messages;
    }

}

Output

Repository to process: C:\Users\goxr3plus\.m2
Number of jars to process: 4920
C:\Users\goxr3plus\.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)

1
这篇回答不适用于DevOps/系统管理员,而是适用于使用IDE(如eclipse)并遇到“invalid LOC header (bad signature)”问题的人。
您可以按照以下方式强制更新maven依赖项:

enter image description here

enter image description here


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