Repository: GoogleContainerTools/jib
File: jib-core/src/main/java/com/google/cloud/tools/jib/image/ReproducibleLayerBuilder.java (Java)

Code before:
    private static final Path DIRECTORY_FILE = Paths.get(".");

    private final List<TarArchiveEntry> entries = new ArrayList<>();
    private final Set<String> names = new HashSet<>();

    /**
     * Adds a {@link TarArchiveEntry} if its extraction path does not exist yet. Also adds all of
     * the parent directories on the extraction path, if the parent does not exist. Parent will have
     * modification time set to {@link FileEntriesLayer#DEFAULT_MODIFICATION_TIME}.
     *
     * @param tarArchiveEntry the {@link TarArchiveEntry}
     */
    private void add(TarArchiveEntry tarArchiveEntry) {
      if (names.contains(tarArchiveEntry.getName())) {
        return;
      }

      // Adds all directories along extraction paths to explicitly set permissions for those
      // directories.
      Path namePath = Paths.get(tarArchiveEntry.getName());
      if (namePath.getParent() != namePath.getRoot()) {
        TarArchiveEntry dir;
        try {
          dir = new TarArchiveEntry(DIRECTORY_FILE, namePath.getParent().toString());
        } catch (IOException e) {
          throw new UncheckedIOException(e);
        }
        dir.setModTime(FileEntriesLayer.DEFAULT_MODIFICATION_TIME.toEpochMilli());
        dir.setUserId(0);
        dir.setGroupId(0);
        dir.setUserName("");
        dir.setGroupName("");
        add(dir);
      }

      entries.add(tarArchiveEntry);
      names.add(tarArchiveEntry.getName());
    }

    private List<TarArchiveEntry> getSortedEntries() {
      List<TarArchiveEntry> sortedEntries = new ArrayList<>(entries);
      sortedEntries.sort(Comparator.comparing(TarArchiveEntry::getName));
      return sortedEntries;
    }
  }

  private static void setUserAndGroup(TarArchiveEntry entry, FileEntry layerEntry) {
    entry.setUserId(0);
    entry.setGroupId(0);
    entry.setUserName("");
    entry.setGroupName("");

Review comment (suggestion):
Just make this method `throws IOException`. I've verified that this is the simplest (and also right) change.

Code after:

    private final List<TarArchiveEntry> entries = new ArrayList<>();
    private final Set<String> names = new HashSet<>();

    /**
     * Adds a {@link TarArchiveEntry} if its extraction path does not exist yet. Also adds all of
     * the parent directories on the extraction path, if the parent does not exist. Parent will have
     * modification time set to {@link FileEntriesLayer#DEFAULT_MODIFICATION_TIME}.
     *
     * @param tarArchiveEntry the {@link TarArchiveEntry}
     * @throws IOException if an I/O error occurs
     */
    private void add(TarArchiveEntry tarArchiveEntry) throws IOException {
      if (names.contains(tarArchiveEntry.getName())) {
        return;
      }

      // Adds all directories along extraction paths to explicitly set permissions for those
      // directories.
      Path namePath = Paths.get(tarArchiveEntry.getName());
      if (namePath.getParent() != namePath.getRoot()) {
        TarArchiveEntry dir = new TarArchiveEntry(DIRECTORY_FILE, namePath.getParent().toString());
        dir.setModTime(FileEntriesLayer.DEFAULT_MODIFICATION_TIME.toEpochMilli());
        dir.setUserId(0);
        dir.setGroupId(0);
        dir.setUserName("");
        dir.setGroupName("");
        add(dir);
      }

      entries.add(tarArchiveEntry);
      names.add(tarArchiveEntry.getName());
    }

    private List<TarArchiveEntry> getSortedEntries() {
      List<TarArchiveEntry> sortedEntries = new ArrayList<>(entries);
      sortedEntries.sort(Comparator.comparing(TarArchiveEntry::getName));
      return sortedEntries;
    }
  }

  private static void setUserAndGroup(TarArchiveEntry entry, FileEntry layerEntry) {
    entry.setUserId(0);
    entry.setGroupId(0);
    entry.setUserName("");
    entry.setGroupName("");

    if (!layerEntry.getOwnership().isEmpty()) {
      // Parse "<user>:<group>" string.
      String user = layerEntry.getOwnership();
      String group = "";