I am trying to add an Run Script to install4j that handles the unzipping and untarring of tarballs for things like like mysql and tomcat that are getting embedded in my installer. I realize that I could explode these tars as part of the build process in ant, but for at least one use case I can't do that.
I have included the code below in my Run Script action, using the org.apache.tools.tar.TarEntry and TarInputStream classes. This is working reasonably well, with one bug.
Using this implementation, file paths that are longer than 99 characters are being truncated and the resulting files are being exploded into the top-level directory.
I'm trying to figure out if this is a bug in my implementation or a problem with the apache tools classes. It seems tarEntry.getName() isn't returning the entire path when it's over 99 characters. Is there an easy way work around this without having to rewrite what TarInputStream does? Tar.Entry has a isGNULongNameEntry method, but I can't seem to figure out a reliable way to account for where to put the file when this returns true.
Any suggestions?
import java.io.*;
import java.util.zip.*;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;
String outputDirectory = "mysql";
File tgzFile = new File(context.getInstallationDirectory(), outputDirectory + File.separator + "mysql-5.5.17-linux2.6-i686.tar.gz");
// Create the Tar input stream.
FileInputStream fin = new FileInputStream(tgzFile);
GZIPInputStream gin = new GZIPInputStream(fin);
TarInputStream tin = new TarInputStream(gin);
// Create the destination directory.
File outputDir = new File(outputDirectory);
outputDir.mkdir();
// Extract files.
TarEntry tarEntry = tin.getNextEntry();
while (tarEntry != null) {
File destPath = new File(context.getInstallationDirectory(), outputDirectory + File.separator + tarEntry.getName());
tarEntry.isGNULongNameEntry()
if (tarEntry.isDirectory()) {
destPath.mkdirs();
} else {
// If the parent directory of a file doesn't exist, create it.
if (!destPath.getParentFile().exists())
destPath.getParentFile().mkdirs();
FileOutputStream fout = new FileOutputStream(destPath);
tin.copyEntryContents(fout);
fout.close();
// Presserve the last modified date of the tar'd files.
destPath.setLastModified(tarEntry.getModTime().getTime());
}
tarEntry = tin.getNextEntry();
}
tin.close();
return true;