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

2

5

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.

Hungary answered 23/8, 2011 at 23:31 Comment(3)
Check this: #542627Trabzon
Are you asking how to obtain the argument TicTacToe.properties or how to get a reference to the executing jar file?Shrunken
I am asking how to get a reference to the "self.jar" and then extract a file from "self.jar" .Hungary
P
8

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.

Peruse answered 12/2, 2013 at 23:8 Comment(2)
extract to where?Wendeline
To files on Filesystem (in this case to current runtime directory)Peruse
U
2

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.

Upstage answered 23/8, 2011 at 23:39 Comment(1)
I'll give that a try and I will post later on what happened.Hungary

© 2022 - 2024 — McMap. All rights reserved.