Some polish for self extracting jar
- show progress bar while unpacking. - show error popup on any problem.
This commit is contained in:
Binary file not shown.
@@ -18,12 +18,6 @@
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
|
||||
@@ -9,6 +9,12 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import ui.ProgressApi;
|
||||
import ui.ProgressBar;
|
||||
|
||||
|
||||
/**
|
||||
* SelfExtractor
|
||||
@@ -21,7 +27,19 @@ public class SelfExtractor {
|
||||
byte[] buffer = new byte[BUF_SIZE];
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new SelfExtractor().run(args);
|
||||
try {
|
||||
new SelfExtractor().run(args);
|
||||
System.exit(0);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
String message = e.getMessage();
|
||||
if (message==null) {
|
||||
message = e.getClass().getName();
|
||||
}
|
||||
JOptionPane.showMessageDialog(new JFrame(), message, "Error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
private void run(String[] args) throws Exception {
|
||||
@@ -46,7 +64,7 @@ public class SelfExtractor {
|
||||
}
|
||||
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))) {
|
||||
@@ -85,20 +103,20 @@ public class SelfExtractor {
|
||||
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:")) {
|
||||
//For convenience in 'development mode' look for a local jar built by maven.
|
||||
File devJar = new File("target/self-extracting-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('!')));
|
||||
}
|
||||
|
||||
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:")) {
|
||||
//For convenience in 'development mode' look for a local jar built by maven.
|
||||
File devJar = new File("target/self-extracting-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) {
|
||||
@@ -109,6 +127,9 @@ public class SelfExtractor {
|
||||
|
||||
public void unpack() throws Exception {
|
||||
File destDir = new File(System.getProperty("user.dir"));
|
||||
int numEntries = getNumEntries();
|
||||
int processed = 0;
|
||||
ProgressApi progress = ProgressBar.create(numEntries);
|
||||
try (ZipInputStream zip = openContentsZip()) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zip.getNextEntry())!=null) {
|
||||
@@ -127,7 +148,22 @@ public class SelfExtractor {
|
||||
copy(zip, out);
|
||||
}
|
||||
}
|
||||
processed++;
|
||||
System.out.println("Progress = "+processed +"/"+numEntries);
|
||||
progress.worked(1);
|
||||
}
|
||||
} finally {
|
||||
progress.done();
|
||||
}
|
||||
}
|
||||
|
||||
private int getNumEntries() throws IOException {
|
||||
int count = 0;
|
||||
try (ZipInputStream zip = openContentsZip()) {
|
||||
while (zip.getNextEntry()!=null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package ui;
|
||||
|
||||
public interface ProgressApi {
|
||||
|
||||
void worked(int amount);
|
||||
void done();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.BoundedRangeModel;
|
||||
import javax.swing.DefaultBoundedRangeModel;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public class ProgressBar extends JPanel {
|
||||
|
||||
private JProgressBar progressBar;
|
||||
|
||||
public ProgressBar(BoundedRangeModel model) {
|
||||
super(new BorderLayout());
|
||||
|
||||
progressBar = new JProgressBar(model);
|
||||
progressBar.setValue(0);
|
||||
progressBar.setStringPainted(true);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.add(progressBar);
|
||||
|
||||
add(panel, BorderLayout.CENTER);
|
||||
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||
}
|
||||
|
||||
public static ProgressApi create(int totalWork) {
|
||||
BoundedRangeModel model = new DefaultBoundedRangeModel(0, 0, 0, totalWork);
|
||||
CompletableFuture<JFrame> window = new CompletableFuture<>();
|
||||
final ProgressApi api = new ProgressApi() {
|
||||
|
||||
@Override
|
||||
public void worked(int amount) {
|
||||
model.setValue(model.getValue()+amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
window.thenAccept(w -> SwingUtilities.invokeLater(() -> {
|
||||
w.setVisible(false);
|
||||
w.dispose();
|
||||
}));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try {
|
||||
//Create and set up the window.
|
||||
JFrame frame = new JFrame("Unpacking...");
|
||||
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
|
||||
//Create and set up the content pane.
|
||||
JComponent newContentPane = new ProgressBar(model);
|
||||
newContentPane.setOpaque(true); //content panes must be opaque
|
||||
frame.setContentPane(newContentPane);
|
||||
|
||||
//Display the window.
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
window.complete(frame);
|
||||
} catch (Throwable e) {
|
||||
window.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return api;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user