Mostrando entradas con la etiqueta Java. Mostrar todas las entradas
Mostrando entradas con la etiqueta Java. Mostrar todas las entradas

domingo, julio 08, 2007

Creación de un EJB(I): Session Bean

Bueno, después de este pequeño traspiés con la nueva versión de J2EE, voy a ir contándoos lo que voy haciendo para crear un bean de sesión desde donde lo dejé. Recordemos que en el primer post hablamos sobre la tecnología J2EE y en el segundo post habíamos instalao nuestro servidor de aplicaciones de Sun. Por lo que me comentó Manolo, existe también otro servidor de aplicaciones llamado JBOSS que parece ser que es más eficiente, pero como yo ya había trabajao con una versión previa de éste, os voy a contar cómo se hace ésto. También he visto por ahí que hay un proyecto open source llamado GlashFish que creo que también es un servidor de aplicaciones y tiene buena pinta pero eso es arena de otro costal que ya urgaremos cuando proceda. Yo voy a lo mío.

Después de instalar el servidor de aplicaciones, en la nueva versión, necesitamos para desplegar nuestras aplicaciones un pack para Netbeans o un plugin para eclipse que se ofrecen junto con el servidor de aplicaciones en la página de Sun. Ésas eran las herramientas que se descargaban si en vez de pulsar en Download with JDK pulsábamos en Download with Tools. Como por entonces no tenía ni idea de que ya no existía la herramienta de despliegue deploytool, pues yo ya tengo mi servidor de aplicaciones instalao en mi máquina. No todo está perdido. Yo he escogido hacerlo con NetBeans como reto personal porque ya conocía Eclipse y tenía ganas de ver qué tal era NetBeans, pero vosotros podéis hacerlo con lo que elijáis.

Bien, para empezar nos vamos a la página de descarga de Sun y pinchamos en un link que hay a la derecha en un div azul titulado Related Resources y que se llama NetBeans. Ahí podemos descargarnos tanto el propio IDE NetBeans como el Enterprise Pack. Descargad agusto. Luego la instalación es bastante simple. Hacemos un chmod +x fichero_binario y luego un ./fichero_binario. Con ésto se nos abre un instalador gráfico bastante intuitivo al que la máxima información que tendremos que aportarle será el sitio donde queremos que lo instale cuando se trate del IDE o del sitio donde hemos instalao el IDE cuando se trate del Enterprise Pack. Habrá un momento de la instalación que nos preguntará si queremos instalar un servidor de aplicaciones o si queremos usar una instalación preexistente. Obviamente aquí usaremos el servidor que habíamos instalao en el post anterior y para ello tendremos que darle el nombre de usuario y la contraseña de administrador que nos creamos en su momento.

Aparte de ésto, lo demás no os creará problemas. Y bien, ahora tenemos nuestro servidor de aplicaciones perfectamente sincronizao con nuestro IDE NetBeans que hemos instalao para el desarrollo de nuestros beans y sólo nos queda desarrollar las aplicaciones.


Creación de un Bean de Sesión - El meollo.

Vamos a crearnos un Bean de Sesión que a partir de un día, mes y año de nacimiento calcule la edad que debe tener la persona. Además posteriormente y para ver la funcionalidad de ésto, nos vamos a crear una página JSP que haga uso de este Bean para recoger la información introducida por un usuario, mandársela al bean, recoger el resultado y mostrarlo por pantalla. Al lío pues.

Arrancamos NetBeans si no lo hemos hecho ya y pinchamos en Archivo -> Nuevo Proyecto -> Nueva Aplicación Empresarial. Rellenamos los campos necesarios. En nuestro caso le vamos a poner de nombre CalculadorEdad. Ponemos la carpeta donde queremos que se guarde y seleccionamos la versión de J2EE que queremos usar. En este primer post vamos a usar J2EE 1.4 que es la versión que yo había trabajado, pero a ver si más adelante os puedo escribir cómo hacerlo con J2EE 5 para que veáis la diferencia. Aseguráos antes de darle a "Terminar" de que marcáis las casillas de "Crear módulo EJB" y "Crear módulo de aplicación Web" y dejad sin marcar la de "Crear módulo de aplicación Web" de abajo que se refiere a un cliente de aplicación web que nosotros no necesitaremos, sólo los dos primeros. Debería quedar parecido a lo que sigue:

Pinchad en "Terminar".

