2013-04-26 132 views
2

我爲我的遊戲編寫了一個啓動程序,當給定有效的用戶名和密碼時,將從網站下載JAR文件(如果該文件尚不存在或有更新可用)。登錄系統和文件下載工作,但我如何運行下載的JAR文件?我試過Runtime.getRuntime().exec("java -jar " + file.getAbsolutePath());,但無濟於事。執行外部JAR

感謝您的幫助!


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); 
     } 
    } 

這就是我試圖使用現在的代碼,但它無法正常工作。 @Boris蜘蛛的任何提示?

+0

爲什麼不加載它並在內部運行?否則,總是使用'String []'方法並分開參數,考慮使用'ProcessBuilder'。 – 2013-04-26 22:08:19

回答

4

不要像命令那樣執行jar。使用類加載器從jar中加載你想要的類,然後實例化它。

http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html

  1. 裝入罐子通過構建new JarClassLoader("url goes here")。在JarClassLoader上調用.invokeClass("MyMainClassName", new String[] { "Args", "Go", "Here" })
+0

「實例化」有點誤導。調用下載的jar的'main'方法是他想要的。 – Brian 2013-04-26 22:10:42

+1

JarClassLoader類是內置於Java中還是位於單獨的庫中? – nrubin29 2013-04-26 23:02:23

+0

@ PogoStick29是的,JarClassloader是一個內置的類 – MadProgrammer 2013-04-26 23:20:35

0

您應該使用URLClassLoader加載jar,然後致電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); 

摘自this SO answer

+0

您應該嘗試加載不可能的清單文件,以確定主類 – MadProgrammer 2013-04-26 22:14:59

+0

@Boris the Spider使用您的答案,我得到以下異常:'java.lang.NoSuchMethodException:net.audiorpg.audiorpg.AudioRPG.main()' – nrubin29 2013-04-26 22:42:24

+0

固定,我想。 – 2013-04-27 00:14:04