2013-04-26 93 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