javainstallationjarself-extracting

Java: creating self extracting jar that can extract parts of itself out of the archive?


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.


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.