sábado, 25 de febrero de 2012

5 opciones de hosting para aplicaciones Java

La tecnología avanza y hoy en día tenemos nuevas opciones para hospedar las aplicaciones de tal forma que estén las 24 horas de los 365 días del año (o 366) disponibles para ofrecer sus servicios. Veamos algunas de las que hemos tenido hasta el momento con algunas de sus características.

Servidor propio
Disponer de un servidor propio tiene varias ventajas como que tenemos total control sobre la máquina y en la que podremos instalar todo lo que necesitemos sin ninguna limitación, sin embargo, esta ventaja también puede ser una desventaja ya que tendremos que tener los conocimientos y tiempo para administrar la máquina. Otra desventaja es que deberemos solventar los fallos de hardware que se produzcan como una rotura de un disco duro, un sobrecalentamiento de la placa base, memoria, procesador o router lo que puede afectar a la disponibilidad de la aplicación. Además, tendremos que disponer de un sitio adecuado para alojar la máquina y de los costes que conlleva tenerla encendida en todo el momento que no hay que despreciar. También tenemos que tener en cuenta que si necesitamos escalar la aplicación tendremos más dificultades que otras opciones ya que tal vez tengamos que adquirir nuevo hardware y haya que adaptar la aplicación.

En definitiva esta opción nos obliga no solo a centrarnos en nuestra aplicación sino también en la infraestructura donde se despliega y en su administración. Sin embargo, hay que decir que una gran ventaja es que nuestros datos están bajo nuestro control y no en segundas o terceras partes.

A pesar de todas sus desventajas esta opción puede ser muy interesante para un uso personal. Como por ejemplo disponer de un servidor para descargas, compartir archivos u ofrecer servicios de red a los equipos de nuestra casa. Hay diferentes plataformas sobre las que podemos implementar nuestro propio servidor, algunas de las más conocidas en estos momentos son las placas Pandaboard, SheevaPlug, BeagleBoard, TimSlice o las inminentes Raspberry Pi (¡que cuestan 35$!). Todas ellas tienen en común que son un ordenador completo que no ocupan mucho más que un disco duro de 2.5" y están basadas en microprocesadores ARM con lo que tienen un consumo muy reducido que notaremos en la factura de la luz (consumen entre 2W y 9W, ¡un ordenador de sobremesa consume entre 150W y 300W! por lo que el coste de las placas se amortiza con el tiempo). Al ser ordenadores completos y de propósito general podremos darle otros usos como centro multimedia para reproducir películas, vídeos o fotos en la televisión ya que algunas placas tienen una salida HDMI.

Proveedores de hosting
Si no queremos administrar el hardware ni tampoco el software y nos queremos olvidar de los fallos del mismo podemos hacer uso de alguna de las opciones que ofrecen los proveedores de hosting. Sin embargo, con estas opciones no tendremos posibilidad de elegir la plataforma con la que construir nuestra aplicación ya que la mayoría solo ofrece bases de datos MySQL, la plataforma ASP o ASP.NET o PHP y tal vez no en la versión que queramos. Tradicionalmente los proveedores de hosting que ofrecían la plataforma Java han sido muy pocos con lo que los programadores de Java tendremos que buscar otras opciones. A no ser que dispongamos de un servidor dedicado nuestra aplicación competirá con las otras aplicaciones por los recursos del servidor lo que puede afectar a la capacidad de nuestra aplicación. En caso de que optemos por un servidor dedicado tendremos el problema de la escalabilidad si la aplicación lo demanda.

Algunos de los proveedores más conocidos son Arsys y Piensasolutions.

Actualmente la tendencia en diferentes ámbitos está en la computación en la nube y en esta tendencia el hospedaje de las aplicaciones se ofrecen como servicio. Hay diferentes opciones entre las que poder elegir y con diversas características que deberemos evaluar según las necesidades. Veamos algunas de las más conocidas.