Ahora creamos el nuevo Session Bean. Para ello le damos al botón derecho en CalculadorEdad-ejb -> Nuevo -> Bean de sesión.
Introducimos el nombre que será CalculadorEdad, ponemos el nombre de un paquete, que será por ejemplo "calculadoredad". Marcamos "sin estado" puesto que vamos a hacer un Stateless Session Bean, ponemos el tick en las dos interfaces, remota y local y pinchamos en Terminar. En realidad podríamos valernos sólo con la Remota, ya que la local es para optimizar accesos desde local pero vamos a ponerlo todo y así vemos todas las interfaces en pleno rendimiento. El resultado será que nos creará automáticamente las clases que necesitamos e implementará él sólo el código aburrido de los métodos de ciclo de vida y demás asuntos escabrosos. A nosotros nos tocará entonces implementar los métodos de negocio que son los específicos de nuestro bean. La intención es crear una aplicación que introduciendo una fecha de nacimiento calcule los años que tiene la persona dada. Así pues, nuestro método de negocio lo llamaremos edad y recibirá como parámetros 3 int representando el día, mes y año de nacimiento. Además le diremos que lanza una excepción que llamaremos PeroQueInventoEsEsteException y que extiende de Exception para indicar cuando alguien ha introducido una fecha no válida (ya se que aún no la hemos creado, lo haremos a continuación).

Si le damos al botón derecho en la clase CalculadorEdadBean , y seleccionamos métodos EJB -> Agregar método Business podremos añadir nuestro método de negocio que os describía arriba y el código se implementa sólo. Jurch, estos IDEs...dentro de poco no habrá que saber programar para programar :).

Justo después de haber puesto todo lo que arriba decíamos vamos a crearnos nuestra excepción especial. Para eso nos vamos dentro de CalculadorEdad-ejb al apartado de "Paquetes de orígen". Le damos al botón derecho encima y decimos Nuevo -> Clase java. Como nombre le damos PeroQueInventoEsEsteException y le decimos que la cree. A continuación la abrimos haciendo doble click en ella y añadimos a su declaración de clase el código "extends Exception" para que tenga las propiedades de una excepción normal y corriente. Luego en el constructor por defecto metemos como código "super();" y nos creamos un constructor con un String como parámetro que tenga por código "super(motivo);" siendo motivo el nombre del String del parámetro. Ya tenemos nuestra excepción.

Ahora vamos a implementar el código de nuestro método de negocio. Para ello nos vamos a la clase CalculadorEdadBean que es quien tiene que implementar el código de nuestro bean y picamos código. Mi implementación to perrillera del método que calcula la edad es la que os pongo aquí.

public int edad(int dia, int mes, int anho) throws PeroQueInventoEsEsteException{
//Obtenemos un objeto java.util.Date con la fecha actual y un objeto java.sql.Date con la fecha que ha introducido el usuario
java.sql.Date fecha = java.sql.Date.valueOf(new Integer(anho).toString()+"-"+new Integer(mes).toString()+"-"+new Integer(dia).toString());
hoy = new Date();
//Para compararlos obtengo el número de milisegundos desde "The Epoch"
long nacimiento = fecha.getTime();
long actual = hoy.getTime();

//Si se ha introducido una fecha futura...
if(nacimiento>actual){
throw new PeroQueInventoEsEsteException("¿Tu tas creído que somos unos pardillos o qué? ¿usease que aún no has nacío no?");
}

//Calculamos el tiempo en milisegundos que la persona lleva viviendo y hayamos su edad averiguando cuántos años son esos milisegundos. Hay un error obvio debido a los años bisiestos pero no lo contemplaremos aquí.
long tiempoDeVida = actual-nacimiento;
int edad = (int)(((tiempoDeVida/1000)/3600)/24)/365;

return edad;
}


Hago uso de java.util.Date (que está importada en el inicio de la clase con un simple "import java.util.Date") y de java.sql.Date por la facilidad de uno para crear objetos Date a partir de Strings y la facilidad del otro para crear objetos Date representando la fecha actual. Como ambos tienen un método getTime() que devuelve el número de milisegundos desde "The Epoch" que es como se conoce a las 00:00h del 1 de enero de 1970, mediante una simple resta puedo tener los milisegundos de vida de la persona que ha introducido su fecha de nacimiento. Paso los milisegundos a años y voilà, ya tenemos su edad. Está claro que no estoy contemplando los bisiestos y ésto sería un problema, pero como la propia implementación es bastante perrillera no me voy a centrar en que el código sea bonito o que cumpla bien con su cometido, sino en que veáis una implementación de un EJB. Además la aproximación es bastante cercana, y sólo fallará en días próximos a nuestro cumpleaños así que lo podemos considerar aceptable para un ejemplo :). De toas formas sí, ya se que es un código un tanto perrillero, pero weno, qué le vamos a hacer.

