30 de abril de 2008

Blog cerrado (temporalmente??)

Cierro este blog y me mudo a wordpress. La razon? no hay una en especial, lo probé unos dias y me pareció bueno. Las herramientas de administración son muy variadas. Vamos a ver como se sigue comportando blogger, y si ofrece algo más interesante de pronto vuelva. Lo importante es que seguiré publciando y dando opiniones, tips y consejos en mi nuevo blog.

3 de abril de 2008

Enviar mails desde netbeans 6

Netbeans 6, pretende facilitar enormemente las tareas del desarrollador. En el siguiente ejemplo demostraré como crear una sencila aplicación para enviar mails desde un servidor de correo, en este caso en particular a través de una cuenta de gmail. La aplicación será generada prácticamente en su totalidad por netbeans, y solo tendremos que añadir y modificar unas partes. Crea una aplicación web, denomínala EjemploMail y le agregas el framework visual server faces. Agregale los componentes necesarios para que se vea como una página que utilizarás para componer y enviar emails. UNa interfaz que tenga un input para escribir el destinatario del mail, otro para el título del mensaje (subject), y uno más para el contenido. Por su longitud, lo más lógico es agregar este último como textarea. Les debe quedar algo como esto:
Luego hacemos doble click en el boton "Enviar". Esto nos llevará a la vista de código java de la página. Más exactamente, dentro del código a ejecutarse para el botón. En la barra lateral llama "Paleta" encontraremos varias plantillas de código. Por ejemplo código que contiene bloques try/catch, bucle for, y algunos códigos prediseñados para recorres consultas (dataproviders). Dentro de estos códigos existe uno que se llama "Send mail" ubicado en la sección Web App Functions. Haga click en el y arrástrelo hacia el método que contiene el evento del botón. La figura muestra donde esta ubicado el código plantilla, y hasta dónde debe ser arrastrado.
Luego de soltar el código plantilla de la paleta, aparecerá un cuadro de diálogo pidiendonos algunos parametros para enviar el mail. Mejor los dejamos vacios y los llenamos desde el código, donde netbeans nos ayudará a completarlo. Asi que simplemenete damos click en "OK".
Ahora cuando vamos a echarle un vistazo al código, vemos el código plantilla que netbenas ha generado. Se trata de algo más de 60 líneas de código. Al comienzo están las variables que nos pedía el cuadro de diálogo. Cada una de ellas aparece declarada como "String" a las cuales se ha incializado con un valor vacío, excepto la variable "message", q no aparecía en el cuadro de diálogo. Bueno, vamos a llenar los campos: La variable "To" indica el destinatario, asi q a esta variable le asignamos el textfield que recibirá el destino. La variable "From" indica el usuario que envia, alli escribiré mi driección de correo de gmail completa, incluyendo @gmail.com La variable "subject" indica el titulo del mensaje. En la variable "message" colocams el texto que venga del textarea. La variable "server" la llenamos con la dirección del servidor de correo saliente que tengamos asociado. Para gmail es smpt.gmail.com En "user" coloca tu user de gmail. Es decir, el correo, pero SIN el @gmail.com y en "password".... ya sabes. Verifica que la variable boolean llamada "ssl" esté en true. Esta última configuración solo es propia de gmail. Si vas a enviar correo desde otro servidor debes verificar sus respectivos protocolos y puertos. Para especificarla un puerto a la conexion con el servidor smtp puedes agregar la sgte linea de código: props.put("mail.smtp.port", puerto); Donde, "puerto" es una variable tipo String que contiene el número del puerto para conectarse con el servidor. Para comprobar que el mail sea enviado, agregamos un "groupMessage" a la página. Un GroupMessage es un componente sencillo que nos permite mostrar mensajes de error o información adicional. Desde la vista de diseño, arrastralo de la paleta. Se encuentra dentro de los componentes woodstock basic. Para enviarle información escribimos desde cualquier parte de la página: info("Mensaje de confirmación"); error("Mensaje de error"); Adicional a estos 2 métodos, existe un tercero denominado log(String msj), con el cual anotamos en el log del servidor de aplicaciones en que este montada la aplicación. Coloca un mensaje de exito después de la línea de código: log("Mail was sent successfully."); ubicada justo antes de cerrar el try e iniciar el catch, y una linea con un mensaje de error, apenmas un par de lineas abajo, justo después de la línea log("Smtp_Send_Failed:"); Tip: si quieres enviar texto en código html, debes modificar un atributo del objeto msg el cual es de tipo javax.mail.Message. Este objeto es el que va a contener el mensaje. Asi que justo después que se le asigne el mensjae pones la siguiente línea: msg.setContent(message, "text/html"); El bloque de código queda más o menos asi: msg.setSubject(subject); msg.setSentDate(new Date()); msg.setText(message); msg.setContent(message, "text/html"); Si agregas esa línea antes de que asignes el mensaje, lo mmás seguro es que no funcione correctamente. Pronto veré como hago para montarles el ejemplo completo.