Amazon EC2
Amazon EC2
Amazon EC2 ofrece su infraestructura como servicio (IaaS) en la que nuestra aplicación estará hospedada en sus servidores. En esta opción tendremos un gran control sobre el software que instalamos en el servidor ya que en gran medida lo que la diferencia de un servidor propio es que nos conectamos al servidor de forma remota para administrarlo, si el servidor propio lo administrásemos de forma remota ni eso.

Al igual que otras opciones de la nube tiene la ventaja de que en caso de que nuestra aplicación escale podemos adquirir mas recursos de cómputo, como capacidad de procesamiento, memoria o almacenamiento en disco. En realidad Amazon no dispone una máquina física para cada servidor de sus usuarios sino que da una representación lógica de un servidor, por esto motivo, si necesitemos disponer de una nueva máquina podremos disponer de ella en pocos minutos y la podremos aprovisionar rápidamente con imágenes de software (AMI) buscando una que se adecue a nuestras necesidades. Aunque necesitemos más tiempo de configuración que en las opciones de Google App Engine y Jelastic.

Se puede probar durante un año gratis en una instancia micro. Aquí pueden consultarse los precios de Amazon EC2 y aquí los tipos y características de las instancias. A la hora de pagar hay que preseleccionar un tipo de instancia por lo que necesitaremos evaluar nuestras necesidades por lo alto y probablemente estemos pagando por capacidad que luego no aprovechamos.

Amazon también proporciona una plataforma PaaS, AWS Elastic Beanstalk, sino queremos ser responsables de administrar a bajo nivel las máquinas. Beanstalk nos permite centrarnos en el desarrollo de la aplicación en vez de la administración de la infraestructura.

Google App Engine (GAE)
Google App Engine
La solución de Google para el «cloud computing» ofrece una plataforma como servicio (PaaS) para las aplicaciones con una serie de API que deberán usar para conseguir ciertas funcionalidades, como persistencia. Tiene como ventaja que no tenemos que preocuparnos de administrar un servidor y todas las herramientas para hacerlas funcionar entre si, solo nos preocuparmos por nuestra aplicación. Tiene como desventaja que deberemos adaptar nuestra aplicación a las API que nos ofrece GAE y por tanto estaremos encadenados a su plataforma. También estaremos limitados a utilizar Python o Java por el momento.

Dispone de cuotas parte de las cuales pueden usarse de forma gratuita y aquí los precios de los recursos consumidos.

Jelastic
Jelastic
Una opción más reciente para únicamente la platforma Java, por el momento, es Jelastic. Se trata de una PaaS sin la desventaja de tener que administrar un servidor como en Amazon y sin la desventaja de estar encadenados a ciertas API como en el caso de Google App Engine de tal modo que si queremos cambiar de proveedor no tendremos que reimplementar la aplicación. Nos ofrece herramientas estándares sobre las que de desarrollar la aplicación como son nginx como servidor web, apache tomcat 6/7, jetty o glashfish como contenedores de aplicaciones, Maria DB, MySQL o PostgreSQL como bases de datos relacionales y MongoDB o CouchDB como bases de datos no-sql y el JDK 6 o 7.

Esta opción permite centrarse en el desarrollo de la aplicación y posiblemente sea la opción más adecuada para un equipo de developers puro que no dispone de sysadmins. La aplicación se puede tener en funcionamiento en minutos (en vez de horas como en Amazon EC2) ya que todos los elementos de la infraestructura ya están configurados para funcionar entre si. Dado que no hay que aprender nuevas API como en el caso de GAE permite aprovechar los conocimientos que todo desarrollador Java ya tiene.

La escalabilidad y el coste se mide en cloudlets. Un cloudlet se corresponde con 128 MiB de memoria y 200 Mhz de cómputo y tiene un precio de 0,016 €/hora (para el proveedor dogado). Aún en estado beta puede probarse de forma gratuita. La aplicación puede escalar de forma transparente de forma vertical hasta un máximo de 16 cloudlets y en horizontal hasta un máximo de 4 máquinas.