Lo único que nos queda por hacer con el Bean es darle un nombre de referencia en el servidor para que pueda ser encontrado por nuestra página web (que crearemos a continuación) cuando vaya a buscarlo. Ésto es fácil. Nos vamos al menú de la izquierda, donde está nuestro CalculadorEdad-ejb. Desplegamos el submenú "Archivos de configuración" y hacemos doble click encima de "sun-ejb-jar.xml". Ese fichero es en realidad un xml, pero nuestro querido IDE NetBeans nos lo mostrará como cajitas y menús tó wapos (si es que vivimos en una puta metáfora con las interfaces gráficas ;) ). Veréis que debajo de "Configuración Sun" tenéis un submenú llamado CalculadorEdadBean, pues pinchad en él, y veréis algo como ésto:


Rellenadlo como véis en la imágen, poniendo "ejb/CalculadorEdadBean" en el campo de "Nombre JNDI". Ya tenemos nuestro bean programado y reconocido por el servidor para que pueda ser llamado por otras aplicaciones, servlets, beans o JSPs.

Ahora nos vamos a crear una página JSP. En realidad esta página ya está creada. Se creó automáticamente cuando marcamos la casilla de "Crear módulo de aplicación Web" cuando creamos el proyecto. Para verla, id en el menú de la izquierda a "CalculadorEdad-war" y desplegad su submenú. De ahí nos vamos a páginas web y veréis que hay una que se llama "index.jsp". Ésta es la que nuestro servidor de aplicaciones mostrará cuando ejecutemos la aplicación y entremos en localhost:8080/CalculadorEdad-war. Pinchad dos veces sobre ella y se os abrirá a la derecha. Ahora la vamos a editar. Os voy a enseñar el código en dos trozos pa ir explicándooslo poco a poco. Primer cacho:


De lo que veis, llamaros la atención sobre unas pocas cosas:
  • No os olvidéis de importar las clases necesarias para el funcionamiento de vuestra página JSP, además de las clases de las interfaces del Bean que váis a usar.
  • Cread un contexto inicial como se ve en el código.
  • Fijáos en la forma de obtener una referencia a nuestro Bean. Primero se obtiene una referencia al interfaz de inicio o interfaz Home de nuestro Bean sobre la que llamaremos a su método create(). Lo hacemos con el método lookup(String) sobre nuestro contexto inicial y le preguntaremos por "java:comp/env/" + el nombre que le dimos a la referencia del EJB. ¿Os acordáis? Lo que sí recordaréis seguro es que en los Session Beans el bean nace y muere con el cliente, así que aquí no tendría mucho sentido obtener la referencia de otra forma. La creamos cada vez y punto.

Ahora pasamos al segundo cacho:


Aquí está la chicha de nuestra página. Quitando el código que es meramente HTML, lo más importante quizás sea lo que está a partir de la línea 47. Tened en cuenta que cuando llamemos a nuestra página JSP lo podremos hacer pasándole parámetros en la propia URL del tipo dia=4&mes=5&anho=1984. Ésta es la forma de funcionar de una petición "GET". Para recuperar esos parámetros en nuestro JSP tendremos siempre el objeto request siempre inicializado y que indica la petición, y si llamamos a su método getParameter("parametro"), éste nos podrá devolver o el valor del parámetro, o bien null, y debemos contemplar esa posibilidad. También contemplamos la posibilidad de que el usuario pinche sobre el botón sin haber introducido nada (se hace en las comprobaciones noseque.length()>0) por lo que se estará enviando una cadena vacía. Una vez capturados los parámetros con los que se ha llamado a nuestra página JSP mediante nuestro formulario que generaba peticiones "GET" sobre la propia página, los transformamos en el tipo de dato que necesitábamos, para ello apoyándonos en la clase java.lang.Integer y llamamos al método de negocio edad(int,int,int) que nos habíamos creado usando la referencia que obtuvimos en el primer cacho de código. Al realizar la llamada tenemos que encapsularla por un try-catch que recoja las excepciones que se puedan producir, que en nuestro caso será la excepción especial cachonda que nos habíamos creao. Y finalmente, si la excepción no se ha producido sólo tenemos que mostrar el mensaje con el resultado de la llamada a nuestro bean. ¿A que no es complicao?

Por último, vamos a crear una referencia al EJB en nuestro módulo de aplicación web. Cosa sencillica. Nos vamos al menú de la izquierda de NetBeans. Desplegamos el menú de "CalculadorEdad-war" y dentro de él el submenú de "Archivos de configuración". Hacemos doble click sobre web.xml. Aquí pasa como antes, que pese a que es un fichero xml, nuestro IDE nos lo muestra de forma bonica (si queréis ver su forma real podéis pinchar en el botón "XML" que os lo enseñará perfectamente). Ya trastearéis un poquillo por este fichero para descubrir que se pueden configurar muchísimas cosas, como por ejemplo el tiempo que dura una sesión o temas de seguridad y demás, pero lo que a nosotros nos importa lo conseguimos pinchando en el botón de "Referencias". Ahí desplegaremos "Referencias EJB" y pincharemos sobre "Agregar". Ahí se os mostrará algo como:


