Reputation: 1612
I wrote a launcher for my game that, when given a valid username and password, will download a JAR file from a website if the file does not already exist or an update is available. The login system and file download work, but how do I run the downloaded JAR file?
I have tried Runtime.getRuntime().exec("java -jar " + file.getAbsolutePath());
, but to no avail.
Thanks for the help!
downloading = new JLabel("Download AudioRPG executable from server. This may take up to a minute.");
downloading.setHorizontalAlignment(SwingConstants.CENTER);
Thread th = new Thread(new Runnable() {
public void run() {
remove(username);
remove(password);
remove(submit);
remove(remember);
add(downloading, BorderLayout.CENTER);
pack();
try {
FTPClient client = new FTPClient();
client.connect("audiorpg.net");
client.login("audiorpg", "mcpogotime1");
client.changeDirectory("files");
client.download("AudioRPG.jar", exe);
client.disconnect(true);
downloading.setText("Done! Launching AudioRPG...");
}
catch (Exception e) { e.printStackTrace(); }
}
});
th.start();
startExternalJAR(getClass(), th, exe);
private static void startExternalJAR(Class<?> c, Thread th, File exe) {
if (!th.isAlive()) {
try {
final String mainClass;
final JarFile jarFile = new JarFile(exe);
try {
final Manifest manifest = jarFile.getManifest();
mainClass = manifest.getMainAttributes().getValue("Main-Class");
} finally {
jarFile.close();
}
final URLClassLoader child = new URLClassLoader(new URL[]{exe.toURI().toURL()}, c.getClassLoader());
final Class<?> classToLoad = Class.forName(mainClass, true, child);
final Method method = classToLoad.getDeclaredMethod("main", String[].class);
final Object[] arguments = {new String[0]};
method.invoke(null, arguments);
}
catch (Exception ex) { ex.printStackTrace(); }
}
else {
try { Thread.sleep(1000); }
catch (Exception e) { }
startExternalJAR(c, th, exe);
}
}
That is the code I am attempting to use now, but it is not working. @Boris the Spider any tips?
Upvotes: 2
Views: 6360
Reputation: 61128
You should use the URLClassLoader
to load the jar
and then call main
.
final String mainClass;
final JarFile jarFile = new JarFile(file);
try {
final Manifest manifest = jarFile.getManifest();
mainClass = manifest.getMainAttributes().getValue("Main-Class");
} finally {
jarFile.close();
}
final URLClassLoader child = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());
final Class classToLoad = Class.forName(mainClass, true, child);
final Method method = classToLoad.getDeclaredMethod("main", String[].class);
final Object[] arguments = {new String[0]};
method.invoke(null, arguments);
Taken from this SO answer.
Upvotes: 0
Reputation: 6593
Don't execute the jar like a command. Load the class you want from the jar using the classloader and then instantiate it.
http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html
new JarClassLoader("url goes here")
..invokeClass("MyMainClassName", new String[] { "Args", "Go", "Here" })
on the JarClassLoader.Upvotes: 4