如何检查JAR文件是否有效?

2022-04-04 00:00:00 jakarta-ee java jar classpath

My WebApp允许用户上传JAR文件。但是,上载JAR文件后,它会被损坏。我已经通过比较上传文件(Winmd5free)前后的MD5校验和来验证这一点。

上传的JAR文件与原始JAR文件几乎相同:

  • 文件大小与原始文件相似(以KB为单位)
  • 我可以使用解压程序打开上传的JAR文件并查看其内容(资源和类文件),与原始文件相比一切都是一样的

当我打开上传的JAR文件(使用记事本++)时,我确实注意到二进制内容与原始内容不同。此外,当我使用JarInputStream读取JAR条目时,没有条目。

JarInputStream is = new JarInputStream(new FileInputStream(new File("uploaded.jar")));
JarEntry entry = null;
while(null != (entry = is.getNextJarEntry())) {
    System.out.println(entry.getName());
}

此外,当我双击JAR(Windows)时,我得到以下消息。

错误:Jarfile无效或损坏

我的问题是:

  • 有没有办法以编程方式检查JAR文件是否有效?我本希望JarInputStream立即检测到这一点,但它根本没有显示任何问题
  • 当我在Windows中双击JAR文件时,是不是是java.exe向我显示了无效或损坏的JAR文件消息?
  • 当无效的JAR文件作为类路径的一部分传入时,为什么没有抛出错误/异常?例如,运行java -cp uploaded.jar;libs* com.some.class.Test命令?

这个问题与JAR签名和/或检查JAR文件的签名无关。它只是检查一个文件(上传与否)是否为有效的JAR文件(不一定检查JAR的类文件是否有效,因为已经有关于此问题的另一篇SO文章)。

我的运行结果jar -tvf uploaded.jar

java.util.zip.ZipException: error in opening zip file
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:127)
        at java.util.zip.ZipFile.<init>(ZipFile.java:88)
        at sun.tools.jar.Main.list(Main.java:977)
        at sun.tools.jar.Main.run(Main.java:222)
        at sun.tools.jar.Main.main(Main.java:1147)

解决方案

以编程方式检测无效JAR文件的方法是使用java.util.ZipFile

public static void main(String[] args) {
    if(args.length < 1) {
        System.err.println("need jar file");
        return;
    }
    
    String pathname = args[0];
    try {
        ZipFile file = new ZipFile(new File(pathname));
        Enumeration<? extends ZipEntry> e = file.entries();
        while(e.hasMoreElements()) {
            ZipEntry entry = e.nextElement();
            System.out.println(entry.getName());
        }
    } catch(Exception ex) {
        ex.printStackTrace();
    }
}

如果JAR文件无效,则实例化ZipFile对象时将抛出ZipException

相关文章