jump to navigation

Capturar la pantalla con Java (Screen capture) marzo 30, 2007

Posted by superpiwi in Eclipse, Java, Programacion.
8 comments

Hoy en este post me he encontrado un trozo de codigo que nos permite capturar la pantalla del escritorio desde Java. Lo corto y pego porque esta curioso y tambien puede ser de utilidad cuando queramos capturar alguna ventana y no dispongamos de ninguna otra aplicacion de captura.

Aqui dejo el codigo:


import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
public class Captura
{
static public void captureScreen(String fileName) throws Exception {
Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRectangle = new Rectangle(screenSize);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRectangle);
ImageIO.write(image, "png", new File(fileName));
}
//----
public static void main(String[] args) {
try
{
System.out.println("[ Captura iniciada ]");
//sleep 5 sg
Thread.currentThread().sleep(5*1000);
String FILENAME="/home/jose/Desktop/captura01.png";
Captura.captureScreen(FILENAME);
System.out.println("[ Captura finalizada ]");
}
catch(Exception e)
{
e.printStackTrace();
}
}
//----
}
//end of class Captura

Le he añadido un sleep para dar tiempo a minimizar la ventana del Eclipse y poder capturar el escritorio, podrias implementar tu propio capturador, por ejemplo basado en tiempo o en la pulsacion de una tecla.

Aqui el resultado de mi captura 🙂

captura01.png

Desde BEA con amor marzo 30, 2007

Posted by superpiwi in Eclipse, Java, Programacion.
add a comment

En la siguiente direccion de Bea puedes descargarte una version de Callisto que entre otras cosas ya lleva incorporadas las Web Tools (WTP) para el desarrollo de aplicaciones web.

Visto en | JavaBlogger

oerr – Obtener la descripcion de un mensaje de error de Oracle marzo 22, 2007

Posted by superpiwi in Java, Oracle, Programacion, Unix.
2 comments

oerr (Oracle error utility) es un shell script que se instala en las bases de datos de Oracle y unicamente en las plataformas UNIX. Nos sirve para obtener rapidamente la descripcion de un error a partir de su codigo.


$(manager): /manager > oerr
Usage: oerr facility error
Facility is identified by the prefix string in the error message.
For example, if you get ORA-7300, "ora" is the facility and "7300"
is the error. So you should type "oerr ora 7300".
If you get LCD-111, type "oerr lcd 111", and so on.
$(manager): /manager > oerr ora 1000
01000, 00000, "maximum open cursors exceeded"
// *Cause:
// *Action:

Para windows existen alternativas.

http://www.oracleutilities.com/OSUtil/oerr.html

http://www.jlcomp.demon.co.uk/faq/windowsoerr.htm

Tambien para encontrar la descripcion del error puedes utilizar un buscador como Google, pero lo anterior te sirve cuando no siempre tienes acceso a Internet.

Crear un unico JAR marzo 21, 2007

Posted by superpiwi in Eclipse, Java, Programacion.
15 comments

«Un One-jar unico, Un One-jar para encontrarlos a todos y atarlos en las tinieblas».
(Perdonar la gracia, no he podido resistirme).

One-jar es una solucion que nos permite usar un unico jar para unir todas nuestras dependencias y hacer mas facil la distribucion de nuestras aplicaciones entre maquinas. Especialmente cuando nuestra aplicacion depende de multiples ficheros .jar. La idea es usar un unico fichero .jar.

Imaginate por ejemplo un proyecto que estas desarrollando y que internamente usa
estas tres librerias: log4j.jar, dom.jar y mysql.jar
Cuando quisieras llevar ese proyecto a otra maquina tendrias que mover 4 ficheros:
el de tu proyecto, p.ej si lo compilas y empaquetas como Miapp.jar
y esas otras 3 librerias.
Ademas tendrias que configurar el CLASSPATH para apuntar a esas librerias o incluir un fichero de manifiesto en Miapp.jar que indicara la ruta de las mismas. No seria mas sencillo tener un unico JAR con el codigo de tu aplicacion y que incluyera todo lo que necesitas utilizar. De eso trata One-jar.
Basicamente, se trata de un boot-loader que cuando lo inicializas carga en memoria todas las librerias que utilizas y ya no te da el conocido error de «Class Not Found» cuando intentas ejecutar tu aplicacion.

onejar03.jpg

Para utilizar one-jar descargate el siguiente fichero de su pagina web: one-jar-boot-0.95.jar

Tienes que montar una estructura de carpetas similar a la siguiente:

Cras una carpeta Tu_Proyecto y en ella añades lo siguiente:

Las clases de one-jar (las que resultan al descomprimir one-jar-boot-0.95.jar)