OpenShift
OpenShift (de la mano de RedHat) es una opción similar a Jelastic, es un PaaS, pero soporta diferentes tecnologías además de Java como PHP, Ruby, Node.js y Python. También diferentes bases de datos como MySql, PostgreSql y MongoDB. Puede ser probada de forma gratuita con un límite de 3 gears, donde cada gear se corresponde con 512 MiB y 1 GiB de espacio en disco. Otra opción similar es AppFog que también tiene una capa gratuita.

Otras opciones son AppFog (esta es muy recomendable), Cloud Foundry (VMWare), Heroku, Azure (Microsoft) y Google Compute Engine (Google Cloud Platform).

Como se ve las opciones de hosting o alojamiento no son pocas cada una con varias características, precios y formas de cobro diferentes.

Referencia:
http://es.wikipedia.org/wiki/Computaci%C3%B3n_en_la_nube
http://archlinuxarm.org/
http://www.raspberrypi.org/
http://pandaboard.org/
http://www.danielclemente.com/consumo/
http://www.arsys.es/
http://www.piensasolutions.com/
http://aws.amazon.com/es/ec2/
http://code.google.com/intl/es-ES/appengine/
http://cloud.google.com/
http://jelastic.com/
https://www.appfog.com
https://openshift.redhat.com
http://www.windowsazure.com/es-es/
http://blog.jelastic.com/2012/02/09/jelastic-versus-heroku/

sábado, 18 de febrero de 2012

Debug de una aplicación Java

Java
Durante el desarrollo de una aplicación es normal que se produzcan excepciones y errores. Para descubrir sus causas y depurarlos se pueden utilizar varias herramientas. Una de ellas es utilizando un sistema de trazas como slf4j en el que podamos ver que ha estado haciendo la aplicación en el momento del fallo. Con la traza de la excepción la mayoría de las veces es suficiente para reproducir el error en una máquina de desarrollo pero en ocasiones hay «bugs» que si no se «tracean» o «debuggean» con un depurador no es fácil seguir la pista al código que se está ejecutando.

Para depurar una aplicación en Java hay que arrancar la máquina virtual en modo debug de tal forma que luego con un IDE como eclipse podamos depurar la aplicación. Los parámetros a añadir a la linea de comandos que arranca la JVM son:

-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

Si estamos depurando una aplicación web que se ejecuta en el contenedor Tomcat los shell scripts que lo arrancan nos lo ponen más fácil, tan solo tendremos que iniciar Tomcat con el siguiente comando y él se encargará de pasar los parámetros anteriores a la JVM:

catalina.sh jpda start

Para arrancar Tomcat en modo debug desde Ant podemos utilizar la siguiente tarea:

...
<condition property="LIB_HOME" value="/home/picodotdev/java">
 <and><os family="unix"/></and>
</condition>

<property name="TOMCAT" value="apache-tomcat-7.0.25"/>

<condition property="TOMCAT_STARTUP" value="startup.sh">
 <and><os family="unix"/></and>
</condition>
<condition property="TOMCAT_CATALINA" value="catalina.sh">
 <and><os family="unix"/></and>
</condition>
<condition property="TOMCAT_SHUTDOWN" value="shutdown.sh">
 <and><os family="unix"/></and>
</condition>
...
<target name="serverStartDebug">
 <exec executable="${LIB_HOME}/${TOMCAT}/bin/${TOMCAT_CATALINA}" dir="${LIB_HOME}/${TOMCAT}/bin/">
     <arg line="jpda start"/>
 </exec>
    <waitfor maxwait="10" maxwaitunit="second">
     <socket server="localhost" port="8080"/>
 </waitfor>
</target>
...

