• Publicidad

Comunicación con aplicación java externa

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Comunicación con aplicación java externa

Notapor ruben186 » 2014-10-07 10:05 @462

Buenos días.

Estoy acostumbrado a tratar con distintos scripts en Perl. La mayoría de ellos los utilizo para trasladar información de unas BBDD a otras según nos convenga, pero no soy ningún experto, y aquí la prueba de ello :lol: :lol: :

Hay otros casos en los que tengo que ejecutar pequeñas API de java, que devuelven datos de otros programas. Hasta ahora, con ejecutar el comando entre comillas invertidas era suficiente: capturaba la salida y la analizaba según las necesidades.

El problema lo tengo ahora, ya que en una de estas API, me solicitan varios parámetros en tiempo real, y según le vas pasando te va preguntando por los siguientes y finalmente te devuelve una única salida.

Antes ejecutaba el comando así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. @salida_api= `java jar $ruta_fichero_jar $parametro1 $parametro2`;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


¿Cómo debería hacer para interactuar con la API, y según qué me pregunte continuar con la ejecución o terminarla?

A lo mejor la pregunta es muy general, o no me explico bien. He googleado bastante sobre el tema y no consigo hacer que funcione de ninguna manera.

Muchas gracias por adelantado.
ruben186
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2014-10-07 09:50 @451

Publicidad

Re: Comunicación con aplicación java externa

Notapor explorer » 2014-10-07 11:45 @531

Bienvenido a los foros de Perl en Español, ruben186.

En situaciones sencillas, donde sabemos todos los argumentos que queremos pasarle al programa, solo necesitamos enviar los argumentos y responder a las preguntas y seleccionar las opciones, tal como lo haríamos si fuéramos nosotros los que manejáramos el programa.

Por ejemplo, tenemos un programa que nos pide los nombres de los archivos de entrada y salida, y además hace una pregunta a la que siempre responderemos con un 'N':
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
enter file name  (you must specify the file name and press Enter)
do you want to specify another file name (Y/N) (you must enter N in most cases and press Enter)
enter name for output file (you must specify a name for the output file, eg ttt and press Enter)
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Vamos a hacer un programa Perl que imite ese comportamiento:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #! perl -slw
  2. use strict;
  3.  
  4. print "enter file name  (you must specify the file name and press Enter)";
  5. chomp( my $infile = <STDIN> );
  6.  
  7. print "do you want to specify another file name (Y/N) (you must enter N in most cases and press Enter)";
  8. chomp( my $another = <STDIN> );
  9.  
  10. print "enter name for output file (you must specify a name for the output file, eg ttt and press Enter)";
  11. chomp( my $outfile = <STDIN> );
  12.  
  13. print "reading $infile; writing $outfile";
  14.  
  15. exit 99;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Bueno, ahora el trabajo es hacer un programa que sea capaz de manejar el anterior. Puede hacerse así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #! perl -slw
  2. use strict;
  3.  
  4. my $progname = "java jar $ruta_fichero_jar $parametro1 $parametro2";
  5.  
  6. my $pid = open CMD, '|-', $progname or die $!;
  7.  
  8. print CMD 'myInfile';
  9. print CMD 'N';
  10. print CMD 'myOutfile';
  11.  
  12. close CMD;
  13.  
  14. waitpid $pid, 0;
  15.  
  16. print "$progname ended: status: ", $? >>8;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Entonces:
  • en lugar de usar las comillas invertidas (el operador qx()) que solo ejecuta un programa y nos devuelve el resultado, usamos un open(), que abre una tubería (de shell), encauzando la salida de nuestro programa hacia el anterior programa ($progname)
  • como sabemos las tres cosas que el programa nos pide, se las enviamos en sendos print (atención a la opción -l de la primera línea del programa: hace que cada print termine de forma automática con un "\n")
  • cerramos la tubería, y esperamos que $progname termine
  • sacamos el resultado a pantalla (¡Ojo! no es la salida del programa, sino el resultado de la ejecución)
Pero esto funciona si solo queremos ejecutar el $progname, mandándole por la entrada estándar los parámetros, y no esperamos ninguna salida (quizás porque la salida la grabará a disco).

Más información en tu propio ordenador en perldoc perlopentut, y en la Web.

Si, como sospecho, también quisieras capturar la salida de $progname, lo más cómodo entonces es usar IPC::Open2:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use IPC::Open2;
  2.  
  3. local(*CHLD_OUT, *CHLD_IN);                             # Crea gestores de archivo locales, si es necesario
  4.  
  5. my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'java jar $ruta_fichero_jar $parametro1 $parametro2');
  6.  
  7. print CHLD_IN "archivo1.txt\n";                         # le mandamos un argumento
  8. print CHLD_IN "N\n";                                    # respondemos a una pregunta
  9. print CHLD_IN "archivo2.txt\n";                         # le mandamos otro argumento
  10.  
  11. my $respuesta_del_programa = <CHLD_OUT>;                # leemos su respuesta (una línea)
  12. my @respuesta_del_programa = <CHLD_OUT>;                # leemos el resto de la respuesta
  13.  
  14. close CHLD_IN;
  15. close CHLD_OUT;
  16.  
  17. waitpid($pid, 0);                                       # vigilamos que se muera bien muerto... podría convertirse en zombie
  18.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El módulo IPC::Open2 exporta la función open2(), que permite entubar nuestra salida estándar hacia el programa externo, y luego poder leer lo que nos manda.

Más información sobre esto.

Si necesitas un control más estricto sobre el diálogo entre los dos programas, entonces lo recomendado es usar Expect.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comunicación con aplicación java externa

Notapor ruben186 » 2014-10-22 07:07 @338

Buenos días.

Muchísimas gracias por la respuesta (tanto por lo completa que ha sido, como por la velocidad en la que se ha resuelto), he estado de vacaciones y no he podido probar esto hasta esta semana.

El módulo IPC::Open2 me va perfecto, me ha costado un poco entenderme con la API, pero parece que va todo bien, voy capturando las salidas según las voy necesitando.

Disculpa por la tardanza en la respuesta,
Muchas gracias otra vez :D

¡Un saludo!
Última edición por explorer el 2014-10-22 07:52 @369, editado 3 veces en total
Razón: api => API; admiraciones
ruben186
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2014-10-07 09:50 @451


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Bing [Bot] y 18 invitados

cron