Como desplegar un servicio web sin utilizar un Java EE container

Desde la javaSE 6 es muy sencillo la creación de servicios Web ya que las annotations incluidas (proyecto Metro) en el jsdk nos permiten que un POJO pueda fácilmente convertirse en un servicio.

NOTA: Desde javaSE 5 podíamos crear servicios web con annotations, pero para entonces el jsdk no incluía al proyecto Metro, por lo cual era necesario descargar los jar necesarios del proyecto Metro e incluirlos en nuestra aplicación.

En esta oportunidad les traigo un pequeño ejemplo de un servicio Web pero con la particularidad de que lo desplegaremos sin hacer uso del un Java EE container (contenedor de servlet, servidor de aplicaciones).

Nuestro primer paso será crear el SEI (Service Endpoint Interface), aunque no es requisito indispensable, resulta en una buena practica de programación.

Una vez definido el SEI procedemos a realizar la implementación del servicio o lo que es lo mismo el SBI (Service Bean Implementation).

Ahora viene una parte que a mi me resulta interesante, creamos el Publisher, el cual no es mas que la clase encargada de crear y publicar el endPoint de nuestro servicio Web.

Para aquellos que no lo sepan, el servicio Web que acabamos de crear y publicar lo hemos hecho utilizando jax-ws y por ende nuestro servicio web es del tipo SOAP.

Como comprobar que nuestro servicio esta funcionando correctamente, teniendo en cuenta que no nos arroja ningún mensaje de error por consola? Sencillamente iniciemos nuestro navegador (browser) de preferencia e introduzcamos la ruta http://localhost:9876/helloworld?wsdl ó http://127.0.0.1:9876/helloworld?wsdl y les aparecerá un mensaje como este:

Ese documento XML que hemos obtenido no es mas que el WSDL (Web Service Definition Language) que es una especie de contrato donde están definidas las operaciones y características del servicio Web.

NOTA: Los usuarios de Safari verán sencillamente una pagina en blanco, pero si revisan el código fuente de dicha pagina podrán ver el documento XML, es esta la razón por la cual he optado por utilizar Firefox.

Ahora bien, ya hemos hecho un servicio Web, lo hemos publicado e incluso hemos podido ver su WSDL, queda realizar lo más esperado, poder ejecutar y probar nuestro servicio Web, para esta labor haré uso de SoapUI una herramienta gratuita que nos permite hacer pruebas de servicios web de forma sencilla, para esto crearemos un nuevo proyecto de SoapUI y le indicamos el WSDL de nuestro servicio Web, como verán en la siguiente imagen:

Esta herramienta utilizara el WSDL para construir los sobres SOAP haciendo muy sencilla la tarea de hacer las pruebas. Para finalizar haremos una ejecución editando el XML de petición que por defecto nos elabora soapUI y le colocaremos una cadena de caracteres, en este caso he utilizado mi nombre (Uds. tienen todo el derecho de colocar el suyo/vuestro jejeje) y procedemos a pulsar el símbolo de play o triángulo de ejecución y podrán ver el mensaje de respuesta de nuestro servicio.

Aqui les dejo una imagen de la ejecución hecha por mi.

Finalmente hemos realizado un servicio Web de tipo SOAP mediante jax-ws, lo hemos desplegado sin necesidad de un servidor de aplicaciones o contenedor Java EE (lo cual tiene sus limitantes, ya que solo puede recibir una petición a la vez) y hemos fácilmente hecho pruebas de nuestro servicio con una herramienta sencilla así como también útil que es soapUI. Espero les haya sido de utilidad y les haya resultado interesante.

Sabias que el serialVersionUID en las clases Java nos previene de errores en la deserialización

Estoy seguro que todos aquellos que hemos programado en Java en alguna oportunidad hemos visto como nuestro IDE nos arrojaba un warning (advertencia) indicandonos que «la clase serializable nombre_clase no declara un campo serialVersionUID final estatico de tipo long» y más seguro estoy (por experiencia propia) de que sin meditarlo mucho optamos por la opción que nos daba el IDE (eclipse, netbeans o cualquier otro) para que nos resolviera el warning y asi tener nuestro código limpio de mensajes de advertencia y errores.

Ejemplo de mensaje warning de serialVersionUID

¿Qué es serialVersionUID?

Es un número de versión que posee cada clase Serializable, el cual es usado en la deserialización para verificar que el emisor y el receptor de un objeto serializado mantienen una compatibilidad en lo que a serialización se refiere con respecto a la clases que tienen cargadas (el emisor y el receptor).