1 de febrero de 2008

Auto-Boxing

Desde Java 5, existe una característica denominada como: Auto-Boxing. Algo asi como un auto-empacador (dejemoslo en auto-boxing) suena mejor, no?. Mejor veamos un ejemplo de como funciona. Antes de Java 5, si se quería utilizar una clase "Wrapper" (Integer, Double, Long, etc...), durante la ejecución, se necesitaba aplicar operaciones matemáticas sobre el objeto "wrapper", era necesario algo asi:

Integer y = new Integer(567); // Crear el objeto
// Muchas lineas de código aquí....
int x = y.intValue(); // Obtener su valor numérico...
x+=1550; // Realizar operación matemática...
y = new Integer(x); // Volverlo a guardar en la variable
System.out.println("y = " + y); // Imprimir por pantalla


Sin embargo, con las ventajas otorgadas por auto-boxing, ahora simplemente hacemos esto:

Integer y = new Integer(567); // Creamos el objeto
y+=1550; // Implicitamente se obtiene el valor, realiza la operación, y se guarda de nuevo en el objeto
System.out.println("y = " + y); // Imprimir por pantalla

Ambos ejemplos,si mi cabeza no me falla dan como resultado:
y = 2117

Apesar de que vemos que al objeto tipo Integer se le esta aplicando una suma directamente, en realidad el compilador hace los mismos pasos que en el ejemplo de arriba. simplemente es una cuestión de conveniencia para facilidad del desarrollador.

Una particularidad que tienen los objetos Wrapper (Long, INteger, Float, etc...) es que por cuestiones de ahorro en memoria, dos instancias de los siguientes objetos serán iguales. (Es decir pasaran el test '==') cuando sus valores sean iguales, para los siguientes casos:

- Boolean (todos)
- Byte (todos)
- Character(desde 'u0000' hasta 'u007f') (7f es 127 en el sistema decimal)
- Short & Integer (desde -128 hasta 127)

Es decir, si tenemos:

Integer n1 = 100;
Integer n2 = 100;
System.out.println(n1.equals(n2));
System.out.println(n1==n2);

El resultado será:

true
true

Pero, si cambiamos los valores a:

Integer n1 = 150;
Integer n2 = 150;
System.out.println(n1.equals(n2));
System.out.println(n1==n2);

El resultado será:

true
false

Volviendo al tema de Auto-Boxing, una de las mayores utilidades de este es al utilizarlo en Colecciones, por ejemplo:

Antes (Java 1.4):


int valor=852
//Mucho código, que procesa la variable valor, va aqui
ArrayList numeros = new ArrayList();
numeros.add(new Integer(valor));


Ahora (Java 5 y posterior)

int valor=852
//Mucho código, que procesa la variable valor, va aqui
ArrayList<Integer> numeros = new ArrayList<Integer>();
numeros.add(valor);

Aparentemente no es mucho el ahorro, pero si manejas constantemente operaciones entre objetos y primitivos, seguro se notará la diferencia. Por último, si te ha extrañado la diferencia de sintaxis para el ArrayList entre las 2 versiones de Java, no os preocupéis, es un cambio implementado también en Java 5, se llama Generics y será el tema de mi proximo post.

14 de diciembre de 2007

RECOMENDACIONES PARA EL SUN JAVA SYSTEM APPLICATION SERVER 8.2

El servidor Sun Java System Application Server 8.2, viene incluido en el paquete de instalación de Java Studio Creator. Para efectos de desarrollo

EN LA PROGRAMACIÓN:

Concatenación:

Cuando a un mismo String le estamos concatenando constantemente nuevas cadenas, lo mejor es declarar StringBuffe en vez de String un Usar el método append(String str) de la clase StringBuffer en vez de concatenar directamente. Por ejemplo:

En vez de:

String str = "testing";

str = str + "abc";

str = str + "def";


Utilizar


StringBuffer tmp = new StringBuffer("testing");

tmp.append("abc");

tmp.append("def");

String str = tmp.toString();


Lo que ocurre en el primer ejemplo es que al final de él, tenemos 4 objetos creados; uno que contiene la cadena "testingabcdef", refrenciado por la variable str, otro que contiene la cadena "testing" sin variable de referencia, otro que contiene la cadena "abc" sin variable de referencia y un último que contiene "def", tambiéen sin variable de referencia. Aunque los tres últimos objetos son candidatos a ser removidos por el Garbage Collector, nada nos lo garantiza. Por lo tanto es basura que se acumula en la memoria y esto reduce drásticamente el rendimiento de la aplicación (no del servidor). Mientras tanto, en el segundo ejemplo, primero se crea el objeto que contiene "testing" al cual luego se le añaden 2 cadenas. La forma en que trabaja StringBuffer le permite añadir nuevas cadenas al objeto sin crear objetos adicionales. Por lo tanto al final solo quedan 2 referencias al mismo objeto.

Recolección de basura: en java existe algo llamado Garbage Collector localizado en la máquina virtual, el cual se encarga de liberar de memoria los objetos que dicha máquina considera no serán necesarios. Esta tarea se le puede facilitar al GC, si le asignamos null a las variables que no volvamos a utilizar. Esto, será como un flag que le indique al GC directamente, que puede liberar la posición de memoria que almacena dicho objeto. Sin embargo aunque nosotros marquemos las variables dcon "null", esto no garantiza en ningún moment que el vaciado de memeoria se realñizará inmediatamente. Si realizamos dicha petición manualmente (invocando System.gc();) simplemente le estamos haciendo una sugerencia a la máquina virtual, mas no es una orden que esta cumplirá inmediatamente, asi que no hay que confiarse.

Declaración de constantes: en caso de tener en nuestro código una variable “estática”, como por ejemplo PI, se puede declarar de esta manera:

public static final int PI=3.1416;

Esto por un lado nos ayuda a controlar el valor de la variable, pues de este modo no será posible modificarla más adelante, ni en la propia clase y mucho menos en clases de otros paquetes o subclases.

EN EL SERVIDOR

Logs: el escribir constantemente e innecesariamente en un log, obliga a tener acceso discos duros, lo cual reduce el rendimiento del servidor.

Niveles de logs: el servidor puede definir los niveles o frecuencia con la que hace log a sus diferentes módulos, por ejemplo, CORBA, JAAS, JMS, etc. Los niveles son:

  • FINEST: Máximo nivel de detalles

  • FINER: Nivel de detalle medio

  • FINE: Nivel de detalle mínimo

  • CONFIG: Mensajes relacionados con la configuración del servidor

  • INFO: Mensajes relacionados con la configuración o el estado del servidor, sin incluir los errores

  • AVISO: Advertencias, incluidas las excepciones

  • SEVERE: Eventos que interfieren en la ejecución normal del programa

Para obtener mayor cantidad de mensajes se recomienda FINE, FINER, o FINEST. Para condiciones normales el nivel de WARNING, y bajo condiciones de “benchmarking”, se recomienda SEVERE. Entre mayor sea el nivel de detalle, menor serà el rendimeinto del servidor, aunque un menor nivel de detalle en ambientes de desarrollo puede ser perjudicial, ya que en caso de presentarse errores, muy probablemente estos no se almacenarán en el log.

Los niveles se pueden ajustar en:

  1. Ir a la consola de administración del servidor de aplicaciones.

  2. Click en “Application Server”.

Figura 1

Menu Principal del SJSAS 8.2

  1. Click en la ficha “Registro”

  2. Clck en la sub-ficha “Niveles de Registro”

  3. Seleccione el nivel que desea para cada módulo.

Recargue automático: el servidor tiene por default activada una configuración que le permite “reescanear” las clases de una aplicación que ha sido desplegada, buscando y reflejando cambios que se hayan hecho en dichas clases. Se recomienda desactivar esto (sobre todo en producción), porque consume tiempo y recurso de forma innecesaria.