una Carpeta Main con el .jar de tu aplicacion (y que incluye internamente su manifiesto)

una Carpeta Lib (Las librerias que usas)
y el manifiesto de one-jar

Es decir,
tendras una carpeta Main donde dejaras el .jar de tu proyecto. Imaginate que tu proyecto se llama Miapp.jar, pues lo añades en esa carpeta sin olvidar de incluir el Manifiesto que es un fichero de esta
forma:

Manifest-Version: 1.0
Main-Class: <tu clase Main>
Class-Path: <las librerias que usas>

Es decir, este fichero de manifiesto tiene 3 entradas, en una de ellas (Main-Class) indicas la clase principal que quieres ejecutar, y en otra (Class-Path) indicas las librerias de las que depende, y que necesita para poder ejecutarse.

En la carpeta Lib añadirias todos esos .jar adicionales que usas. y por ultimo el manifiesto de one-jar que te encuentras al descomprimir el fichero descargado.

Con todo eso crearias un nuevo jar que empaquetas con el mismo nombre p.ej MiApp.jar de manera que al ejecutarlo con:

java -jar MiApp.jar

realmente se llama a la clase proncipal de one-jar que se encarga de cargar en memoria los .jar que usas y despues llama a tu clase principal. El resultado, se ejecuta tu clase principal y no necesita buscar los .jar adicionales porque ya estan cargados.

Es un poco complicado, Veamos de manera rapida como utilizarlo.

Yo tengo este proyecto:

mi clase principal se llama: comun.util.unix.ScriptActionExecution

y depende de estas librerias:

bsh-2.0b4.jar
profiler.jar
jsch-0.1.20.jar
log4j-1.2.8.jar
jdom.jar

El fichero de manifiesto («MANIFEST.MF») que tengo para mi aplicacion es:


Manifest-Version: 1.0
Main-Class: comun.util.unix.ScriptActionExecution
Class-Path: bsh-2.0b4.jar profiler.jar jsch-0.1.20.jar log4j-1.2.8.jar jdom.jar

onejar01.jpg

El fichero build.xml de ANT para generarlo podria ser el siguiente:


<?xml version="1.0"?>
<project name="clienteSSH" default="init" basedir=".">
<property name="fuente" value="." />
<property name="doc" value="javadoc" />
<property name="paquetes" value="comun.util.unix.*" />
<!-- textos relativos al proyecto -->
<property name="proyecto" value="clienteSSH" />
<property name="copyright" value="(k) 2005" />
<property name="jarfile" value="Main.jar" />
<target name="init">
<tstamp/>
<property name="nombre" value="Definiciones para Tareas"/>
<echo message="------------------- ${nombre} ----------------"/>
<property name="debug" value="on"/>
<property name="optimize" value="off"/>
<property name="deprecation" value="off"/>
<property name="build.compiler" value="classic"/>
<property name="target.vm" value="1.3"/>
<path id="classpath">
<fileset dir="./lib">
<include name="*.jar"/>
</fileset>
</path>
</target>
<target name="compilar" depends="init">
<echo message="-------------- Compilando Clases --------------"/>
<mkdir dir="build"/>
<javac srcdir="."
destdir="./build"
debug="${debug}"
optimize="${optimize}"
deprecation="${deprecation}"
target="${target.vm}">
<classpath refid="classpath"/>
</javac>
</target>
<target name="jar" depends="compilar">
<echo message="-------------- Generando Archivo JAR --------------"/>
<jar jarfile="Main.jar" manifest="./MANIFEST.MF" basedir="./build" includes="**"/>
</target>
<target name="limpiar" depends="compilar" >
<delete file="Main.jar"/>
</target>
<target name="limpiardoc">
<!--
Eliminamos los directorios de la vez anterior.
Eliminamos los dos juntos para no favorecer que
existan versiones de docuemntacion que no se
corresponden con las clases compiladas y viceversa
-->
<delete dir="${doc}" />
</target>
<target name="documentar" depends="limpiardoc">
<!--
Creamos el directorio si no existe. Y no existira porque
lo hemos eliminado con el objetivo limpiar, del cual
depende documentar
-->
<mkdir dir="${doc}" />
<!--
Generamos la documentcion de nuestro proyecto.
Los atributos de esta clase son incontables, asi
que ahora solo mostreré unos pocos. Consultar la
documentación de Ant y de javadoc si necesitais
algo más.
-->
<javadoc packagenames="${paquetes}"
sourcepath="${fuente}"
destdir="${doc}"
author="true"
version="true"
private="true"
locale="es"
windowtitle="API de ${proyecto}"
doctitle="${proyecto}"
bottom="${copyright}"
/>
</target>
<target name="one-jar" depends="jar" description="Build one ONE-JAR">
<property name="onejardir" location="./one-jar"/>
<mkdir dir="${onejardir}/main"/>
<mkdir dir="${onejardir}/lib"/>
<copy tofile="${onejardir}/${jarfile}"
file="lib/one-jar-boot-0.95.jar"/>
<copy todir="${onejardir}/main"
file="./${jarfile}"/>
<copy todir="${onejardir}/lib" flatten="true">
<fileset dir="lib" includes="*.jar"
excludes="one-jar-boot-0.95.jar"/>
</copy>
<jar jarfile="${onejardir}/${jarfile}" update="true"
basedir="${onejardir}" excludes="${jarfile}"/>
</target>
</project>

