Question

I know how to create a executable .jar file. There are many examples of that on the internet. What I am wondering, is if anyone knows of a way that a executable .jar file can auto extract out parts of itself to the "running directory"?

So, instead of:

jar xf TicTacToe.jar TicTacToe.class TicTacToe.properties
java -jar TicTacToe.jar

I would like to only do this:

java -jar TicTacToe.jar TicTacToe.class TicTacToe.properties

This basically makes a self extracting installer. Is this possible, if so, what code is necessary to do this?

NOTE: ultimately, once it works, I will wrap it into launch4j in order to to emulate a .exe self extracting installer.

Was it helpful?

Solution

You can write a main method which does check if the files are present, and if not extract them (by copying the resource stream to a file). If you only need a fixed set of files (like in your example), this can be easyly done with this:

public class ExtractAndStart
{
    public static void main(String[] args)
    {
        extractFile("TicTacToe.properties");
        Application.main(args);
    }

    private static void extractFile(String name) throws IOException
    {
        File target = new File(name);
        if (target.exists())
            return;

        FileOutputStream out = new FileOutputStream(target);
        ClassLoader cl = ExtractAndStart.class.getClassLoader();
        InputStream in = cl.getResourceAsStream(name);

        byte[] buf = new byte[8*1024];
        int len;
        while((len = in.read(buf)) != -1)
        {
            out.write(buf,0,len);
        }
        out.close();
            in.close();
    }
}

There are also creators for self-extracting archives but they usually extract all and then start some inner component.

Here is a short article how it works:

http://www.javaworld.com/javatips/jw-javatip120.html

And it recommends to use ZipAnywhere which seems outdated. But Ant Installer might be a good alternative.

OTHER TIPS

You can determine which jar a class was loaded from using the following pattern:

SomeClass.class.getProtectionDomain().getCodeSource().getLocation().getFile()

From that, you should be able to use ZipInputStream to iterate over the contents of the jar and extract them to the directory you want to install to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top