Una vez que tenemos la máquina virtual arrancada en modo debug podremos depurar la aplicación desde un IDE. En el siguiente paso veremos como hacerlo desde eclipse. Para ello en el eclipse iremos al menú «Debug > Debug Configurations > Remote Java Application» e indicaremos los parámetros: proyecto que queremos depurar, tipo de conexión (Standard (Socket Attach)), Host (localhost, si la JVM donde está ejecutandose la aplicación es la máquina local) y puerto (8000, lo mismo indicado que en el parámetro address).


Dado que en realidad nos estamos conectando a la máquina virtual de Java de forma remota y a través de la red tal vez necesitemos abrir el puerto 8000. Si tenemos un sistema Linux y ufw como firewall lo podremos hacer con:

$ sudo ufw allow 8000
$ sudo ufw status


 Una vez hayamos realizado los pasos anteriores estamos listos para «debuggear», podremos añadir puntos de ruptura donde queramos en la aplicación y podremos ver las variables y sus valores presentes en el ámbito de donde se ha parado la aplicación.


Referencia:
http://wiki.apache.org/tomcat/FAQ/Developing#Q2

viernes, 10 de febrero de 2012

Por qué usar enums en vez de constantes en Java

Java
En las versiones anteriores a la versión 1.5 o 5 de Java no existían los tipos de datos enum con lo que debíamos usar constantes de la siguiente forma:

public static String COLOR_ROJO = "rojo";
public static String COLOR_VERDE = "verde";
public static String COLOR_AZUL = "azul";

A partir de la versión 5 de Java se incorporarón al lenguaje los tipos de datos enumerados con el objetivo de mejorar varios aspectos sobre el uso de las constantes. Básicamente, un enum en Java es un conjunto fijo y relacionado de constantes como pueden ser los días de la semana y deberían usarse siempre que se necesite representar un conjunto de constantes con esas características. La característica de relacionado es importante, las constantes solo lo están por la convención que sigamos al darles un nombre. Los enums se definen de la siguiente forma:

public enum Dia {
 LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO
}

public enum Color {
        ROJO("FF0000"), 
 VERDE("00FF00"), 
 AZUL("0000FF");

 private final String rgb;

 Color(String rgb) {
  this.rgb = rgb;
 }

 public String getRGB() {
  return rgb;
 }
}

Como son constantes por las convenciones del lenguaje se escriben en mayúscula. Pero los enum son algo más que constantes, la clase del tipo del enum puede definir métodos y otras propiedades, como el método getRGB del ejemplo anterior o en el siguiente caso que se usa el método values() y que se añade automáticamente a todos los enums.

for (Dia d : Dia.values()) {
    System.out.printf("El día de la semana %s", d);
}

for (Color c : Color.values()) {
    System.out.printf("El color %s tiene como RGB %s", c, c.getRGB());
}

Algunas cosas que hacen de los enum muy interesantes es que al definir las constantes de este modo obtenemos «type safety». Si decimos que un método de una clase recibe un enum el compilador comprobará en tiempo de compilación que cuando lo usamos le pasemos realmente un valor de ese enum, cosa que con constantes definidas como int o String el compilador solo comprueba que pasemos un int o String y por tanto podremos pasar cualquier valor aunque no sea una de las constantes esperadas por el método. Otra de las ventajas que ya se ve en ejemplo anterior es que los enums pueden tener comportamiento a través de los métodos que defina. Tanbién, específicamente diseñadas para los enums existen las clases EnumSet y EnumMap que trabajan con enums de forma más eficiente que con Set y Map. Además, los enums pueden ser usados en expresiones switch cosa que con constantes de tipo String solo podemos hacer a partir de la versión 7 de Java..

Para comprarar valores de enums podemos hacerlo con el operador == o con el método equals. Usar el operador == tiene la ventaja de evitar un posible NullPointerException y de que el compilador comprueba que se estén comparando dos valores del mismo enum.

== nunca lanza NullPointerException

Dia dia = null;
if (dia == Dia.LUNES);      // se ejecuta
if (dia.equals(Dia.LUNES)); // lanza NullPointerException