Disculpad el fichero ANT (lo he recuperado de hace unos cuantos añitos) seguro que es mejorable, pero de todas formas es funcional.

Aqui la tarea que nos interesa es «one-jar» pues al ejecutarla desde eclipse se me genera ya el fichero unico .jar con todas las dependencias incluidas. Que hace, pues lo que os comente al principio.

Me copia la estructura de lib/one-jar-boot-0.95.jar, tambien me añade al directorio «main» el .jar de mi aplicacion original (incluyendo
su fichero de manifiesto) y por ultimo añade a la carpeta «lib» todos esos .jar de los que depende mi aplicacion.
Y me genera un .jar nuevo (y unico) con el mismo nombre que el que haya configurado en la propiedad ${jarfile} que en este caso es
«Main.jar»

y para ejecutarlo me lo llevo el .jar recien generado a cualquier maquina con el JRE correspondiente y lo invoco como java -jar Main.jar (no hay problemas ya de Class not found)

onejar02.jpg

Mas informacion

Templates en Eclipse marzo 20, 2007

Posted by superpiwi in Eclipse, Java, Programacion.
2 comments

La primera vez que descubri las plantillas en Eclipse me sorprendio gratamente (Te ahorrabas escribir mucho codigo repetitivo). ¿Que no sabeis de que os hablo?. Enseguido te lo enseño.

Abre el editor de eclipse y ponte a escribir una clase, cuando tengas el cuerpo escribe en el texto «main» y pulsa Control+Espacio (¿sorprendido?). Pues haz lo mismo con «try» y pulsa Control+Espacio. se te autocompleta el bloque.

La ventaja de las plantillas es que puedes escribir las tuyas propias.

Hoy en Dzone Snippets me he encontrado una interesante, la que implementa el patron «Singleton«.

Abre el editor de Eclipse. ve a Window->Preferences->Java->Editor->Templates y pulsa el boton «New…» e inserta el siguiente codigo:


private static ${enclosing_type} instance;
private ${enclosing_type}(){}
public static ${enclosing_type} getInstance(){
if(null == instance){
instance = new ${enclosing_type}();
}
return instance;
}

Dale un nombre, p.ej «Singleton» y Acepta.

template01.jpg

Ya puedes usar la nueva plantilla donde quieras. Cuando escribas una nueva clase escribe el texto «Singleton» y pulsa a continuacion Control+Espacio, automaticamente te permitira añadir el bloque creado anteriormente.

Y otra plantilla para generar un comentario en los ficheros creados:


/*-
* @(#)${file_name} %I% %G%
*/

Cheat sheets para dar y tomar marzo 18, 2007

Posted by superpiwi in Java, Programacion.
1 comment so far

En la siguiente direccion: The Developer Cheat Sheet Compilation podeis encontrar un monton de cheat sheets agrupadas por tematicas. Las de Oracle estan genial.

Ejecutar Shell Scripts desde Java marzo 14, 2007

Posted by superpiwi in Java, Oracle, Programacion, Unix.
13 comments

Y ya que hemos hablado en el Post anterior de Shell Scripts, porque no ejecutarlos directamente desde codigo fuente con Java. Antes de nada recomiendo una lectura:

When Runtime.exec() won’t

En este caso he creado una clase propia «Script.java» y he adaptado la del ejemplo que aparece en el articulo anterior.

Esta clase Script nos permite ejecutar comandos y shell scripts empleando el interprete de comandos.

Por ejemplo el siguiente codigo:


Script sc = new Script();
sc.setVerbose(true);
String CONTENT = "sqlplus2\nls -l\nps\necho \"End\\nFin\"";
String OUTPUT = sc.executeScript(CONTENT,
"/home/jose/Desktop/MiScript.sh", true);
System.out.println(OUTPUT);
String ERROR = sc.getError();
System.out.println("**ERROR**" + ERROR);

Como observais estoy lanzando la ejecucion de estos tres comandos:


sqlplus2 (que no existe y dara error)
ls -l
ps
y un echo End salto de linea Fin

