2008-10-11 136 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可执行文件,而不是依靠用户的路径上找到它使它不那么脆。另外,您应该也可以将标准输入重定向到子进程。

相关问题