Rellenadlo como ahí pongo. Aquí fijáos que en el nombre de la referencia tiene que haber una coherencia con el nombre que configuramos antes en el servidor al EJB. Luego, dado que hemos metido las distintas clases de nuestro EJB en un paquete llamado calculadoredad, fijáos en que al indicar las interfaces de inicio y remota hemos puesto delante calculadoredad.*, es importante. Una vez que hayáis hecho ésto, pinchamos en guardar y tocad la madera más cercana porque se supone que ya lo tenemos todo listo para desplegar nuestra aplicación. Lo que sigue es fácil. Le damos al botón derecho encima de "CalculadorEdad", que es la raíz de nuestro menú de la izquierda y seleccionamos "Ejecutar Proyecto". Nos saldrán un chorro de letras por abajo, os pedirá el nombre de usuario y contraseña de administrador y parecerá que nuestra máquina esté intentando calcular todos los números de pi, pero cuando lleve un rato leeréis algo así como "GENERACIÓN CORRECTA" y sabréis que todo este tiempo habrá merecido la pena :). Que no os lleve a engaños, este mensaje aparece también cuando la mayoría de las cosas fallan. Depende del tipo de fallo que se produzca. Si las referencias las habéis puesto mal o el código no rula como debería de rular, el mensaje os aparecerá, pero cuando intentéis entrar en vuestra página lo que salga o cómo funcione la aplicación...eso ya será otro rollo.

Para comprobar que la cosa rula abrimos un navegador y metemos la dirección
http://localhost:8080/CalculadorEdad-war/
Si todo ha ido medianamente bien debería de mostrársenos algo como ésto...


Ahora introducimos un día de nacimiento, mes y año correctos, por ejemplo Día: 4, Mes: 5, Año: 1984, y pinchamos en "Submit". Nos debería salir algo como...

Es correcto. Pero, ¿qué pasa si introducimos una fecha en el futuro? ¿cómo manejará nuestra página aquella PeroQueInventoEsEsteException que nos inventamos? ¡Probémoslo! El resultado debería parecerse a éste...


Wapo ¿verdad?. En realidad, seguramente no queráis hacer una aplicación de un servidor de aplicaciones que maneje una página que te calcula tu edad con un cierto márgen de error de días según bisiestos...es mu probable que no, pero hacer un calculador de edad es lo mismo que hacer cualquier otra cosa, sólo cambiad el código y número de los métodos de negocio y fenómeno. Se que es un poco tedioso, pero también hay que tener en cuenta que en este ejemplo nosotros hemos hecho todo el trabajo. En un servidor de aplicaciones real seguramente no tuviéramos que hacerlo. Ahí es donde entra el reparto de roles que contempla este tipo de programación. El desarrollador no tiene por qué ser el mismo que el desplegador, que a su vez no hace falta ni que conozca a quien montó el servidor de aplicaciones. Por eso os enseñé en el anterior post cómo arrancar y parar el servidor desde línea de comandos, pues puede que os toque símplemente hacer ésto y no desarrollar nada encima. Una vez montado el sistema, ya es sólo cuestión de hacer correr distintas aplicaciones sobre él y si somos listos al cliente le cambiaremos muy poco la interfaz para no hacerle la picha un lío, como al fin y al cabo lo que va por debajo no le importa, sólo tenemos que añadir métodos de negocio y añadir nuevas funcionalidades en nuestra interfaz que nunca cambia :). Todo ventajas. Inconveniente: ésto es java, así que ya se sabe, el procesador echando humo y la memoria derrochándose. Pero weno, dejemos eso para otro momento.

El desarrollo de un EJB de sesión con estado es bastante similar al del sin estado que hemos desarrollado así que el siguiente post lo dedicaré a crear un EJB de entidad (con una bonita base de datos derby). Espero no haberos aburrido mucho y que ésto os pueda servir para introduciros en cómo hacer lo que ya sabéis que queréis hacer.

lunes, julio 02, 2007

Instalación del Servidor de Aplicaciones

Actualización 04/07/07: Tras escribir este post, me he dao cuenta que la última versión del servidor de aplicaciones de Sun y de los EJB presentan algunas diferencias clave con respecto a la versión que yo había manejado y de la que os iba a hablar. Para empezar, hasta la versión anterior a la que os he indicao como instalar, se proporcionaba con ella una herramienta de despliegue llamada "deploytool" que en la nueva versión ha sido sustituída por un pack para NetBeans 5.5 u opcionalmente un pluguin para Eclipse, trastearé con ellos antes de escribir cómo hacerlo. También, la programación de los EJB 3.0 presenta algunas diferencias con respecto a su versión anterior en cuanto al número de interfaces a implementar por el/la programador/a y alguna notación específica a utilizar. Dejadme un tiempecillo que lo trastee todo y ya os escribo más adelante.


