2008-10-11 17 views
7

Al usar Maven para construir un JAR ejecutable, ¿cómo especifico los argumentos JVM que se usan cuando se ejecuta el JAR?Cómo especificar el argumento JVM para el archivo ejecutable construido de Maven

Puedo especificar la clase principal usando <mainClass>. Sospecho que hay un atributo similar para los argumentos de JVM. Especialmente necesito especificar la memoria máxima (ejemplo -Xmx500m).

Aquí es mi montaje plugin:

<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> 

Editar/Seguimiento: Parece que podría no ser posible especificar argumentos de JVM para un JAR ejecutable según this y this puesto.

Respuesta

4

No conozco ninguno de estos mecanismos. La configuración de JVM se especifica mediante el comando java que realiza la llamada.

Aquí está la especificación de archivo JAR, que visiblemente no menciona ningún atributo distinto de Main-Class para stand-alone de ejecución:

http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html

2

En primer lugar, permítanme decir que todo este complicado es probablemente difícil por una razón.

Este enfoque puede funcionar para usted si realmente lo necesita. Tal como está escrito, asume que "java" está en el camino de la persona que llama.

general:

  1. declarar una clase Bootstrapper como la clase principal en el manifiesto del frasco.

  2. El programa de arranque genera otro proceso en el que llamamos java (pasando cualquier argumento de la línea de comandos que desee) en la clase principal "real".

  3. redirigida el niño procesa System.out y System.err a flujos respectivos del Bootstrapper

  4. Espere a que el proceso hijo para terminar

Aquí hay una good background article.

src/main/java/cero/Bootstrap.java - esta clase se define en pom.xml como MainClass de la jarra: <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/main/java/cero/Aplicación .java - este es el punto de entrada normal para su programa

package scratch; 

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

de llamadas: java -jar scratch-1.0-SNAPSHOT-jar-with-dependencies.jar devoluciones:

Hello World! maxMemory:520290304 
Exit:0 
+3

Esto realmente parece más como un truco frágil. Teniendo en cuenta que en muchas máquinas, java (.exe) no está en la RUTA, o que la que está en la RUTA no es la que la persona que llama desea usar, no veo cómo esto no causaría más problemas. que resolver –

-1

Antigua pregunta pero surgió en mi búsqueda de Google para este problema exacto, así que estoy respondiendo.

Trate

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

Si esta parte del código XML es para el complemento Maven exec, entonces no resolverá el problema OT ... – DejanLekic

0

En respuesta a la respuesta de David Carlson, puede hacer que sea menos frágil mediante el uso de la propiedad del sistema java.home para localizar el ejecutable java en lugar de depender de la ruta del usuario para encontrarlo. Además, probablemente también deberías redirigir la entrada estándar al proceso secundario.

Cuestiones relacionadas