Al ejecutar este codigo desde java nos devolveria lo siguiente:


ERROR> /home/jose/Desktop/MiScript.sh: 1: sqlplus2: not found
OUTPUT> total 44
OUTPUT> drwxr-xr-x 3 jose jose 4096 2007-01-11 09:18 ant
OUTPUT> drwxr-xr-x 6 jose jose 4096 2007-02-01 17:34 build
OUTPUT> -rw-r--r-- 1 jose jose 12953 2007-02-01 17:34 build.xml
OUTPUT> drwxr-xr-x 2 jose jose 4096 2007-01-11 09:17 CVS
OUTPUT> drwxr-xr-x 7 jose jose 4096 2007-01-11 09:17 Documentacion
OUTPUT> drwxr-xr-x 7 jose jose 4096 2007-01-11 09:17 JavaSource
OUTPUT> -rwxr-xr-x 1 jose jose 111 2007-03-14 17:13 pepe.sh
OUTPUT> drwxr-xr-x 11 jose jose 4096 2007-02-20 15:52 WebContent
OUTPUT> PID TTY TIME CMD
OUTPUT> 4887 ? 00:00:00 gconfd-2
OUTPUT> 11652 ? 00:00:00 x-session-manag
OUTPUT> 11665 ? 00:00:02 Scribe.exe <defunct>
OUTPUT> 11693 ? 00:00:00 ssh-agent
OUTPUT> 11696 ? 00:00:00 dbus-daemon
OUTPUT> 11697 ? 00:00:00 dbus-launch
OUTPUT> 11700 ? 00:00:00 gnome-keyring-d
OUTPUT> 11703 ? 00:00:03 gnome-settings-
OUTPUT> 11727 ? 00:00:27 metacity
OUTPUT> 11732 ? 00:00:23 gnome-panel
OUTPUT> 11734 ? 00:00:15 nautilus
OUTPUT> 11738 ? 00:00:00 bonobo-activati
OUTPUT> 11741 ? 00:00:00 gnome-vfs-daemo
OUTPUT> 11747 ? 00:00:00 update-notifier
OUTPUT> 11749 ? 00:00:00 gnome-volume-ma
OUTPUT> 11751 ? 00:00:00 evolution-alarm
OUTPUT> 11759 ? 00:00:10 trackerd
OUTPUT> 11762 ? 00:00:15 gnome-cups-icon
OUTPUT> 11774 ? 00:00:02 python
OUTPUT> 11776 ? 00:00:00 trashapplet
OUTPUT> 11779 ? 00:00:00 evolution-data-
OUTPUT> 11803 ? 00:00:00 evolution-excha
OUTPUT> 11833 ? 00:00:00 mapping-daemon
OUTPUT> 11834 ? 00:00:00 gnome-power-man
OUTPUT> 11843 ? 00:00:00 mixer_applet2
OUTPUT> 11885 ? 00:00:02 notification-da
OUTPUT> 11912 ? 00:00:05 gnome-screensav
OUTPUT> 12025 ? 00:01:49 skype
OUTPUT> 12094 ? 00:04:30 firefox-bin
OUTPUT> 12270 ? 00:00:00 eclipse
OUTPUT> 12276 ? 00:03:44 java
OUTPUT> 14360 ? 00:00:03 gnome-terminal
OUTPUT> 14369 ? 00:00:00 gnome-pty-helpe
OUTPUT> 14597 ? 00:01:59 wineserver
OUTPUT> 14599 ? 00:00:00 explorer.exe
OUTPUT> 17598 ? 00:00:00 java
OUTPUT> 17617 ? 00:00:00 sh
OUTPUT> 17618 ? 00:00:00 sh
OUTPUT> 17622 ? 00:00:00 ps
OUTPUT> End
OUTPUT> Fin
total 44
drwxr-xr-x 3 jose jose 4096 2007-01-11 09:18 ant
drwxr-xr-x 6 jose jose 4096 2007-02-01 17:34 build
-rw-r--r-- 1 jose jose 12953 2007-02-01 17:34 build.xml
drwxr-xr-x 2 jose jose 4096 2007-01-11 09:17 CVS
drwxr-xr-x 7 jose jose 4096 2007-01-11 09:17 Documentacion
drwxr-xr-x 7 jose jose 4096 2007-01-11 09:17 JavaSource
-rwxr-xr-x 1 jose jose 111 2007-03-14 17:13 pepe.sh
drwxr-xr-x 11 jose jose 4096 2007-02-20 15:52 WebContent
PID TTY TIME CMD
4887 ? 00:00:00 gconfd-2
11652 ? 00:00:00 x-session-manag
11665 ? 00:00:02 Scribe.exe <defunct>
11693 ? 00:00:00 ssh-agent
11696 ? 00:00:00 dbus-daemon
11697 ? 00:00:00 dbus-launch
11700 ? 00:00:00 gnome-keyring-d
11703 ? 00:00:03 gnome-settings-
11727 ? 00:00:27 metacity
11732 ? 00:00:23 gnome-panel
11734 ? 00:00:15 nautilus
11738 ? 00:00:00 bonobo-activati
11741 ? 00:00:00 gnome-vfs-daemo
11747 ? 00:00:00 update-notifier
11749 ? 00:00:00 gnome-volume-ma
11751 ? 00:00:00 evolution-alarm
11759 ? 00:00:10 trackerd
11762 ? 00:00:15 gnome-cups-icon
11774 ? 00:00:02 python
11776 ? 00:00:00 trashapplet
11779 ? 00:00:00 evolution-data-
11803 ? 00:00:00 evolution-excha
11833 ? 00:00:00 mapping-daemon
11834 ? 00:00:00 gnome-power-man
11843 ? 00:00:00 mixer_applet2
11885 ? 00:00:02 notification-da
11912 ? 00:00:05 gnome-screensav
12025 ? 00:01:49 skype
12094 ? 00:04:30 firefox-bin
12270 ? 00:00:00 eclipse
12276 ? 00:03:44 java
14360 ? 00:00:03 gnome-terminal
14369 ? 00:00:00 gnome-pty-helpe
14597 ? 00:01:59 wineserver
14599 ? 00:00:00 explorer.exe
17598 ? 00:00:00 java
17617 ? 00:00:00 sh
17618 ? 00:00:00 sh
17622 ? 00:00:00 ps
End
**ERROR**/home/jose/Desktop/MiScript.sh: 1: sqlplus2: not found

