Sidelab Commons

SidelabCode tiene un nuevo proyecto, liberado bajo una licencia de código abierto. Se trata de Sidelab Commons. El objetivo de Sidelab Commons es exportar pequeñas librerías de utilidad para que puedan ser utilizadas desde otros proyectos.

Para explicar en más detalle el objetivo del proyecto, aunque muchos ya habrán realizado una asociación con el proyecto Apache Commons, nos centraremos en un caso particular. En varias ocasiones nos hemos encontrado con la necesidad de invocar comandos, a través de la API Runtime (más concretamente Runtime.exec), desde java. Además, esta funcionalidad la hemos requerido desde proyectos muy diferentes:

  • En Optsicom Remote Experiment System (Optsicom RES) se utiliza para ejecutar en una máquina remota un programa Java arrancando una nueva VM.
  • En Optsicom Framework se utiliza para ejecutar un experimento en una VM diferente.
  • En Pascaline, un plugin de Eclipse para Pascal, se utiliza para invocar el compilador de FreePascal.
  • SidelabCode Stack, el instalador de la forja de SidelabCode, se utiliza para invocar apt-gets y todo tipo de comandos que permiten configurar adecuadamente los servicios de la forja.
  • En proyectos que hemos desarrollado para empresas también hemos necesitado invocar comandos externos a menudo.

El uso de Runtime.exec no es trivial. Además de las diferentes versiones disponibles, hay que tener en cuenta la captura de la salida estándar y la salida de error del proceso que se está lanzando. Normalmente, para cerciorarnos de que el proceso ha terminado correctamente es necesario:

  • Al terminar el proceso comprobar el código de salida
  • Recuperar la salida estándar
  • Recuperar la salida de error

La recuperación de las salidas del proceso requiere la creación de un hilo para la salida estándar y otro para la salida de error que consumen los datos de los respectivos InputStreams hasta que el proceso los cierra. Básicamente, el código tiene este aspecto:

new Runnable() {
  public void run() {
    try {
      byte[] buffer = new byte[1024];
      int leidos = 0;
      while ((leidos = System.in.read(buffer)) != 0) {
        out.write(buffer, 0, leidos);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}

Como esto es tedioso de hacer cada vez, en su día lo factorizamos en una pequeña librería que llamamos commandline. Ahora, hemos abierto el proyecto Sidelab Commons para alojar este tipo de recursos. Actualmente, cualquier proyecto puede hacer uso de commandline, y obtener de forma sencilla la salida de un proceso:

CommandLine cl = new CommandLine(); // Opcionalmente podríamos especificar el dir de trabajo en el constructor.
CommandOutput co = cl.syncExec("tail /etc/apache2/sites-enabled/default");
System.out.println(co.getStandardOutput());
System.out.println(co.getErrorOutput());

Puedes descargar commandline o añadirlo como dependencia a tu pom. Echa un vistazo a nuestro archiva.

Por cierto, recuerda que cuando invocas comandos desde Java, no estás ejecutando el comando dentro de una shell, y por tanto no funcionan los wildcards (cosas como ls *.java). Si necesitas realmente ejecutar tu comando desde una shell para que te interprete adecuadamente este tipo de comodines usa bash -c ‘ls *.java’ o mira la documentación de la shell que soporte tu sistema. Nosotros, por ejemplo, hemos tenido problemas ejecutando un proceso en Windows y tuvimos que utilizar “cmd /c” para correrlo dentro de la shell de Windows en modo no interactivo. Puedes echar un vistazo a esto en el proyecto Pascaline.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s