2008-10-11 139 views
7

使用Maven構建可執行JAR時,如何指定執行JAR時使用的JVM參數?如何爲Maven構建的可執行文件指定JVM參數JAR

我可以使用<mainClass>指定主類。我懷疑JVM參數有一個類似的屬性。特別我需要指定最大內存(例如-Xmx500m)。

這裏是我的組裝插件:

<plugin> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <configuration> 
     <descriptorRefs> 
     <descriptorRef>jar-with-dependencies</descriptorRef> 
     </descriptorRefs> 
     <archive> 
     <manifest> 
      <addClasspath>true</addClasspath> 
      <mainClass>com.me.myApplication</mainClass> 
     </manifest> 
     </archive> 
    </configuration> 
    </plugin> 

編輯/追問:看來,它可能無法按照thisthis後的可執行的JAR指定JVM參數。

回答

2

首先,讓我說什麼這個棘手的可能是硬因爲某種原因。

如果您真的需要,這種方法可能適用於您。正如所寫,它假定「java」在呼叫者的路徑上。

概述:

  1. 聲明一個引導程序類在JAR的清單主類。

  2. 引導程序產生另一個進程,在這個進程中,我們在「真正的」主類上調用java(傳遞任何你想要的命令行參數)。

  3. 重定向子進程的System.out和System.err的引導程序各自的流

  4. 等待子進程結束

這裏有一個good background article

的src /主/爪哇/刮傷/ Bootstrap.java - 這個類是在pom.xml中定義爲 罐子的mainclass:<mainClass>scratch.Bootstrap</mainClass>

package scratch; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.PrintStream; 

public class Bootstrap { 
    class StreamProxy extends Thread { 
     final InputStream is; 
     final PrintStream os; 

     StreamProxy(InputStream is, PrintStream os) { 
      this.is = is; 
      this.os = os; 
     } 

     public void run() { 
      try { 
       InputStreamReader isr = new InputStreamReader(is); 
       BufferedReader br = new BufferedReader(isr); 
       String line = null; 
       while ((line = br.readLine()) != null) { 
        os.println(line); 
       } 
      } catch (IOException ex) { 
       throw new RuntimeException(ex.getMessage(), ex); 
      } 
     } 
    } 

    private void go(){ 
     try { 
      /* 
      * Spin up a separate java process calling a non-default Main class in your Jar. 
      */ 
      Process process = Runtime.getRuntime().exec("java -cp scratch-1.0-SNAPSHOT-jar-with-dependencies.jar -Xmx500m scratch.App"); 

      /* 
      * Proxy the System.out and System.err from the spawned process back to the user's window. This 
      * is important or the spawned process could block. 
      */ 
      StreamProxy errorStreamProxy = new StreamProxy(process.getErrorStream(), System.err); 
      StreamProxy outStreamProxy = new StreamProxy(process.getInputStream(), System.out); 

      errorStreamProxy.start(); 
      outStreamProxy.start(); 

      System.out.println("Exit:" + process.waitFor()); 
     } catch (Exception ex) { 
      System.out.println("There was a problem execting the program. Details:"); 
      ex.printStackTrace(System.err); 

      if(null != process){ 
       try{ 
        process.destroy(); 
       } catch (Exception e){ 
        System.err.println("Error destroying process: "+e.getMessage()); 
       } 
      } 
     } 
    } 

    public static void main(String[] args) { 
     new Bootstrap().go(); 
    } 

} 

的src /主/爪哇/劃痕/應用的.java - 這是你的程序

package scratch; 

public class App 
{ 
    public static void main(String[] args) 
    { 
     System.out.println("Hello World! maxMemory:"+Runtime.getRuntime().maxMemory()); 
    } 
} 

調用正常的切入點:java -jar scratch-1.0-SNAPSHOT-jar-with-dependencies.jar 返回:

Hello World! maxMemory:520290304 
Exit:0 
+3

這實際上似乎更像是一個脆弱的黑客。考慮到在許多機器上,java(.exe)或者不在PATH中,或者PATH中的那個不是調用者想要使用的那個,我看不出這會導致更多問題比解決。 – 2011-11-09 15:18:54

-1

古代的問題,但出現在我的谷歌搜索這個確切的問題,所以我回答它。

嘗試

<configuation> 
... 
<argLine> -Xmx500m </argLine> 
... 
</configuation> 
+1

如果這段XML代碼是用於Maven exec插件的,則僅供參考,它不會解決OT問題... – DejanLekic 2012-04-11 12:26:52

0

針對大衛卡爾森的回答,您可以通過使用java.home系統屬性來定位Java可執行文件,而不是依靠用戶的路徑上找到它使它不那麼脆。另外,您應該也可以將標準輸入重定向到子進程。

相關問題