Sencillo y potente!!!

Tambien permite ejecutar shell scripts creandolos dinamicamente. esto por ejemplo nos sirve para lanzar scripts que solo contienen sentencias SQL. Por ejemplo el siguiente caso:


Script sql = new Script();
sql.setVerbose(false);
sql.setAddSHELLHEADER(true);
sql.setSHELLHEADER("#!/bin/sh");
//sql.setRUTA("/home/jose/Desktop");
CONTENT = "SELECT sysdate FROM DUAL;\nSELECT sysdate FECHA_HOY FROM DUAL;";
OUTPUT = sql.executeSQLScript(CONTENT, "EVO", "EVO", "EVODES",
null, "/home/jose/Desktop/MiSQL.sh", false);
System.out.println(OUTPUT);
ERROR = sql.getError();
System.out.println("**ERROR**" + ERROR);

Que nos devolveria:


SQL*Plus: Release 10.2.0.3.0 - Production on Wed Mar 14 17:38:06 2007
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning option
JServer Release 9.2.0.8.0 - Production
SQL>
SYSDATE
---------
14-MAR-07
SQL>
FECHA_HOY
---------
14-MAR-07
SQL> Disconnected from Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning option
JServer Release 9.2.0.8.0 - Production
**ERROR**

Aqui el truco es generar dinamicamente un fichero .sh con el contenido que se quiere ejecutar y luego lanzar el interprete de comandos para ejecutar ese fichero creado dinamicamente.

Pero mejor veis las clases y ya trasteais con ellas. Aqui las dejo.

StreamGlobber.java


