2009-08-04 8 views
35

Esto es una continuación de mi own previous question y estoy algo avergonzado de preguntar esto ... Pero de todos modos: ¿cómo comenzarías una segunda JVM desde un programa independiente de Java de una manera independiente del sistema? Y sin depender, por ejemplo, de una variable env como JAVA_HOME, ya que podría apuntar a un JRE diferente del que se está ejecutando actualmente. Se me ocurrió el siguiente código, que realmente funciona, pero se siente un poco incómoda:¿Es * esta * realmente la mejor manera de iniciar una segunda JVM a partir del código de Java?

public static void startSecondJVM() throws Exception { 
    String separator = System.getProperty("file.separator"); 
    String classpath = System.getProperty("java.class.path"); 
    String path = System.getProperty("java.home") 
       + separator + "bin" + separator + "java"; 
    ProcessBuilder processBuilder = 
       new ProcessBuilder(path, "-cp", 
       classpath, 
       AnotherClassWithMainMethod.class.getName()); 
    Process process = processBuilder.start(); 
    process.waitFor(); 
} 

Además, la JVM actualmente en ejecución podría haberse iniciado con algunos otros parámetros (D, X ..., .. .) que la segunda JVM no sabría.

+0

Parece que el código fue tomado de esta respuesta http://stackoverflow.com/a/723914/3520484. – Mark

Respuesta

5

No es claro para mí que siempre desee usar exactamente los mismos parámetros, classpath o lo que sea (especialmente -X tipo de cosas; por ejemplo, ¿por qué el niño necesita la misma configuración de pila que sus padres) al iniciar un proceso secundario.

Preferiría utilizar una configuración externa de algún tipo para definir estas propiedades para los niños. Es un poco más trabajo, pero creo que al final necesitarás la flexibilidad.

Para ver la extensión de los posibles ajustes de configuración, puede consultar los ajustes de "Ejecutar configuraciones" en Eclipse. Bastantes pestañas que valen la pena la configuración allí.

+0

Un archivo de configuración para JVM es una buena idea. Creo que debería ser editable en un diálogo para que los usuarios puedan, pero no necesiten modificar los parámetros (al igual que el ejemplo de Eclipse). Gracias por eso. Lo que también apuntaba era la ruta al ejecutable.Como Stephen C mencionó, el código no funcionará si el ejecutable de la JVM no se llama "java". ¿Hay alguna manera independiente del sistema para encontrar el nombre del ejecutable? –

+0

Da la casualidad que actualmente estoy trabajando con un Java cuyo ejecutable no es "java" por su nombre. Y estoy generando con una Java tradicional. Y tengo al menos 4 ejecutables java diferentes en mi máquina, y javas "no java". No se puede deducir de manera confiable, entonces ¿por qué no incluir la ruta a Java como uno de los elementos configurables? Verá que esto es realmente lo que hace Eclipse, aunque de una manera no muy fácil de configurar. – djna

+0

¿Por qué es esta la respuesta aceptada? si no responde la pregunta que está esperando un "sí" o un "no", y en la situación posterior supongo que existe una alternativa para el "no". –

6

Creo que la respuesta es "Sí". Esto probablemente sea tan bueno como lo puedes hacer en Java usando un código independiente del sistema. Pero tenga en cuenta que incluso esto es solo relativamente sistema independiente. Por ejemplo, en algunos sistemas:

  1. no se haya establecido la variable JAVA_HOME,
  2. el nombre del comando utilizado para lanzar una JVM puede ser diferente (por ejemplo, si no es una JVM de Sun), o
  3. las opciones de la línea de comando pueden ser diferentes (por ejemplo, si no es una Sun JVM).

Si mi objetivo era la máxima portabilidad en el lanzamiento de una (segunda) JVM, creo que lo haría utilizando scripts de envoltura.

+1

Gracias por eso. La variable JAVA_HOME no es relevante aquí como System.getProperty ("java.home")! = JAVA_HOME. ¿Tiene un ejemplo de una JVM donde mi código no funcionaría porque el ejecutable tiene un nombre diferente? –

+0

@Robert: un par de ejemplos: IBM (¿y otros?) Tienen "javaw" como alternativa, y Jikes RVM se inicia con "rvm". (Y para JNode, podría ejecutar "java" u "org.jnode.command.common.java" ... los comandos no están identificados por las rutas). –

5

Para encontrar el ejecutable java con el que se está ejecutando su código actualmente (es decir, la variable 'ruta' en el código de muestra de su pregunta) hay un método de utilidad dentro de Apache que puede ayudarlo. No tiene que compilar su código con ant, simplemente utilícelo como biblioteca para este único método.

Es:

org.apache.tools.ant.util.JavaEnvUtils.getJreExecutable ("java")

Se ocupa de la clase de casos especiales con diferentes proveedores de JVM que otros han mencionado . (Y mirando el código fuente para ello, hay más casos especiales de lo que hubiera imaginado.)

Está en ant.jar. ant se distribuye bajo la licencia de Apache, así que con suerte puedes usarlo como quieras sin problemas.

Cuestiones relacionadas