0

I am evaluating install4j for a new team/project. The plan is to replace a set of home-grown installers that are specific to their platforms with a single install4j installer. I've created a simple installer for the output of the teams build. Install4j does a fine job with the simple installer that takes the output of the build into a self extracting file and putting it in a directory when executed.

However, when I try to unzip and untar files that are embedded in the builds output it fails with the exception below.

Is install4j not able to handle gzip'd tar files "out of the box"? Do I need to write custom code for this? Or does it look like some other kind of error? I checked and I can unzip and untar the file myself from the command-line into the directory I've specified.

This is something I need to do with multiple artifacts in my installer for MySQL, Tomcat etc.

java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:131)
    at java.util.zip.ZipFile.<init>(ZipFile.java:148)
    at com.install4j.runtime.beans.actions.files.AbstractExtractZipFileAction.getMaxProgress(Unknown Source)
    at com.install4j.runtime.beans.actions.files.AbstractExtractZipFileAction.extractZip(Unknown Source)
    at com.install4j.runtime.beans.actions.files.AbstractExtractZipFileAction.execute(Unknown Source)
    at com.install4j.runtime.beans.actions.SystemInstallOrUninstallAction.install(Unknown Source)
    at com.install4j.runtime.installer.InstallerContextImpl.performActionInt(Unknown Source)
    at com.install4j.runtime.installer.ContextImpl.performAction(Unknown Source)
    at com.install4j.runtime.installer.controller.Controller.executeActions(Unknown Source)
    at com.install4j.runtime.installer.controller.Controller.handleCommand(Unknown Source)
    at com.install4j.runtime.installer.controller.Controller.start(Unknown Source)
    at com.install4j.runtime.installer.Installer.runInProcess(Unknown Source)
    at com.install4j.runtime.installer.Installer.main(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at com.exe4j.runtime.LauncherEngine.launch(Unknown Source)
    at com.install4j.runtime.launcher.Launcher.main(Unknown Source)
Frank
  • 165
  • 1
  • 13

2 Answers2

2

This didn't end up being as hard as I thought it might be. I found a snippet of JAVA code in this post that helped.

So below is the code I ended up adding to a "Run Script" action. It's not yet smart enough to determine the appropriate mysql tar file for the platform being installed on, but it's a start.

import java.io.*;
import java.util.zip.*;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;

File tgzFile = new File(context.getInstallationDirectory(), "mysql/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);

String outputDirectory = "mysql";

// 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());

    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;
Community
  • 1
  • 1
Frank
  • 165
  • 1
  • 13
  • There is one problem I've discovered with this implementation. It doesn't handle GNU Long Filenames. So tar files that have paths longer than 99 characters aren't handled properly. Still working through that. – Frank Feb 08 '12 at 16:55
0

The ZIP actions in install4j currently do not work with gzipped tar files, only with ZIP files.

Ingo Kegel
  • 46,523
  • 10
  • 71
  • 102
  • OK, so that answers the question that I do have to write custom code for now. Any advice/tips/pointers to the most efficient way to do that? Can I do it with the "Run Script" action easily? Or do I need to write an extension? If I need to write an extension, can you point me to any tutorials? – Frank Feb 08 '12 at 13:12
  • Today I run into the same problem and it still doesn't working with version 6.0.4. Maybe it could be an improvement in one of the next versions? Otherwise I have to unpack and zip my files at maven build time but this is not the preffered workaround. – Hardie82 Mar 09 '16 at 10:58
  • I've added this to our issue tracker. – Ingo Kegel Mar 09 '16 at 11:40