/**
* StramGobbler.java
*
* Para capturar la salida de la ejecucion del comando.
*
* @modified clase original de javaworld modificada por jdelgado
* @version 0.0.0.2 - 13 Marzo 2007
* @sinde JDK 1.5 - Eclipse 3.2
*/
package comun.util.unix;
import java.io.*;
class StreamGobbler extends Thread {
// Flujo de entrada
InputStream is;
// Tipo de Flujo: generalmente output o error
String type;
// Flujo de salida
OutputStream os;
// Variable para mostrar por la salida estandard
boolean debug = false;
// para guardar la salida generada
String output = "";
// ----
/**
* Constructor
*
* @param is
* InputStream
* @param type
* tipo de flujo (OUTPUT o ERROR)
* @param debug
* indica si se debe mostrar o no la salida por la salida
* estandard
*/
StreamGobbler(InputStream is, String type, boolean debug) {
this(is, type, null, debug);
}
// ----
/**
* Constructor
*
* @param is
* InputStram
* @param type
* tipo de flujo (OUTPUT o ERROR)
* @param redirect
* OutputStream donde redireccionar la salida
* @param debug
* indica si se debe mostrar o no la salida por la salida
* estandard
*/
StreamGobbler(InputStream is, String type, OutputStream redirect,
boolean debug) {
this.is = is;
this.type = type;
this.os = redirect;
this.debug = debug;
}
// ----
/**
* Ejecutar el hilo
*/
public void run() {
try {
PrintWriter pw = null;
if (os != null)
pw = new PrintWriter(os);
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
// si hay fichero lo imprime a fichero
if (pw != null)
pw.println(line);
if (debug)
System.out.println(type + "> " + line);
output = output + line + "\r\n";
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
// ------
/**
* Recuperar el flujo de datos generado
*
* @return un String con el output
*/
public String getOutput() {
return output;
}
// ------
}
// end of class StreamGobbler.java

y la clase Script.java:


/**
* Script.java
*
* Clase para ejecutar scripts unix o SQL localmente
*
* @author jdelgado
* @version 0.0.0.1 - 13 Marzo 2007
* @since JDK 1.5 - Eclipse 3.2
*
*/
package comun.util.unix;
import java.io.File;
import java.io.FileOutputStream;
public class Script {
// contenido a ejecutar
private String content = null;
// interprete de comandos: Si usas Windows adaptalo para usar CMD
private String SHELL = "/bin/sh";
// resultado de la ejecucion
private String output = null;
// posibles errores en la ejecucion
private String error = null;
// imprimir o no traza en los threads
private Boolean verbose = false;
// path por defecto para ficheros temporales
private String RUTA = "/tmp";
// cabecera para shell scripts
private String SHELLHEADER = "#!/bin/sh";
// indica si hay que añadir el interprete a los shell scripts que se generen
private boolean addSHELLHEADER = false;
// caracter de retorno
private String RETORNO = "\n";
// ----
/**
* Constructor. crea una nueva instancia de la clase
*/
public Script() {
}
// ----
/**
* Constructor. crea una nueva instancia de la clase
*
* @param content
* contenido del script a ejecutar
*/
public Script(String content) {
this.content = content;
}
// ----
/**
* Ejecuta el script
*
* @throws Exception
* excepcion levantada en caso de error
*/
public String executeCommand() throws Exception {
output = null;
error = null;
StreamGobbler errorGobbler = null;
StreamGobbler outputGobbler = null;
try {
if (content == null)
throw new Exception("command is null");
// String ruta="/home/jose/Desktop/temporal.txt";
// FileOutputStream fos = new FileOutputStream(ruta);
Runtime rt = Runtime.getRuntime();
// Process proc = rt.exec(new String[]{"/bin/sh", "-c", "cd
// /home/jose/Desktop\n./SQLPLUS.sh\ncal\\nps -ef"});
String[] data = new String[3];
data[0] = this.SHELL;
data[1] = "-c";
data[2] = this.content;
Process proc = rt.exec(data);
// any error message?
errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR",
this.verbose);
// any output?
outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT",
null, this.verbose);
// StreamGobbler(proc.getInputStream(), "OUTPUT", fos);
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
} catch (Throwable t) {
t.printStackTrace();
} finally {
String out = outputGobbler.getOutput();
this.output = out;
output = out;
out = errorGobbler.getOutput();
this.error = out;
error = out;
}
return output;
}
// ----
/**
* Recupera la salida de la ejecucion del comando
* @return un string con el resultado de la ejecucion
*/
public String getOutput() {
return output;
}
// ----
/**
* Recupera el error de la ejecucion del comando
* @return un string con el error de la ejecucion
*/
public String getError() {
return error;
}
// ----
/**
* Ejecuta un Script creando un fichero .sh con el contenido y ejecutandolo
*
* @param content
* contenido del script
* @param pathname
* el nombre del fichero que se crea si es null lo crea en /tmp y
* de la forma /tmp/timestamp.sh
* @param delete
* indica si se debe borrar o no el fichero temporal tras su
* ejecucion
* @result el resultado de la ejecucion del Script
* @throws Exception
* Excepcion levantada en caso de error
*/
public String executeScript(String content, String pathname, boolean delete)
throws Exception {
File f = null;
FileOutputStream fout = null;
try {
// crear fichero .sh
if (pathname == null) {
long timestamp = System.currentTimeMillis();
pathname = RUTA + File.separator + timestamp + ".sh";
}
if (this.addSHELLHEADER)
{
content = this.SHELLHEADER+this.RETORNO+content;
}
traza("executeScript","Generando fichero [" + pathname + "]...");
f = new File(pathname);
fout = new FileOutputStream(f);
fout.write(content.getBytes());
if (fout != null)
fout.close();
traza("executeScript","Fichero generado");
// darle permisos de ejecucion
traza("executeScript","Asignando permisos...");
Script permisos = new Script("chmod +x " + pathname);
permisos.setVerbose(this.verbose);
permisos.executeCommand();
String error = permisos.getError();
if (error != null) {
if (error.length() > 0)
throw new Exception("Permission denied : " + error);
}
traza("executeScript","Permisos asignados");
// ejecutar fichero .sh
traza("executeScript","Ejecutando script...");
Script ejecucion = new Script(pathname);
ejecucion.setVerbose(this.verbose);
String result = ejecucion.executeCommand();
error = ejecucion.getError();
this.error = error;
this.output = result;
traza("executeScript","Script ejecutado");
// eliminar fichero .sh
if (delete) {
if (f != null) {
if (f.exists())
f.delete();
}
traza("executeScript","fichero eliminado");
}
return result;
} catch (Exception e) {
throw e;
}
}
// ----
/**
* Para probar el correcto funcionamiento de la clase
* @param args argumentos de entrada
*/
public static void main(String[] args) {
try {
// sqlplus directamente no mejor ejecutar sh shellscript.sh que tenga el
// contenido
// Script sc = new Script("ls -l\ncal2\nps -ef | grep
// java\nsqlplus");
// sc.setDebug(false);
// String output = sc.executeCommand();
// System.out.println("OUT:-------------------\r\n"+output);
// String error = sc.getError();
// System.out.println("ERROR:-----------------\r\n"+error);
// output = sc.getOutput();
// System.out.println("output:\r\n"+output);
// System.out.println("***ERROR***");
// String err = sc.getError();
// System.out.println("error:"+err);
Script sc = new Script();
sc.setVerbose(true);
String CONTENT = "sqlplus2\nls -l\nps\necho \"End\\nFin\"";
String OUTPUT = sc.executeScript(CONTENT,
"/home/jose/Desktop/MiScript.sh", true);
System.out.println(OUTPUT);
String ERROR = sc.getError();
System.out.println("**ERROR**" + ERROR);
Script sql = new Script();
sql.setVerbose(false);
sql.setAddSHELLHEADER(true);
sql.setSHELLHEADER("#!/bin/sh");
//sql.setRUTA("/home/jose/Desktop");
CONTENT = "SELECT sysdate FROM DUAL;\nSELECT sysdate FECHA_HOY FROM DUAL;";
OUTPUT = sql.executeSQLScript(CONTENT, "EVO", "EVO", "EVODES",
null, "/home/jose/Desktop/MiSQL.sh", false);
System.out.println(OUTPUT);
ERROR = sql.getError();
System.out.println("**ERROR**" + ERROR);
} catch (Exception e) {
e.printStackTrace();
}
}
// ----
/**
* Completa un script de SQL para poder ejecutarlo con sqlplus desde un
* shell script
*
* @param sqlcontent
* sentencias SQL
* @param user
* usuario de base de datos
* @param password
* password de la base de datos (TODO: guardar encriptada)
* @param sid
* sid de la base de datos
* @param redirect
* si se indica es el fichero donde se redirecciona la salida del
* sqlplus
* @return un string con el sqlplus
*/
public String prepareSQLScript(String sqlcontent, String user,
String password, String sid, String redirect) {
if (redirect == null)
redirect = "";
else
redirect = "> " + redirect;
String INICIO_SQL = "sqlplus " + user + "/" + password + "@" + sid
+ " << EOF" + " " + redirect;
String FIN_SQL = "EOF";
String sql = sqlcontent;
sql = INICIO_SQL + RETORNO + sql + RETORNO + "exit" + RETORNO + FIN_SQL;
return sql;
}
// ----
/**
* Ejecuta un Script SQL mediante sqlplus
*
* @param sqlcontent
* las sentencias SQL
* @param user
* usuario de la base de datos
* @param password
* la password de la base de datos
* @param redirect
* si se indica es el fichero donde se redirecciona la salida del
* sqlplus
* @param pathname
* nombre del shell script que se crea
* @param delete
* indica si se debe borrar o no el shell script tras la
* ejecucion
* @return el resultado de la ejecucion del script
*/
public String executeSQLScript(String sqlcontent, String user,
String password, String sid, String redirect, String pathname,
boolean delete) throws Exception {
String SQL_CONTENT = prepareSQLScript(sqlcontent, user, password, sid,
redirect);
return executeScript(SQL_CONTENT, pathname, delete);
}
// ----
/**
* Recupera el valor del flag
* @return el valor del flag
*/
public Boolean getVerbose() {
return verbose;
}
// ----
/**
* Fija el valor del flag para mostrar por la consola estandard la ejecucion
* @param debug el valor del flag
*/
public void setVerbose(Boolean debug) {
this.verbose = debug;
}
// ----
/**
* Para imprimir un mensaje de traza
*
* @param metodo
* nombre del metodo
* @param mensaje
* nombre de la clase
*/
public void traza(String metodo, String mensaje) {
// TODO: reemplazar aqui para emplear LOG4J
// System.out.println(mensaje);
}
// ----
public boolean isAddSHELLHEADER() {
return addSHELLHEADER;
}
public void setAddSHELLHEADER(boolean addSHELLHEADER) {
this.addSHELLHEADER = addSHELLHEADER;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getRETORNO() {
return RETORNO;
}
public void setRETORNO(String retorno) {
RETORNO = retorno;
}
public String getRUTA() {
return RUTA;
}
public void setRUTA(String ruta) {
RUTA = ruta;
}
public String getSHELL() {
return SHELL;
}
public void setSHELL(String shell) {
SHELL = shell;
}
public String getSHELLHEADER() {
return SHELLHEADER;
}
public void setSHELLHEADER(String shellheader) {
SHELLHEADER = shellheader;
}
public void setError(String error) {
this.error = error;
}
public void setOutput(String output) {
this.output = output;
}
}
// end Script.java

Pueden ser de utilidad cuando queremos automatizar tareas (ejecucion automatica de shell scripts) y no queremos meternos en mucha faena escribiendolos en ANT. Pero bueno, de esto ya hablaremos otro dia…

shell.jpg

Algunas formas de ejecutar sqlplus desde un Shell Script marzo 14, 2007

Posted by superpiwi in Java, Oracle, Programacion, Unix.
32 comments

Aqui un pequeño Tip. Imaginate que tienes una base de datos llamada DESA en tu tnsnames.ora y es de la forma:


DESA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = DESA)
)
)

