Maintain file permissions when extracting from a zip file using JDK 5 api

12,201

Solution 1

Essentially, you can't STORE (unix) file permissions in Zip/Jar files, so you can't preserve them when extracting your jar (they were lost when the jar was created to begin with). See this question: creating a jar file - preserving file permissions

If you need the file permissions preserved in the archive and restored when extracting, you need to consider the alternative .tar or .tar.gz / .tar.bz2 format, which is also natively supported by most Java build tools (Ant, Gradle, Maven...)

Solution 2

I think it is actually impossible to keep the permissions correctly.

Permissions are very OS specific: while POSIX file permissions allow the user to set whether you can read, write or execute a file for the file owner, the group and others, the NTFS file system has a similar system but the concept for an execute permission is inexistant. And the early FAT/FAT32 file syste, do not have file permissions at all (a part from the read-only attribute).

Being cross-platform, it would be difficult for java to set the permission properly on the newly created (unzipped) files depending on the underlying OS....

That said, Java 6 has a new java.io.File class that allows you to set permissions (with methods like setExecutable(), setReadable(), etc...)

These helped me a lot, especially the setExecutable() which was my main concerned when having to unzip executables on a Linux file system. And you don't have to bother about figuring out what OS you are running on as the method will simply do nothing if running under Windows or other systems without the concept of executable files.

Solution 3

The unix permissions are stored in the zip, either in the entry external attributes, or in the extra fields (using the "Asi" extra field, tagged with the 0x756E id). java.util.zip.ZipEntry exposes the extra fields and the Asi field could be read if there is one, but the external attributes are not accessible. So it's not possible to restore the files permissions in all cases using only the JDK zip implementation.

Fortunately the Apache Commons Compress project has its own ZipFile implementation which parses the external attributes, the permissions are exposed with the ZipArchiveEntry.getUnixMode() method. Then with Ant's PermissionUtils class and the Java NIO API, the permissions can be applied back to the file extracted with:

Files.setPosixFilePermissions(path, PermissionUtils.permissionsFromMode(entry.getUnixMode()));

Solution 4

Look at Apache Commons Compress and look at TarArchiveEntry, that should preserve the file permissions like you want it to.

TarArchiveEntry entry = tarInput.getNextTarEntry();

Here are the javadocs. I think I've gone Commons mad...

Solution 5

As tracked in this OpenJDK bug: https://bugs.openjdk.java.net/browse/JDK-6194856:

The "standard" zip file format does not have any way to store "executable file" meta-information, since it was originally designed for MS-DOS filesystems.

In order to preserve Unix information like file modes, the zip handling code would have to handle extensions to the zip file format. Other zip implementations have such extensions.

There are some extensions to the file format that would allow maintaining this kind of information, but it can never be guaranteed (there is no requirement that zip files contain such "extended" metadata) and it would be a lot of work to implement and (especially!) test.

Also see this answer: Can i store unix permissions in a zip file (built with apache ant)?

Non-standard Java libraries may implement this (such as apache-commons).

Share:
12,201
Raymond Kroeker
Author by

Raymond Kroeker

Updated on June 14, 2022

Comments

  • Raymond Kroeker
    Raymond Kroeker almost 2 years

    I am using java.util.Zip and java.util.ZipEntry to successfully extra a zip file's contents to disk. I would like to maintain the file permissions set when extracting on a *nix file-system.

    Can anyone point me to the "correct" way to do this?

  • Cheeso
    Cheeso almost 15 years
    does TarArchiveEntry work on zips as well as tar files? they are not the same, right?
  • dm76
    dm76 about 14 years
    I agree with Cheeso - what does this have to do with zip files ?
  • Pierre-Adrien
    Pierre-Adrien almost 14 years
    I know this thread is getting quite old but your answer helped me. I was trying to extract a ***.app on Mac Os but the resulting application would launch, I changed permissions of the actual launcher file inside it using the setExecutable() method and it seems to be working perfectly ! Thanks for the help :)
  • Josejulio
    Josejulio almost 8 years
  • Cameron Lowell Palmer
    Cameron Lowell Palmer over 4 years
    This is not entirely accurate. Extra fields are commonly used for the purposes of file permission preservation.
  • Patrice M.
    Patrice M. about 3 years
    Thank you @Cameron I do realize that this answer is no longer the most accurate, and even may not have been when written years ago. Still it's not a bad answer that deserves the -1's since then (not implying you did :-) ). It would be more helpful to the community to provide a newer answer that reflects the best answer to this question, today, if you can expand on your comment ? I'd happily upvote it and delete mine.