2009-02-02 21 views
9

Solía ​​Ejecutar un programa Java de nuestro programa Java

Runtime.getRuntime().exec("_____") 

pero lanza una IOException de la siguiente manera:

java.io.IOException: CreateProcess: c:/ error=5 
    at java.lang.Win32Process.create(Native Method) 
    at java.lang.Win32Process.<init>(Win32Process.java:63) 
    at java.lang.Runtime.execInternal(Native Method 

No sé si tengo el problema con la especificación de la ruta o algo más. ¿Puede alguien ayudarme con el código?

+0

¿Qué getMessage() en ese IOException volver? –

+1

¿Desea ejecutarlo en una máquina virtual diferente? Siempre puede crear un nuevo hilo y dejar que el otro programa se ejecute. –

+0

java.io.IOException: CreateProcess: c:/error = 5 en java.lang.Win32Process.create (Método nativo) en java.lang.Win32Process. (Win32Process.java:63) en java.lang.Runtime.execInternal (Método nativo) – Arun

Respuesta

2

¿Qué tal si llama al principal desde su programa java?

Test.main (null);

Esto funcionó bien para mí

+0

Hola amigo, también está funcionando 4 yo, pero necesito usar la clase Runtime. Ese es el gran problema. – Arun

+1

¿Por qué necesita tiempo de ejecución si funciona la llamada a main()? – Sietse

+5

Llamar a "principal" no está exento de efectos secundarios. Incluso si se asegura de que las clases se descarguen cuando haya terminado con ellas utilizando sus propios cargadores de clases, las aplicaciones invocadas pueden alterar el estado global de la JVM de manera que entre en conflicto con su aplicación. – McDowell

2

¿Hay alguna razón no se puede simplemente llamar directamente en el código de Java?

Si hay un motivo por el que no lo he probado para ejecutar un programa Java, pero podría intentarlo Jakarta Commons Exec funciona bien para ejecutar la mayoría de los programas.

1

Debe pasar la ruta de su ejecutable en el método de ejecución. ¿Estás realmente tratando de ejecutar el proceso "-"?

Además, echa un vistazo a this para algunos consejos útiles.

0

No puedo recordar el código exacto que utilicé para que esto funcione, pero debe pasar "java.exe" (o el equivalente) como el ejecutable, y luego la clase o jar para ejecutar como parámetro, con el directorio de trabajo correcto. Entonces no es tan simple como llamar a un método.

10

Está intentando ejecutar "C: /". Usted querrá ejecutar algo como:

"javaw.exe d:\\somejavaprogram\\program.jar"

Aviso los separadores de ubicación.

Supongo que esto es para un proyecto ad-hoc, en lugar de algo grande. Sin embargo, para las mejores prácticas ejecutar programas externos de código:

  • No codificar la ubicación ejecutable, a menos que esté seguro de que nunca va a cambiar
  • Mirar hacia arriba directorios como% windir% usando System.getenv
  • No suponga que programas como javaw.exe están en la ruta de búsqueda: compruébelos primero o permita que el usuario especifique una ubicación
  • Asegúrese de tomar espacios en cuenta: "cmd /c start " + myProg no funcionará si myProg es "my program.jar".
+3

/como separador de ruta funciona bien en Windows. – PhiLho

+0

Sí, funciona bien para archivos simples, pero es un mal hábito entrar. ¿Qué sucede cuando intentas ejecutar una línea de comando, como "cmd/c cd ../myfolder&make" o intentas leer algo que empieza por "\\? \" ?. Sin mencionar la confusión cuando el usuario ve "c:/users \ myname/desktop \". – Mark

+0

Las cosas se complican si intentas ejecutar 'cmd.exe' desde dentro de otro programa. Empeoran aún más si desea utilizar 'start', ya que tiene algunas opciones realmente * extrañas * –

2

Tuve que hacer esto recientemente.
Aquí es cómo lo hice, recogiendo sólo las partes pertinentes:

private static final String[] straJavaArgs = 
{ 
    "?i/j2re/bin/java", 
    "-ms64m", 
    "-mx64m", 
    "-Djava.ext.dirs=?i/lib;?i/jar/lib;?i/jar" 
}; 

// ... 

    // AppDesc appToRun; 
    List<String> params = new ArrayList<String>(); 
    // Java exe and parameters 
    params.addAll(ExpandStrings(straJavaArgs)); 
    // Common VM arguments 
    params.addAll(Arrays.asList(AppDesc.GetCommonVMArgs())); 
    // Specific VM arguments 
    params.addAll(ExpandStrings(appToRun.GetVMArgs())); 
    // The program to run 
    params.add(appToRun.GetClass()); 
    // Its arguments 
    params.addAll(ExpandStrings(appToRun.GetProgramArgs())); 
    // The common arguments 
    params.addAll(ExpandStrings(AppDesc.GetCommonProgramArgs())); 

    ProcessBuilder processBuilder = new ProcessBuilder(params); 
    process = processBuilder.start(); 
    return CaptureProcessOutput(); // Uses a StreamGobbler class 

protected ArrayList<String> ExpandStrings(String[] stra) 
{ 
    ArrayList<String> alResult = new ArrayList<String>(); 
    for (int i = 0; i < stra.length; i++) 
    { 
    // Super flexible, eh? Ad hoc for the current task, at least... 
    alResult.add(stra[i] 
      .replaceAll("\\?i", strInstallDir) 
      .replaceAll("\\?c", strConfigDir) 
    ); 
    } 
    return alResult; 
} 

public enum AppDesc 
{ 
// Enumerate the applications to run, with their parameters 
} 

incompleto, si necesita más detalles, pregunte.

7
java.io.IOException: CreateProcess: c:/ error=5 
     at java.lang.Win32Process.create(Native Method) 
     at java.lang.Win32Process.&lt;init&gt;(Win32Process.java:63) 
     at java.lang.Runtime.execInternal(Native Method) 

Si recuerdo correctamente, el código de error 5 significa acceso denegado.Esto podría deberse a que su ruta de acceso es incorrecta (tratando de ejecutar "c: /") o está chocando con la seguridad de su sistema operativo (en cuyo caso, mire los permisos).

Si usted está teniendo problemas para localizar el ejecutable de Java, normalmente se puede encontrar utilizando las propiedades del sistema:

public class LaunchJre { 

    private static boolean isWindows() { 
     String os = System.getProperty("os.name"); 
     if (os == null) { 
      throw new IllegalStateException("os.name"); 
     } 
     os = os.toLowerCase(); 
     return os.startsWith("windows"); 
    } 

    public static File getJreExecutable() throws FileNotFoundException { 
     String jreDirectory = System.getProperty("java.home"); 
     if (jreDirectory == null) { 
      throw new IllegalStateException("java.home"); 
     } 
     File exe; 
     if (isWindows()) { 
      exe = new File(jreDirectory, "bin/java.exe"); 
     } else { 
      exe = new File(jreDirectory, "bin/java"); 
     } 
     if (!exe.isFile()) { 
      throw new FileNotFoundException(exe.toString()); 
     } 
     return exe; 
    } 

    public static int launch(List<String> cmdarray) throws IOException, 
      InterruptedException { 
     byte[] buffer = new byte[1024]; 

     ProcessBuilder processBuilder = new ProcessBuilder(cmdarray); 
     processBuilder.redirectErrorStream(true); 
     Process process = processBuilder.start(); 
     InputStream in = process.getInputStream(); 
     while (true) { 
      int r = in.read(buffer); 
      if (r <= 0) { 
       break; 
      } 
      System.out.write(buffer, 0, r); 
     } 
     return process.waitFor(); 
    } 

    public static void main(String[] args) { 
     try { 
      Runtime.getRuntime().exec("c:/"); 

      List<String> cmdarray = new ArrayList<String>(); 
      cmdarray.add(getJreExecutable().toString()); 
      cmdarray.add("-version"); 
      int retValue = launch(cmdarray); 
      if (retValue != 0) { 
       System.err.println("Error code " + retValue); 
      } 
      System.out.println("OK"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

(Probado en Windows XP, Sun JRE 1.6; Ubuntu 8.04, OpenJDK JRE 1.6)

este es el equivalente a correr:

java -version 

también puede que desee ver en el "java.library.path" propiedad del sistema (y "path.separator") cuando se trata de localizar el executabl mi.

7

Puede iniciar otra JVM (como se describe en detalle en otras respuestas). Pero esa no es una solución que prefiera.

Las razones son:

  • llamar a un programa nativo de Java es "sucio" (y, a veces se bloquea su propio VM)
  • lo que necesita saber la ruta de la JVM externa (JVM modernas no lo hacen set JAVA_HOME más)
  • no tiene ningún control sobre el otro programa

la razón principal para hacerlo de todas formas, es decir, que la otra aplicación no tiene control sobre su parte del programa tampoco. Y lo que es más importante, no hay problemas con subprocesos del sistema que no responden, como AWT-Thread, si la otra aplicación no conoce su subprocesamiento 101.

¡Pero! Puede lograr un mayor control y un comportamiento similar mediante el uso de una técnica de complemento elemental. Es decir. simplemente llame a "un método de interfaz conocido" que la otra aplicación debe implementar. (en este caso, el método "principal").

Solo que no es tan fácil como parece lograrlo.

  • tienes que dinámicamente incluir frascos necesarios en tiempo de ejecución (o incluirlos en la ruta de clase para su aplicación)
  • usted tiene que poner el plugin en un recinto de seguridad que impide comprometer clases críticos a la otra aplicación

Y esto requiere un cargador de clases personalizado. Pero ten cuidado, hay algunas trampas ocultas en la implementación de eso. Por otro lado, es un gran ejercicio.

Por lo tanto, elija: rápido y sucio o duro pero gratificante.

0

Tuve un problema similar. Necesitaba ejecutar una sección de código Java en una máquina virtual separada, ya que invocaba código nativo a través de JNI que de vez en cuando explotaba sacando toda la máquina virtual.

Aunque hice trampa un poco. Inicialmente utilicé Runtime para invocar un archivo de comando por lotes simple y puse el comando java work-in-progress allí. Esto me permitió ajustarlo según sea necesario y ejecutar el comando en un indicador de DOS para realizar pruebas fácilmente. Una vez que se terminó, simplemente copié el resultado en la invocación Runtime.

2
public class Test {  
    public static void main(String[] args) throws Exception {  
    Process p = Runtime.getRuntime().exec("\"c:/program files/windows/notepad.exe\""); 
    p.waitFor(); 
    } 

} 

lo anterior funciona bastante bien, en lugar de pasar \ "c:/archivos de programa/ventanas/notepad.exe \", como los argumentos para el ejecutable, utilizan la ruta a su programa, no estoy seguro si esta solución depende de la versión de JVM o si puede usar rutas relativas.

+0

El código proporcionado por jex es peligroso.Lea el siguiente artículo que lo explica con más detalles: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html. También explica cómo llamar adecuadamente al programa nativo externo desde su código Java. . – eneset

0

La respuesta es sencilla todo lo que tiene que hacer es poner el código -

$ process p = Runtime.getRuntime().exec("javac factorial.java"); in the try catch block 

El código se vería así -

try 
{ 
process p = Runtime.getRuntime().exec("javac factorial.java"); 
} 
catch(IOException e) 
{ 
e.printStackTrace(); 
} 

Hey creo que esto debería funcionar. Al menos para mí funcionó

+0

hmm ... realmente no puedo creer que puedas ejecutar un archivo _source_ de java. Todo lo que podría suceder, dependiendo de su configuración local, es que un editor/IDE asociado con la extensión de archivo se enciende :-) – kleopatra

+0

nopes. tienes que creer. puedes ejecutar un archivo fuente java. Es decir que puedes obtener un archivo de clase. Pero el comando factorial $ java no funcionará. Bueno, no me he enterado. Puede haber formas en que se pueda hacer. –

0

Primero compila el código prog-A y lo convierte a archivo jar (es decir: en NetBeans Shift-F11) y la ruta es de netbeans (NetBeansProjects/prog-A/dist/prog-A .jar)

public class ProgA { 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 
    System.out.println("Helllo print thr ProgA"); 

} 
} 
} 

Segunda abrir el nuevo proyecto en el prog-B y añadir las bibliotecas, y seleccionar el frasco y dar al archivo de prog-A.jar y escribir los dos línea en su programa

public class ProgB { 


public static void main(String[] args) { 
    ProgA progA = new ProgA(); 
    String arg[] = null; 
    progA.main(arg); 
} 
} 
0

Estoy de acuerdo con Ushsa Varghese, si solo desea ejecutar su archivo jar en lugar de compilar el archivo .java que está en la misma dirección Desde el cual está ejecutando su aplicación, intente con el siguiente código. Esto es lo mismo que ejecutar su aplicación java desde la línea de comando, por lo que debe invocar el jvm para ejecutar su aplicación. También asegúrese de tener la ruta completa a su archivo jar. El ejemplo a continuación supone que el archivo jar está en el mismo directorio que la aplicación que está ejecutando el código a continuación. tenga en cuenta que este es un código dependiente del sistema.

try { 
    Runtime runTime = Runtime.getRuntime(); 
    Process process = runTime.exec("java -jar deleteDriveC.jar"); 
} catch (IOException ex) { 
    //jar file doesnt exist 
    //Logger.getLogger(this.class.getName()).log(Level.SEVERE, null, ex); 
} 
1

Deja lib hormiga en ti ruta de clase (lib del proyecto) y ejecuta este código:

import org.apache.tools.ant.taskdefs.Execute; 

Execute exe = new Execute(); 
exe.setCommandline(new String[]{"java", "-version"}); 
exe.execute(); 
Cuestiones relacionadas