Para un usuario de base de datos DESA con password DESA.

Desde linea de comandos una forma de ejecutar sentencias sql es mediante SQLPLUS. Tu abririas la session con:

sqlplus desa/desa@DESA (es de la forma user/password@SID)

y ya podrias empezar a escribir las sentencias SQL, cuando quisieras terminar teclearias el comando «exit» y terminarias la sesion con sqlplus. Si quisieramos hacer lo mismo pero desde un shell script podriamos hacer lo siguiente (presentare varias formas, no se si habra mas pero estas pueden serte de utilidad).

La primera es mediante el comando echo:


echo "lista de sentencias SQL....separadas con \n" | sqlplus desa/desa@DESA

Por ejemplo:


#!/bin/sh
echo "SELECT sysdate FROM DUAL;\nSELECT sysdate FECHA FROM DUAL" | sqlplus desa/desa@DESA


(\n es el retorno de carro, es como si pulsaramos la tecla Intro, para ir separando las diferentes sentencias SQL)

Otra opcion es la misma pero en vez de pasarle un listado con las sentencias le indicamos con el operador @ la ruta de un fichero sql con las sentencias (no te olvides de acabar con un commit; y/o exit; si fuera necesario).

echo "@/ruta fichero sql" | sqlplus user/password@bd

Ejemplo:


