Software Build Tool (SBT)

Motivation

Suppose you're writing a plug-in for the next generation SBT which shall create assemblies of all project artifacts. Then you may need to support at least the following archive types:

  • TAR.GZ
  • TAR.BZ2
  • ZIP
  • JAR
  • WAR
  • EAR
  • ...

You can easily figure that writing the code to read and write archive files of all these types will be a cumbersome and tedious task because each archive type typically comes with its own API to read and write its archive files. Furthermore, the algorithms required to manage the state transitions required to support arbitrary modifications to an archive file in a thread-safe manner are very complex.

Copying Archive Files

Thanks to the module TrueZIP File*, here's your relief: The TFile class extends the java.io.File class in order to add the required functionality.

See how easy "tarring" a directory can be:

new TFile("directory").cp_rp(new TFile("archive.tar.gz"));

The name of the method TFile.cp_rp(*) is modeled after the Unix command line cp -rp which copies its arguments recursively and preserves all file attributes.

However, in order to prevent ambiguities, unlike the cp command line utility, TrueZIP does not support auto-completion of path names or mixing file and directory parameters. So you must provide complete path names for both the source and the destination. E.g. in order to copy a single file to an archive file, you would have to call something like this:

new TFile("file").cp_rp(new TFile("archive.tar.gz/file"));

The TFile class provides many alternative constructors and methods to ease the tasks of constructing complete path names and copy files or directories - please consult the Javadoc for more information.

The type of the prospective archive file is detected by its suffix in a path name. In this case .tar.gz was used, but you could use any other registered archive file suffix, too (see below). And of course, archive files can not only be used as the destination of a copy method, but also as the source or both. So here's how to unzip a ZIP file to a directory:

new TFile("archive.zip").cp_rp(new TFile("directory"));

And here's how to "transform" a ZIP file into a TAR.GZ file:

new TFile("archive.zip").cp_rp(new TFile("archive.tar.gz"));

Configuring Archive Detection

You may be wondering how TrueZIP gets configured to treat a file name with a tar.gz or zip suffix as a TAR.GZ or ZIP file instead of a plain old file. For now, let it suffice to say that TrueZIP follows the convention-over-configuration principle as much as possible, so there are reasonable defaults for everything in order to relieve you from typical configuration tasks.

For the previous examples to work, the JARs of the driver modules TrueZIP Driver TAR and TrueZIP Driver ZIP need to be present on the run time class path. You can do this by adding the Maven artifactId truezip-driver-tar and truezip-driver-zip as a dependency to the POM of your Maven build.

For more information about configuring the client APIs, please refer to the article Configuring TrueZIP File*.

False Positive Archive Files

Sometimes a file system entry may have a suffix which is configured to get recognized as an archive file, however the file is not an archive file or not even a file, e.g. a directory. This is called a false positive archive file or false positive for short.

TrueZIP safely detects any false positives and treats them according to their true state, that is, like a plain file or directory. This finding will be remembered until the next call to TVFS.umount(), so the performance impact is minimal.

Committing Changes / Cleaning Up

If your application has created or changed one or more archive files, then these changes need to get committed sometime. Even if your application has done read-only acess to the virtual file system, some temporary files may have been created to speed up random access - this dependends on the driver implementation.

If your application is only short-running, then there is actually nothing to do because the TrueZIP Kernel automatically registers and de-registers a JVM shutdown hook which will commit all changes when its run. Note that shutdown hooks are run even if the application terminates due to a Throwable.

However, if your application is long running or wants to handle any exceptions, then you may want to manually call this operation - here's how to do this:

TVFS.umount();

As a side effect, once this operation succeeded, third parties (e.g. other processes) can safely access the processed archive files until the next time your application starts to operate on them again.

Performance Considerations

Take care not to call TVFS.umount() in a loop which updates the same set of archive files because this would result in poor performance in the order of O(n*n) instead of just O(n), where n is the total number of archive entries.

For more information, please refer to the Javadoc for TVFS.umount().