Y vamos al lío. Ya vimos en el anterior post la teoría mínima sobre J2EE y EJB's que nos iba a hacer falta para saber qué tenemos entre manos, pero sólo con la teoría, y más aún en este caso, no se puede saber de qué se está hablando concretamente, hace falta algo de código, así que en este post la intención era que desarrolláramos y desplegaremos un bean de sesión...peeeeeero, cuando me he puesto a escribir este post me he dao cuenta que ya se hacía demasiao largo sólo con la instalación y configuración del servidor de aplicaciones así que he decidío pasar al siguiente post el desarrollo de nuestro primer bean.

Lo primero de todo será pues arrancar nuestro servidor de aplicaciones. Pero...¿qué servidor es ese?
Bien, vamos a descargárnoslo de la página de Sun. Yo voy a hacer todo el proceso bajo GNU/Linux, concretamente sobre una Kubuntu 7.04, pero ésto es extrapolable de forma inmediata a cualquier otro sistema Linux y descargándose la versión correcta, también a cualquier sistema Windows. No os recomiendo usar Windows, pero allá vosotros/as :).

Entramos en http://java.sun.com y vamos hasta la página de descarga de la última versión de Java EE SDK disponible, junto con el JDK. Para ahorraros la tarea, aquí tenéis un link http://java.sun.com/javaee/downloads/index.jsp. Ahí pincháis en Download with JDK, luego en Accept License Agreement y finalmente sobre la versión de nuestro SO, lo que descargará un fichero autoinstalable donde elijamos. Este fichero contiene entre otras cosas el Java EE SDK y el servidor de aplicaciones de Sun, que son los dos elementos que nos hacen falta.

Una vez lo tenemos en nuestro sistema de ficheros, le damos permisos de ejecución con un simple chmod +x nombre_del_ejecutable. Para ejecutarlo hacemos ./nombre_del_ejecutable y se lanzará un instalador gráfico muy intuitivo. Ya sabéis, siguiente, siguiente, siguiente, meto el sitio donde quiero instalarlo, acepto lincencia, siguiente, siguiente... :). Haciendo eso llegaremos a una pantalla donde tenemos que meter el nombre de usuario del administrador y su contraseña. Importante que os acordéis de este nombre y contraseña. Como siempre, no lo apuntéis en ningún lao salvo que estéis pensando en comeros el papel donde se apunte en breves o que se trate de una región cifrada de vuestro sistema de ficheros. La cosa se vería tal que así:


Como veis, también tendréis que meter los puertos en los que escuchará nuestro servidor de aplicaciones. Si los puertos por defecto los tenéis ocupados por otra aplicación cambiadlos a vuestro gusto o símplemente por el hecho de añadir un poco más de seguridad al asunto colocándolos en puertos que no sean los habituales (sí, ya se que herramientas como nmap permiten escanear alegremente los puertos activos de una máquina, pero está bien poner las cosas un poco más complicás siempre). Yo como voy a instalarlo y desinstalarlo hoy mismo, voy a dejarlo por defecto. El siguiente paso, pulsar en Install now. Lo siguiente ya lo conocéis, una barra de progreso de 0% a 100%, algo como...


y que cuando acabe nos mostrará la página final que además contiene información útil...


La información que ahí aparece es especialmente útil porque indica cuál es la orden para arrancar el servidor, que vendrá a ser algo así como...
/sitio/donde/lo/hayais/instalao/bin/asadmin start-domain domain1 (por defecto se crea el dominio llamado domain1)
...pero antes deberíamos establecer una variable de entorno llamada JAVA_HOME que apuntara al sitio donde tengamos instalao un JDK (Java Development Kit). Si hemos escogío la opción de descarga que os dije tenéis uno en el subdirectorio jdk dentro de la nueva instalación. A continuación incluiremos la subcarpeta JAVA_HOME/bin dentro de la variable PATH de nuestro sistema. Dependiendo del tipo de intérprete que usemos ésto se hará escribiendo en un terminal:
export JAVA_HOME=/sitio/donde/lo/hayais/instalao/jdk
export PATH=${PATH}:${JAVA_HOME}/bin
...ó...
setenv JAVA_HOME /sitio/donde/lo/hayais/instalao/jdk
setenv PATH ${PATH}:${JAVA_HOME}/bin