¿Qué pasa si no declaro un serialVersionUID?

El proceso de serialización asocia cada clase serializable a un serialVersionUID. Si la clase no especifica un serialVersionUID el proceso de serializacion  calculará un serialVersionUID por defecto, basandose en varios aspectos de la clase. Es muy recomendable que se declare un serialVersionUID en las clases serializables, ya que el calculo del serialVersoinUID es muy sensible a detalles de la clase, los cuales pueden variar entre compiladores, es decir, si trabajamos serializando/deserializando objetos y trabajamos con distintos compiladores Java podemos llegar a obtener una InvalidClassException durante el proceso de deserialización debido a discrepancias entre los serialVersionUID calculados por cada compilador. Por eso para garantizar un serialVersionUID que sea indiferente a la implementación del compilador es altamente recomendado declarar un valor explicito del serialVersionUID (de tipo long) y de ser posible que tenga el modificador de acceso private para que afecte unicamente a la clase que lo ha declarado y no a las clases hijas (subclases) que hereden de ella, forzando de alguna manera a cada clase hija a declarar su propio serialVersionUID (Ver imagen abajo).

Ejemplo de herencia de clase Serializable observando warning de serialVersionUID en clase hija

Para mas información no dejen de revisar en la API la interfaz Serializable

Como compilar código Java desde una clase Java

Días atras dandole un vistazo a la Java API, me encontre con una interfaz que no tenia idea que existiera y es la interfaz JavaCompiler. A continuación un ejemplo sencillo de como compilar una clase:

Para el ejemplo anteriormente mostrado, asumimos que hemos codificado una clase y ubicada en c:/Example.java. Como mi idea es demostrar como compilar, le dejo a ustedes la tarea de crear una clase cualquiera, con y sin errores para poder observar la salida de la ejecución de este programa.

Brevemente comento del código.

  • Clase ToolProvider, disponible desde la versión 6, esta clase nos permite obtener proveedores de compiladores.
  • Invocación del método run, método heredado de la interfaz Tool (presente desde la versión 6 de Java), es una interfaz utilizada para invocar programas, y en nuestro caso la utilizamos para la invocación del compilador. Incluso podríamos obtener las versiones soportadas por la herramienta invocando el método getSourceVersions();

La anterior no es la única forma de poder llevar a cabo la compilación, he aquí otro ejemplo, pero en este caso usando métodos propios de la interfaz JavaCompiler.

Esta ultima forma de llevar a cabo la compilación, particularmente es de mi preferencia ya que nos permite mejorar en rendimiento, en el caso de que llevemos a cabo la compilación de un grupo de ficheros (archivos) mientras reutilicemos el gestor de archivos, además de poder pasarle de una forma mas ordenada las opciones de compilación.

NOTA: En este segundo ejemplo también dejo de parte de ustedes la creación del fichero a compilar (C:/Example.java), que en este caso he hecho uso del mismo en ambos ejemplos.

espero les pueda ser de utilidad, incluso podríamos hasta crearnos nuestro propio IDE, donde compilemos y a su vez nos muestre los mensajes de error en caso de haberlos.

 

Sabias que los literales enteros en Java por defecto son compilados como int

Este es el primer post de la nueva categoría que he denominado «Sabias que…», donde les iré contando cosas que me resultan curiosas e interesantes  sin que por eso no dejen de ser algunas veces «triviales», en esta oportunidad les contare algo que algunos puede que desconozcan e incluso puede que llegue a serles útil en el caso de buscar certificarse.

Sin más preámbulos, así como dice el titulo, por defecto todos los literales enteros que declaremos en nuestro programa Java, serán compilados como int (entero). Lo demostrare mediante el siguiente ejemplo, que consistirá de una función que validará el rango de un número entero. Realmente es un ejemplo sencillo pero que cumple con el objetivo del post. A continuación el código.

Si compilan el código mostrado anteriormente, les aparecería el mensaje

Si hacen uso del IDE Eclipse les aparecería el mensaje «The literal 9999999999 of type int is out of range».

Es un error de compilación que se resuelve sencillamente agregando la letra «L», al literal quedando de esta manera 9999999999L.

Como pueden ver es algo muy sencillo, incluso para algunos será trivial pero les aseguro que en una prueba de certificación mas de uno de seguro se equivocaría y diría que el código se compila perfectamente, asumiendo un cast automático.

Si deseas compartir con nosotros eso que te parece interesante y/o curioso, no dudes en hacerlo, así todos aprenderemos.