有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

解压缩java中的嵌套jar文件

我正在尝试解压所有jar文件和嵌套在jar文件中的jar文件。 例如,假设有一个测试。罐子和内部的测试。jar,这里有Test1。罐子 我试图做的是创建一个临时目录并解压缩它们,当它是jar文件时,递归调用

下面是我的代码和日志。我对此一无所知。 我很确定输入的是目录。我不知道如何解决这个错误。另外,我非常确定错误来自这里(Collection<File> files = FileUtils.listFiles(root, null, recursive);

Curr directory:/Users/younghoonkwon/jar-analyzer
unzipping directory/Users/younghoonkwon/jar-analyzer/test1.jar@
Curr directory:/Users/younghoonkwon/jar-analyzer/test1.jar@
java.lang.IllegalArgumentException: Parameter 'directory' is not a directory
    at org.apache.commons.io.FileUtils.validateListFilesParameters(FileUtils.java:545)
    at org.apache.commons.io.FileUtils.listFiles(FileUtils.java:521)
    at org.apache.commons.io.FileUtils.listFiles(FileUtils.java:691)
    at org.vulnerability.checker.JarParser.unzipJars(JarParser.java:31)
    at org.vulnerability.checker.JarParser.unzipJars(JarParser.java:38)
    at org.vulnerability.checker.VulnerabilityChecker.main(VulnerabilityChecker.java:26)
[/Users/younghoonkwon/jar-analyzer/test1.jar]

我的代码:

public void unzipJars(String toFind, String currDirectory) {
    File root = new File(currDirectory);
    try {
        boolean recursive = true;
        System.out.println("Curr directory:"+root);
        Collection<File> files = FileUtils.listFiles(root, null, recursive);
        for (Iterator<File> iterator = files.iterator(); iterator.hasNext();) {
            File file = (File) iterator.next();
            if (file.getName().endsWith(toFind)) {
                if(toFind.endsWith("jar")) {
                    unzip(file.getAbsolutePath() + "@",file.getAbsolutePath());
                    System.out.println("unzipping directory"+ file.getAbsolutePath()+"@");
                    unzipJars("jar", file.getAbsolutePath()+"@");
                    this.jarList.add(file.getAbsolutePath());
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

static void unzip(String destDirPath, String zipFilePath) throws IOException {
    Runtime.getRuntime().exec("unzip "+ zipFilePath + " -d" + destDirPath);
}

共 (2) 个答案

  1. # 1 楼答案

    下面的方法decompress()解压一个JAR文件和其中的所有JAR文件(递归)

    
      /**
       * Size of the buffer to read/write data.
       */
      private static final int BUFFER_SIZE = 16384;
    
      /**
       * Decompress all JAR files located in a given directory.
       *
       * @param outputDirectory Path to the directory where the decompressed JAR files are located.
       */
      public static void decompress(final String outputDirectory) {
        File files = new File(outputDirectory);
        for (File f : Objects.requireNonNull(files.listFiles())) {
          if (f.getName().endsWith(".jar")) {
            try {
              JarUtils.decompressDependencyFiles(f.getAbsolutePath());
              // delete the original dependency jar file
              org.apache.commons.io.FileUtils.forceDelete(f);
            } catch (IOException e) {
              log.warn("Problem decompressing jar file: " + f.getAbsolutePath());
            }
          }
        }
      }
    
      /**
       * Decompress all JAR files (recursively).
       *
       * @param zipFile The file to be decompressed.
       */
      private static void decompressDependencyFiles(String zipFile) throws IOException {
        File file = new File(zipFile);
        try (ZipFile zip = new ZipFile(file)) {
          String newPath = zipFile.substring(0, zipFile.length() - 4);
          new File(newPath).mkdir();
          Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
          // Process each entry
          while (zipFileEntries.hasMoreElements()) {
            // grab a zip file entry
            ZipEntry entry = zipFileEntries.nextElement();
            String currentEntry = entry.getName();
            File destFile = new File(newPath, currentEntry);
            File destinationParent = destFile.getParentFile();
            // create the parent directory structure if needed
            destinationParent.mkdirs();
            if (!entry.isDirectory()) {
              BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
              int currentByte;
              // establish buffer for writing file
              byte[] data = new byte[BUFFER_SIZE];
              // write the current file to disk
              FileOutputStream fos = new FileOutputStream(destFile);
              try (BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) {
                // read and write until last byte is encountered
                while ((currentByte = is.read(data, 0, BUFFER_SIZE)) != -1) {
                  dest.write(data, 0, currentByte);
                }
                dest.flush();
                is.close();
              }
            }
            if (currentEntry.endsWith(".jar")) {
              // found a zip file, try to open
              decompressDependencyFiles(destFile.getAbsolutePath());
              FileUtils.forceDelete(new File(destFile.getAbsolutePath()));
            }
          }
        }
      }
    
  2. # 2 楼答案

    这个算法对我来说似乎还可以。该错误似乎是由解压缩文件不是目录(而是文件)或不存在引起的。如果解压缩文件,您的unzip()方法不会抛出任何exeption。jar失败,因为输出文件已经存在

    您之前是否运行过可能导致该问题的代码。JAR或目录包含同名的不需要的输出文件

    在调用FileUtils.listFiles()之前,通过File.isDirectory()File.isFile()检查根File对象是否实际上是一个目录,并且它是否存在(或者如果它是一个文件但不是目录)