Además también deberíamos de introducir en el PATH una variable que apunte a la localización de los scripts de nuestro servidor, que se habrán instalado en una subcarpeta /bin de nuestra instalación, algo así como...
export J2EE_HOME=/sitio/donde/lo/hayais/instalao
export PATH=${PATH}:${J2EE_HOME}/bin

...ó...
setenv JAVA_HOME /sitio/donde/lo/hayais/instalao
setenv PATH ${PATH}:${JAVA_HOME}/bin


Y finalmente dado que nuestro servidor de aplicaciones necesitará de una base de datos, vamos a establecer la variable CLASSPATH apuntando a un fichero *.jar que permite manejar la BBDD Derby que viene con la instalación de nuestro servidor. Lo tendréis en una subcarpeta llamada /javadb o similar. Ésta variable también tendrá que apuntar al fichero *.jar de J2EE así como al fichero *.jar que apunte a las utilidades de derby. Ésto lo hacemos con un...
export CLASSPATH=${J2EE_HOME}/lib/j2ee.jar:${J2EE_HOME}/javadb/lib/derbyclient.jar:${J2EE_HOME}/javadb/lib/derbytools.jar
...ó...
setenv CLASSPATH ${J2EE_HOME}/lib/j2ee.jar:${J2EE_HOME}/javadb/lib/derbyclient.jar:${J2EE_HOME}/javadb/lib/derbytools.jar

Personalmente os recomiendo que para no tengáis que hacer ésto siempre que queráis arrancarlo, os creéis un pequeño script que os lo haga automáticamente, de hecho, ya que ésto lo haréis cuando vayáis a arrancar el servidor de aplicaciones, lo mejor es que en el mismo script también arranquéis el servidor con la orden que ya vimos anteriormente. Éste script podría lucir algo así como...


Con ésto establecer las variables necesarias y arrancar o parar nuestro servidor sería tan fácil como llamar a nuestro script de la forma adecuada. Imaginemos que nuestro script lo hemos llamao servidor.sh.
Para arrancar nuestro servidor de aplicaciones haríamos...
source servidor.sh arrancar
...y para pararlo haríamos...
source servidor.sh parar
¿fácil no?

Si nuestra máquina fuese a funcionar de servidor de aplicaciones de forma permanente podríamos introducir este script en el runlevel adecuado del arranque de nuestro sistema GNU/Linux para que siempre que arranque la máquina se llame a este script y de forma automática se arranque el servidor. Si lo vamos a usar en un PC de escritorio para pruebas, podríamos crear un lanzador en nuestro entorno gráfico para que con un click se arrancase. Si lo vamos a arrancar y parar de forma periódica a determinadas horas se puede colocar una llamada al script en el cron de la máquina, etc, etc, etc...y así podéis buscar mil formas para facilitar la tarea y no tener que hacer ésto ná más que una vez.

El pantallazo de arranque podía ser éste que os muestro a continuación.


Para comprobar que hemos arrancado bien nuestro servidor, abrimos un navegador y entramos en http://localhost:8080. Deberíamos ver algo como ésto.


Por último, para entrar en la herramienta de administración, entraremos desde nuestro navegador en la dirección http://localhost:4848 y veremos algo como ésto.


Aquí es donde entra en juego el nombre de usuario y la contraseña que escribisteis en un papel para ahora coméroslo. Metéis nombre de usuario de administrador, que en mi caso era admin, contraseña, y os saldrá la página de administración del servidor de aplicaciones, que tendrá una pinta parecida a ésta.


Por supuesto, si hemos cambiado los puertos de administración o web al instalar el servidor, tendremos que coherentemente cambiar las URLs a las que accedemos para ello.

Por último, vamos a parar el servidor porque ya nos hemos hartao de tenerlo encendío y no lo vamos a usar más. El resultado de llamar a nuestro script con el parámetro "parar" será tan escueto como éste que sigue.

Y nada más. Espero que después de ésto tengáis en vuestra máquina un bonito servidor de aplicaciones J2EE activo y preparao pal desarrollo de vuestros beans. Ahora sólo nos falta configurarlo a nuestro gusto, pero eso es algo que haremos en el siguiente post para el desarrollo de nuestro primer bean.

A descansar chavalinos/as que ya os estamos dando mucho curro entre Manolo y yo (como si no supiera que el único que va a leer ésto vas a ser tú, Manolo ;) ).

domingo, julio 01, 2007

J2EE, programación de servidores de aplicaciones

¿Qué? ¿cómo andamos?