== comprueba compatibilidad de tipos en tiempo de compilación

if (Dia.LUNES.equals(COLOR.ROJO)); // compila bien
if (DIA.LUNES == COLOR.ROJO);      // no compila, incompatibilidad de tipos

Estos son motivos suficientes para usar enums en vez de constantes y == en vez de equals para los enums a partir de la versión 5 de Java. Las constantes son mejor que tener en nuestro código «hardcodeados» los valores y con ellas obtendremos la asistencia de IDEs como eclipse para saber donde se utilizan y podremos hacer un refactor si necesitamos hacer un cambio de nombres («refactorización»). Pero los enums superan en ventajas a las constantes por los motivos anteriores asi que si podemos utilizar en nuestros proyectos Java 5 o superior es aconsejable utilizarlos.

Referencia:
http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
http://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals
http://www.javabeat.net/tips/171-how-to-use-enum-in-switch.html

sábado, 4 de febrero de 2012

Recarga de clases (class reloading) en Apache Tapestry

Apache Tapestry
En el mundo Java de desarrollo de aplicaciones web hace no tanto tiempo un cambio en una clase implicaba reiniciar el servidor para ver los cambios. Dado que desarrollando una aplicación los cambios son pequeños, incrementales y numerosos esto implicaba tener que reiniciar constantemente el servidor que dependiendo de la aplicación esto podría llevar no mucho tiempo, desde 10-30, que ya es un tiempo considerable, pero podría llegar a llevar incluso algunos minutos. El tiempo de espera para cada reinicio normalmente es tiempo no productivo que acumulándolo a lo largo del día puede llegar a ser considerable y por ello los frameworks web están evolucionando a no tener que requerir reiniciar el servidor para detectar las modificaciones, esto es, cogiendo los cambios en caliente. Ello nos permite ser más productivos.

Apache Tapestry evlucionó y no se quedó atras. La recarga de clases o «class reloading» es una característica añadida en Tapestry en la versión 5 para las clases de las páginas y componentes al igual que los archivos .tml de las plantillas y los los archivos de catálogos de mensajes. En la versión 5.2 la recarga de clases se extendió a los servicios definidos en los módulos de Tapestry. El proceso de recarga que hace Tapestry cuando se detecta un cambio en una clase no afecta a los datos persistentes ya que estos se guardan aparte, normalmente en la sesión, con lo que el desarrollo nos será muy cómodo.

Si nuestra aplicación tiene como paquete base com.blogspot.elblogdepicodev.tapestry Tapestry recargará las clases de los siguientes paquetes cuando detecte algún cambio:
  • com.blogspot.elblogdepicodev.tapestry.pages
  • com.blogspot.elblogdepicodev.tapestry.components
  • com.blogspot.elblogdepicodev.tapestry.mixins
  • com.blogspot.elblogdepicodev.tapestry.base
Sim embargo, el proceso tiene algunas limitaciones. La recarga solo se aplica a clases y archivos que están en el sistema de archivos y no obtenidos desde archivos JAR. Aunque esta limitación no es importante en desarrollo ya que podemos desplegar la aplicación en nuestro servidor de desarrollo de forma expandida.

El coger los cambios en caliente es una característica deseable de todo framework actual pero también hay que tener en cuenta el tiempo de inicio del servidor ya que en algún momento tarde o temprano nos tocará hacerlo, si queremos ser ágiles en el desarrollo no es recomendable esperar varios minutos a que el servidor termine de iniciarse y en producción es necesario que el tiempo de interrupción sea mínimo.

Un Tomcat sin ninguna aplicación tarda en iniciarse unos 4 segundos, con una aplicación Tapestry desplegada de forma expandida con Hibernate, EhCache y Quartz de tamaño medio tarda unos 10 segundos y en servir la primera página unos 15-20 segundos.

Referencia:
Documentación sobre Apache Tapestry