La forma de desactivarlo es:

  1. Repita los pasos 1 y 2 del apartado anterior.

  2. Luego en la ficha “Avanzada”, que aparece en el frame del lado derecho.

  3. Desactive las opciones referentes a “recargar” e “implementación automática”

  4. Reinicie el servidor.

Precompilar JSP’s: compilar los JSP’s es sinónimo de desgaste en tiempo y recursos durante el despliegue, por lo tanto, si estos están precompilados el rendimiento del servidor mejorará. Para indicar que se desea precompilar los JSP’s:

  1. Repita los pasos 1 y2 del apartado anterior:

  2. Active la opción “precompilar”

  3. Reinicie el servidor.

Tiempo de sesión: estipula el tiempo que tardará el servidor en desconectar una sesión por inactividad. Este tiempo por default es de 30 mins. Este tiempo se ajustará de acuerdo a las necesidades y entorno de la aplicación. Un tiempo muy largo tendrá como consecuencias el almacenamiento innecesario de muchas sesiones, y muy poco tiempo, causará molestias en el usuario final, al ser desconectado frecuentemente. Este valor puede ser ajustado en la consola del servidor en:

  1. Application Server >Configuracion > Contenedor Web

  2. Click en la ficha “Propiedades de sesión”

  3. Indique el nuevo tiempo (en segundos).

  4. Click en “Guardar”

  5. Reinicie el servidor.





12 de diciembre de 2007

Aplicaciones Web en Netbeans con DB2

Desde el primer RC (release Candidate), incluso desde las versiones Beta, ya le venia "siguiendo el rastro" a la salida de NetBeans 6.0. Sus ejemplo, funciones y características que sin duda lo convertirán, a corto plazo, en un poderoso y múltiple entorno. Aunque orientado a Java principalmente, no es lo único que ofrece, ya que cuenta con diferentes módulos y plugins para trabajar con otros lenguajes (Ruby, PHP, C/C++, etc). Volviendo al tema razón de ser de este artículo, desde las primeras versiones de Netbeans 6 intenté hacer una aplicación web sencilla que a través de un componente visual (JSF), una tabla en este caso, pudiera visualizar elementos de una tabla en DB2. Sin embargo nunca (hasta ahora) habia podido hacerlo correctamente. Al desplegar la aplicación obtenía resultados extraños. En las primeras versiones, al parecer los drivers JDBC de DB2 no estaban soportados por la herramienta cosa que por suerte ha cambiado. Sin embargo , un error aún salía en los logs del servidor, al parecer la libreria db2jcct2.dll es necesaria para compltar satisfactoriamente la conexión y no se incluye en los jars JDBC de DB2. La razón para utilizar DB2 es que es una base de datos robusta, que dia a dia ofrece grandes beneficios en aspectos como seguridad, rapidez y alta disponibilidad, y aún más; posee una versión gratis, denominada DB2 Express, la cual actualmente marcha por la versión 9.5, que como lo indica en su página. No tiene límites (porcesadores, memoria..etc), solo los datos (tu espacio en disco duro). A continuación explicaré, como conectar satisfactoriamente DB2 con Netbeans 6:

Primero creamos la conexión con DB2 desde Netbeans 6.0. Netbeans a diferencia de Java Studio Creator se ha desatado de la función embebida de traer los drivers y realizar todas las tareas requeridas para conectarse correctamente. Es un poco más complicado pero permite tener mayor control sobre la aplicación ya que podemos escoger a nuestro gusto o necesidad los componentes del driver.

1. Asegurarse de que la base de datos esté arriba.
2. Creamos un nuevo proyecto Web en Netbeans utilizando el framework "Visual Web Java Server Faces". (yo lo denominé: WebTest1).
3. Dentro de Netbeans en la pestaña que dice Services: DataBases - > Drivers, Haga click derecho en la palabra Driver - > New Driver...
4. A continuación se abre un cuadro de diálogo:


5. Le damos click en "add" (Agregar) y escogemos los 2 archivos drivers jdbc.