Se que dije que el siguiente post sería de XMLSchema pero voy a dejarlo pa más tarde y me dedicaré hoy a hablar un poquillo por encima de la tecnología J2EE (Java 2, Enterprise Edition). Haré una introducción teórica en este primer post de una serie de 4 post en los que trataré lo que os quiero presentar de la siguiente forma:
  1. Introducción teórica a vista de pájaro de Java 2, Enterprise Edition (J2EE) y sus Enterprise Java Beans (EJB).
  2. Creación de un EJB (I): Session Bean.
  3. Creación de un EJB (II): Entity Bean.
  4. Creación de un EJB (III): Message-Driven Bean.

J2EE

Si tuviéramos que, como en el colegio, hacer teoría de conjuntos y ver qué conjuntos es menor que cuál o está contenido en o chorrás desas, tendríamos que decir que:
J2ME < J2SE < J2EE
Y es que si bien J2ME no es exactamente un subconjunto de J2SE o J2EE puesto que puede tener elementos que no aparecen en éstos, sí que cuanto menos es una edición mucho más reducida del entorno de desarrollo.

Los objetivos básicos con los que surge J2EE son:
  • Abstraer las tareas críticas y repetitivas mediante servicios con una interfaz uniforme.
  • Preparar una infraestructura uniforme y de una arquitectura software basada en ella para aplicaciones empresariales.
La tecnología de J2EE utiliza la filosofía de la programación basada en componentes, más que la orientada a objetos. En este tipo de programación, un componente es algo más amplio que un mero objeto, y más asociado a la aplicación.

Además, una aplicación compleja basada en componentes a su vez se subdivide en niveles lógicos, de forma que cada nivel cubra un área de tareas y que pueden componer una o varias partes. Así obtenemos "Thin Clients", frente a los "Fat Clients" de la arquitectura Cliente/Servidor, ya que en los niveles intermedios se delega parte de la responsabilidad del servidor. Cada nivel se comunica sólo con los niveles contiguos mediante interfaces bien definidas.


EJB's

Pero pasemos de to este movidón teórico y metámonos en más teoría pero por lo menos un poco más próxima a la práctica. Veamos el concepto de beans. Los beans son nuestros colegas, nuestras "habichuelas", las entidades mínimas de nuestro diseño de aplicaciones...y de servidores de aplicaciones. En esencia son clases java con unas ciertas propiedades que permitirán darnos algunas prestaciones en función de nuestras necesidades, o más técnicamente son componentes que pueden ser usados para construcción de aplicaciones distribuídas y que encapsulan una parte de la lógica de negocio de una aplicación. Un EJB accede a otros gestores de recursos como bases de datos u otros EJB's y puede ser accedido por otros EJB's, aplicaciones, servlets y aplicaciones cliente. el EJB reside en un contenedor que le provee de servicios de seguridad, transacciones, gestión del ciclo de vida, gestión de concurrencia y despliegue.

Un EJB (salvo en el especial caso de los Message-Driven Beans) tiene varias partes:
  • La interfaz cliente. Permite el uso síncrono por parte de los clientes de los procesos de negocio que modela el EJB. Consta de dos clases de tipo interface. La Home Interface que debe extender la clase EJBHome y controla los métodos del ciclo de vida y la Remote Interface que debe extender la clase EJBObject y controla el acceso a los métodos de negocio remotamente.
  • La clase Enterprise Bean. Implementa el Bean en sí, su funcionamiento interno, las llamadas a las BBDD necesarias, los métodos de negocio, ciclo de vida, etc.
  • El descriptor de despliegue. Proporciona al contenedor toda la información que éste necesita sobre el EJB (nombre, nombre de sus interfaces, tipo de EJB, servicios que se esperan del contenedor, etc). Se trata de un fichero XML, y debido a su complejidad y su extensión se suelen utilizar herramientas de despliegue que lo creen a partir de la selección de opciones en un interfaz gráfico por parte del desplegador.

Lo que nuestros coleguitas beans pretenden ayudarnos a modelar son lo que llamamos "entidades de negocio" y "procesos de negocio", que viene a ser una forma empresarial de llamar a información de nuestra aplicación y métodos de acceso y modificación de esa información. Para que nos entendamos, las entidades de negocio son las bases de datos donde los procesos de negocio son los métodos/funciones/procedimientos que acceden a esas bases de datos y leen o modifican lo que en ellas hay.

Y para eso, ¿en qué nos ayudan los beans? Pues bien, tenemos beans para cada una de nuestras necesidades en una apliación...beans a la carta. En esencia tenemos:

Beans de Sesión (Session Beans):
Se encargan de la parte del lado servidor de la lógica de negocio de una aplicación.
Se crean instancias de un Session Bean cuando se produce una petición de un cliente y su tiempo de vida es el de el proceso abierto. Podemos tenerlos de dos tipos:
  • Beans de sesión sin estado (Stateless Session Beans)
    No guardan información del cliente. Todos los Stateless Session Beans instanciados tienen la misma identidad.

  • Beans de sesión con estado (Statefull Session Beans)
    Presentan diferentes estados en función del cliente, estado que se pierde cuando se deja de usar el Session Bean. Como consecuencia, cada objeto Session Bean tiene distinta identidad.