#!/bin/sh
echo "@/home/jose/sqls/insertar.sql" | sqlplus desa/desa@DESA

Arrancaria una sesion de sqlplus y ejecutaria el contenido del fichero «/home/jose/sqls/insertar.sql»

y la ultima y generalmente mas usada es la siguiente:


sqlplus user/pass@BD << ETIQUETA > redireccion
sentencias SQL...
ETIQUETA

Por ejemplo:


#!/bin/sh
sqlplus desa/desa@DESA << EOF > ./output.log
SELECT sysdate FROM DUAL;
SELECT sysdate FECHA FROM DUAL;
EOF

Ejecutaria todas las sentencias SQL entre ETIQUETA y fin de ETIQUETA. En este ultimo caso, Al ejecutar el script, desde la consola, obtenemos lo siguiente:


SQL*Plus: Release 10.2.0.3.0 - Production on Wed Mar 14 14:05:08 2007
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning option
JServer Release 9.2.0.8.0 - Production
SQL>
SYSDATE
---------
14-MAR-07
SQL>
FECHA
---------
14-MAR-07
SQL> Disconnected from Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning option
JServer Release 9.2.0.8.0 - Production
jose@soledad:~/Desktop$

Es util para construirnos nuestros shell script y poder modificar el modelo de datos de la base de datos ejecutandolos desde un terminal.

Instalar JDK + Eclipse + Tomcat en Ubuntu Edgy marzo 14, 2007

Posted by superpiwi in Eclipse, Java, Programacion.
5 comments

http://ubuntulife.wordpress.com/2007/03/14/intalar-jdk-eclipse-tomcat/

1000 visitas marzo 7, 2007

Posted by superpiwi in Uncategorized.
add a comment

Alcanzamos hoy las 1000 visitas. Que curioso, Pensaba que no habia tantas personas a las que les gustara Java como a mi. Es broma. Muchas gracias por vuestras visitas.