DB2 utiliza los archivos db2jcc.jar y db2jcc_license_cu.jar para conectar cualquier aplicacion JDBC. Cabe resaltar que desde la version 9 de DB2, también está disponible un tercer archivo llamado db2jcc4.jar el cual incluye las funcionalidades de JDBC 4.0 y su antecesor (JDBC 3.0). IBM recomienda no utilizar db2jcc y db2jcc4 juntos, es decir son disyuntivos. Los archivos se encuentran en el directorio SQLLIB\Java de la carpeta de IBM que se escogió para la instalación de DB2. En mi caso queda el driver queda conformado asi:

El nombre lo genera Netbeans, de acuerdo con la información que obtiene de los jar's, aunque se puede personalizar para identificarlo mejor. Lo importante es que en el campo "Driver Class" este la clase com.ibm.db2.jcc.DB2Driver, sino está le damos "Find" y Netbeans buscará dentro de el (los) jar(s) que le hayamos dado nosotros y nos mostrará en "Driver Class" una lista de las posibles clases que podemos utilizar dependiendo del driver.

Luego de dar OK, y ya tenemos configurado el driver de DB2 con netbenas. Sin embargo no tenemos aún una conexión real con la base de datos. Digamos que ya armamos el barco, falta remar hasta la otra orilla. En la lista de drivers ya aparece el nuevo, ahora nos conectamos a la base de datos.

6. Damos click derecho sobre el y seleccionamos "Connect Using", se abre un nuevo cuadro de diálogo en que nos pide la forma de conectarnos a la base de datos host o direccion IP, puerto y nombre de la base de datos, además del usuario y contraseña que tengamos. Luego de digitar estos datos, nos vamos a la ficha "Advanced" y damos click en Get Schemas y seleccionamos el esquema en que se encuentran las tablas. En mi caso el esquema se llama " y "SCH".


Ahora si damos click en "OK", y observamos que en el nodo Databases aparece nuestra nueva conexion:
7. Abrimos la pagina .jsp del proyecto llamada Page1.jsp, y nos ponemos en vista de diseño. Estando ahi seleccionamos de la paleta de JSF una tabla y la arrastramos hasta la pagina page1.jsp.


8. Abrimos el nodo de nuestra conexion y estamos en un ambiente parecido al de nuestra base de datos, donde observamos las tablas, vistas y procedimientos (si disponemos de ellos en nuestra base de datos)

9. Selecionamos la tabla (en mi caso TABLE1) y la arrastramos de igual forma hasta la pagina. Netbeans automaticamente craerá un rowset en el SessionBean1 (si no existe) y un Cachedrowsetdataprovider generado asi nombre_de_tabladataprovider.

10. Aún en la vista de sieño, nos vamos a la tabla JSF y hacemos click dercho->bind to data, seleccionamos el dataprovider de la tabla, que acabamos de agregar a la pagina y de igual forma las columnas de la tabla en DB2, que queremos visualizar:



En mi caso, mi tabla solo tiene 2 campos un entero de nombre CODIGO y un varchar de nombre TEXTO. Depues de dar click en OK, nos queda la tabla parecida a esta:


Normalmente seria solo darle "Run" y esperar que salga la tabla, pero me he dado cuenta que no es asi. Si le damos ejecutar inmediatamente en Mozilla sale la página en blanco, ientras que en explorer sale algo de código html referente a la tabla JSF. Al revisar los logs de Glassfish osbervé constantemente este mensaje:

com.ibm.db2.jcc.b.SqlException: [jcc][10389][12245][3.50.152] Failure in loading native library db2jcct2, java.lang.UnsatisfiedLinkError: no db2jcct2 in java.library.path: ERRORCODE=-4472, SQLSTATE=null

y a continuación de el un stack trace espantoso. Resulta que los señores de IBM requieren otro archivo para conectarse (oootro?? si, otro...). existe una libreria nativa de DB2 llamada db2jcct2.dll que es necesaria de incluir. Vamos a la carpeta de IBM donde instalamos DB2 (ojo, no donde reside la base de datos). En mi caso dicho archivo se encontraba en: C:Archivos de programa\IBM\SQLLIB\BIN, simplemente lo copiamos a la carpeta "lib" del servidor ubicada en C:Archivos de programa\glassfish-v2\lib.
Nota: Si tu servidor estaba iniciado es necesario que lo reinicies despues de copiar el archivo.

bon despliegue!!! :D