Add self-extracting jar utility
This commit is contained in:
132
self-extracting-jar-creator/src/main/java/SelfExtractor.java
Normal file
132
self-extracting-jar-creator/src/main/java/SelfExtractor.java
Normal file
@@ -0,0 +1,132 @@
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
|
||||
/**
|
||||
* SelfExtractor
|
||||
*/
|
||||
public class SelfExtractor {
|
||||
|
||||
private static final String CONTENTS_ZIP_RSRC = "/contents.zip";
|
||||
private static final int BUF_SIZE = 1024*8;
|
||||
|
||||
byte[] buffer = new byte[BUF_SIZE];
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new SelfExtractor().run(args);
|
||||
}
|
||||
|
||||
private void run(String[] args) throws Exception {
|
||||
if (args.length==0) {
|
||||
unpack();
|
||||
} else if (args.length==1) {
|
||||
repack(args[0]);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Expecting one argument pointing to zipfile to re-wrap");
|
||||
}
|
||||
}
|
||||
|
||||
private void repack(String _contentsZip) throws Exception {
|
||||
File contentsZip = new File(_contentsZip);
|
||||
System.out.println("Repackaging "+contentsZip);
|
||||
if (!contentsZip.isFile()) {
|
||||
throw new IllegalArgumentException("File not found:" + contentsZip);
|
||||
}
|
||||
String repackagedPath = contentsZip.toString();
|
||||
if (repackagedPath.endsWith(".zip")) {
|
||||
repackagedPath = repackagedPath.substring(0, repackagedPath.length()-4);
|
||||
}
|
||||
repackagedPath = repackagedPath + ".self-extracting.jar";
|
||||
System.out.println(" as "+repackagedPath);
|
||||
|
||||
File wrapperJar = getMyJar();
|
||||
System.out.println("wrapperJar = "+wrapperJar);
|
||||
try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(wrapperJar))) {
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(new File(repackagedPath)))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zipIn.getNextEntry())!=null) {
|
||||
System.out.println("Adding: "+entry.getName());
|
||||
if (entry.getName().equals("contents.zip")) {
|
||||
//skip. We need to write the wrapped zip contents here.
|
||||
} else {
|
||||
zipOut.putNextEntry(new ZipEntry(entry));
|
||||
if (entry.getName().endsWith("/")) {
|
||||
//skip directory has no bytes as contents
|
||||
} else {
|
||||
copy(zipIn, zipOut);
|
||||
}
|
||||
}
|
||||
} //end while
|
||||
entry = new ZipEntry("contents.zip");
|
||||
zipOut.putNextEntry(entry);
|
||||
System.out.println("Adding: "+entry.getName());
|
||||
try (FileInputStream contentsZipIn = new FileInputStream(contentsZip)) {
|
||||
copy(contentsZipIn, zipOut);
|
||||
}
|
||||
} //end: zipOut
|
||||
}//end: zipIn
|
||||
}
|
||||
|
||||
private void copy(InputStream in, OutputStream out) throws IOException {
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
private File getMyJar() {
|
||||
Class<?> myklass = this.getClass();
|
||||
String resourceName = this.getClass().getName() + ".class";
|
||||
URL resource = myklass.getResource(resourceName);
|
||||
String myResourceUrl = resource.toString();
|
||||
//Example: jar:file:/home/.../self-extracing-jar-creator-0.0.1-SNAPSHOT.jar!/SelfExtractor.class
|
||||
if (!myResourceUrl.startsWith("jar:file:")) {
|
||||
File devJar = new File("target/self-extracing-jar-creator-0.0.1-SNAPSHOT.jar");
|
||||
if (devJar.isFile()) {
|
||||
return devJar;
|
||||
}
|
||||
throw new IllegalStateException("To create self extracting jar, you must run this code from a jar");
|
||||
}
|
||||
return new File(myResourceUrl.substring("jar:file:".length(), myResourceUrl.indexOf('!')));
|
||||
}
|
||||
|
||||
private ZipInputStream openContentsZip() {
|
||||
InputStream zip = this.getClass().getResourceAsStream(CONTENTS_ZIP_RSRC);
|
||||
if (zip==null) {
|
||||
throw new IllegalArgumentException("Couldn't find embedded '"+CONTENTS_ZIP_RSRC+"");
|
||||
}
|
||||
return new ZipInputStream(zip);
|
||||
}
|
||||
|
||||
public void unpack() throws Exception {
|
||||
File destDir = new File(System.getProperty("user.dir"));
|
||||
try (ZipInputStream zip = openContentsZip()) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zip.getNextEntry())!=null) {
|
||||
String name = entry.getName();
|
||||
System.out.println(name);
|
||||
File outfile = new File(destDir, name);
|
||||
if (outfile.exists()) {
|
||||
throw new IllegalArgumentException("File already exists: "+outfile);
|
||||
}
|
||||
if (name.endsWith("/")) {
|
||||
outfile.mkdirs();
|
||||
} else {
|
||||
//file
|
||||
outfile.getParentFile().mkdirs();
|
||||
try (FileOutputStream out = new FileOutputStream(outfile)) {
|
||||
copy(zip, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user