Algunas propiedades
  • Su estado se mantiene en memoria principal durante una transacción pero pasa a almacenamiento secundario tras desactivarse. Además su estado es inaccesible para otros programas, aunque pueda ser sincronizado para las transacciones.
  • Sólo puede usarse por un mismo cliente, no puede ser compartida su referencia.
  • Frente a fallos no se garantiza que una referencia a un objeto Session Bean siga valiendo.
Los Session Beans son especialmente adecuados para encargarse...
...de la lógica de sesión de una aplicación web...


...o también para encargarse de la lógica de sesión de una aplicación de tres capas.



Beans de Entidad (Entity Beans):
Este tipo de beans son los que nos modelan aquéllos conceptos u objetos de negocio cuyos datos deben ser persistentes, para lo que se suele usar una base de datos. Se pueden usar por varios clientes de forma conjunta y simultánea. Su identidad es tan simple como la clave primaria de la base de datos usada. Son tan persistentes que incluso llegan a sobrevivir a caídas de la máquina o de la máquina virtual de Java. En función de quién controle esta persistencia, se clasifican en dos tipos distintos:
  • Persistencia manejada por el bean (Bean Managed Persistence)
    El programador del bean debe programar los métodos que aseguran la persistencia, que vienen a ser los métodos que guardan los datos en la base de datos, así como crear la base de datos y mapear variables con columnas de la base de datos.

  • Persistencia manejada por el contenedor (Container Managed Persistence)
    El programador queda liberado de la tarea de programar la persistencia teniendo únicamente que indicar al contenedor qué variables van a asociadas a qué columnas de la base de datos para que éste controle la persistencia. Todo este mapeo se reflejará en el fichero xml descriptor del bean.
Algunas propiedades:
  • El estado de un Entity Bean es mantenido en una BBDD, con caché en memoria durante una transacción. Por consiguiente, cualquier programa externo puede acceder a él mediante queries SQL. Además su estado se cambia con transacciones y se puede recuperar en cualquier momento.
  • Un objeto Entity Bean puede ser compartido por múltiples clientes pasándose la referencia sin problemas.
  • Frente a fallos, caídas del contenedor o de la máquina, las referencias a los objetos siguen siendo válidas.

Beans controlados por mensajes (Message-driven Beans):
Este tipo de beans permiten a las aplicaciones J2EE procesar mensajes asíncronos, lo que los diferencia de los anteriores cuya llamada era síncrona. En última instancia no son más que escuchadores de mensajes JMS. Su estructura de hecho es similar a la de los escuchadores de eventos de java, sólo que éstos lo que escuchan son mensajes.
La principal diferencia a nivel de uso de éste tipo de bean con los anteriores es que el acceso a ellos no se realiza mediante interfaces, sino por:
  • Mensajes enviados por algún componente J2EE (una aplicación cliente, otro EJB o un componente web).
  • Mensajes enviados por una aplicación o sistema JMS que no use la tecnología J2EE.
También a diferencia de los demás beans, los MDB sólo se componen de una clase java, ya que no tienen interfaces.
describamos entonces algunas de las propiedades de este tipo de EJB's:
  • Una instancia a un MDB no almacena datos o estado conversacional de ningún cliente.
  • Todas las instancias de MDB tienen la misma identidad, por lo que la asignación de una instancia a un cliente es indiferente de qué instancia sea.
  • Un único MDB puede procesar mensajes procedentes de múltiples clientes.
Cuando un mensaje llega, el contenedor de nuestro EJB llama a su método onMessage(), que típicamente lo primero que debe tener programado es la clasificación de este mensaje según pertenezca a cada uno de los 5 tipos de mensajes JMS, para luego procesarlo según la lógica de negocio de nuestra aplicación.

Y bueno, yo creo que como introducción a J2EE y EJB's ya se ha hecho demasiao larga, pero weno, espero haberos ayudao en familiarizaros en esta tecnología. El siguiente post irá dedicao a programar y desplegar un Session Bean pa que le echéis un ojo a su código y veáis que hacerlo es más o menos sencillico aunque un poco coñazo. Además usaremos alguna herramienta de despliegue de EJBs que provee Sun. ya os contaré.

+info:
http://java.sun.com/javaee/5/docs/tutorial/doc/
http://java.sun.com/javaee/5/docs/firstcup/doc/toc.html
http://java.sun.com/javaee/index.jsp