viernes, 24 de febrero de 2017

Instalar Oracle Java JDK8 en Ubuntu 16.04

Introducción

Me ausente de Linux por un periodo de 5 años, hoy regreso y lo encuentro mucho más guapo, he decidido volver. Como fanático de la programación lo primero que haré será instalar Java + Netbeans. Ubuntu por defecto viene con OpenJDK, en el pasado tuve malas experiencias con OpenJDK, prefiero instalar el JDK de Oracle.

Paso 1. Verificar que JDK tenemos

La instalación de Ubuntu que tengo no viene instalado con el OpenJDK, para ver si tenemos alguna versión instalada ejecutamos lo siguiente:














En caso de tener instalado el OpenJDK, hay que desinstalarlo, para hacerlo seguir este tutorial


Paso 2. Agregamos el repositorio de Java a nuestra lista de fuentes


Agregamos el repositorio a nuestra lista de fuentes, ejecutar el siguiente comando:















Nos pide confirmación para continuar, presionar enter para continuar














Si todo va bien veremos esta última pantalla













Paso 3. Actualizamos nuestra lista de fuentes

Para actualizar nuestra lista de fuentes ejecutamos lo siguiente:










Al terminar veremos la siguiente pantalla

















Paso 4. Instalar Java JDK 8

Ejecutamos el siguiente comando







Nos pedirá confirmación, presionar Y y luego enter













Nos advierte que debemos aceptar la Licencia















Aceptamos la Licencia













Esperamos unos minutos y al terminar muestra la siguiente pantalla














Tomar nota del mensaje con el titulo "important", para no tener ningún conflicto vamos a instalar lo que nos pide







Al finalizar veremos la siguiente pantalla













Reiniciamos el equipo y comprobamos la instalación, ejecutamos los siguientes dos comando














Así hemos finalizado con éxito la instalación de Oracle Java JDK 8 en Ubuntu 16.04

viernes, 17 de febrero de 2017

Maven: Que es?

Introducción

Hace ya un par de meses que decidí estudiar la plataforma JEE, la mayoría de los tutoriales que hay en la web están basados en Maven, la mayoría de esos ejemplos no funcionan a la primera ya que los archivos de configuración de Maven pueden estar obsoletos, diferencias entre el ambiente,distinto IDE, diferentes versiones de los componentes, y así. Hay que tener conocimientos sólidos en Maven para adaptar los tutoriales a nuestro ambiente particular.

Es así que decidí estudiar Maven a profundidad, hay un buen número de tutoriales y referencias en la web en español, pero no encontré uno escrito a profundidad, que explique con lujo de detalle todos los conceptos. He obtenido un libro muy completo de Maven, está en ingles, trataré de traducirlo para tenerlo como guía y aprender todos los conceptos de Maven.

¿Qué es Maven?

La respuesta a esta pregunta depende de quien lo pregunte, la mayoría de los usuarios que usan Maven lo consideran cómo una "herramienta build": herramienta usada para compilar, empaquetar y distribuir módulos desde el código fuente. Ingenieros y gerentes de proyectos podrían referirse a Maven cómo algo más completo: una herramienta de gestión(administración) de proyectos. ¿Cual es la diferencia? Una herramienta build como Ant, está enfocado exclusivamente en pre procesar, compilar, empaquetar, probar y distribuir. Una herramienta de gestión de proyectos cómo Maven proporciona un amplio conjunto de características encontrados en una herramienta build, es decir, es una herramienta build y algo más. Además de ser una herramienta build, Maven también puede generar distintos tipos de reportes, generar sitios web, y facilitar la comunicación entre miembros de un equipo de desarrollo.
Una definición más formal de Apache Maven: Maven es una herramienta de gestión de proyectos, que incluye un pom (Project Object Model) el modelo de objetos del proyecto, un conjunto de estándares, un ciclo de vida del proyecto, un sistema de gestión de dependencias, y lógica para ejecutar plugins en las fases del ciclo de vida. Cuando tu usas Maven, tu describes tu proyecto usando un pom definido correctamente, después Maven aplicará lógica de forma transversal (profundidad máxima para cada objeto) al conjunto de plugins compartidos o personalizados. Más adelante veremos que son los plugins.
No dejes que te intimide el hecho de que Maven sea una herramienta de gestión de proyectos. Si sólo estabas buscando una herramienta build, Maven puede hacer el trabajo. De hecho. los primeros artículos de este libro cubrirán la mayoría de los casos de usos comunes: usando Maven para construir y distribuir tu proyecto.

Convención Sobre Configuración

Convención sobre Configuración, también conocido como CoC es un concepto simple que busca minimizar el número de decisiones que un desarrollador necesita hacer, ganando así en simplicidad pero no perdiendo flexibilidad por ello.
Frameworks populares como Ruby on Rails y EJB3 han comenzado a adquirir estos principios como respuesta a la complejidad de los frameworks, tal como es el caso de la especificación inicial EJB 2.1. Para ilustrar el concepto de Convención sobre Configuración, considere la persistencia en EJB3: todo lo que necesitas hacer para tener un bean persistente es agregar a tu clase la anotación @Entity. El framework asume que el nombre de la tabla y columnas están en base al nombre de la clase y sus atributos. Sin embargo tu puedes sobreescribir estos nombres en caso de ser necesario, pero en la mayoría de los casos encontrarás que usar el framework con sus configuraciones por defecto te permitirá una rápida ejecución del proyecto.
Maven incorpora este concepto proporcionando configuraciones y comportamientos por defecto para los projectos. Sin ninguna configuración, se asume que el código fuente estará en ${basedir}/src/main/java y se asume que los recursos estarán en ${basedir}/src/test, y se asume que un proyecto generará un archivo JAR. Maven asume que tu quieres el código byte compilado en ${basedir}/target/classes y entonces crear en ${basedir}/target un archivo JAR para distribuir. Mientras esto puede parecer trivial, considera el hecho de que en Ant se tiene que definir la ubicación de todos estos directorios. Ant no tiene idea de donde pueden estar el código fuente o los recursos en un proyecto. Tu tienes que proporcionar explicita mente esta información. La adopción del concepto Convención sobre configuración de Maven, va más allá de simple ubicaciones de directorios. Los plugins principales de Maven aplican un conjunto común de convenciones para compilar código fuente, empaquetar distribuciones, generar sitios web, y muchos otros procesos. Si tu sigues las convenciones, Maven requerirá esfuerzos mínimos, sólo coloca el código fuente en el directorio correcto y Maven se encargará del resto.
Un efecto secundario de usar sistemas que siguen el concepto de "Convención sobre Configuración" es que el usuario final puede sentir que está siendo forzado a usar un enfoque o metodología particular. Si bien es cierto que Maven tiene algunas opiniones bases que no deberían ser desafiadas, la mayoría de las características que vienen por defecto pueden ser personalizados. Por ejemplo, la ubicación  del código fuente de un proyecto y la ubicación de los recursos, estos pueden ser personalizados, los nombres de los archivos JAR también pueden ser personalizados, . Si no quieres seguir la convención, Maven te permitirá adaptar las características por defecto con tal de adaptarlos a tus requerimientos específicos.


Referencia:
Maven: The complete Reference, Sonatype, http://www.sonatype.org/nexus/resources/resources-book-links-and-downloads/

viernes, 10 de febrero de 2017

Como localizar y leer recursos en Java

Introducción

Localizar y leer recursos puede ser una tarea confusa y frustrante cuando no se tienen fundamentos sólidos, incluso a mi se me olvidan de vez en cuando, es por ello que decidí escribir esta entrada, para consultarla cuando la necesite.
Un recurso puede ser un archivo de texto o binario, imagen, audio, etc,. Usualmente los programas o clases necesitan leer estos recursos de forma independiente a la ubicación. De mi experiencia reconozco que la ubicación de un recurso puede coincidir con algunos de estos escenarios:
  • En la misma ubicación donde se encuentra la clase que necesita leer el recurso.
  • En otro paquete dentro del mismo jar donde se encuentra la clase que necesita leer el recurso
  • En un paquete dentro de un jar distinto al jar donde se encuentra la clase que necesita leer el recurso.
  • En un directorio, donde el directorio se encuentra en el classpath.
  • En algún lugar arbitrario dentro de una aplicación web fuera del jar donde se encuentra la clase que necesita leer el recurso

Las clases Class y ClassLoader contienen métodos para localizar y cargar recursos, cuando digo localizar me refiero a que pueden entregarnos una URL del recurso, y por cargar me refiero a que pueden entregarnos una instancia de un InputStream con el cual podemos leer el contenido.

Nota: El Classpath es una lista de directorios asociada a nuestra aplicación, cada aplicación que se ejecuta en la JVM tiene asociada un Classpath.

Nota: El ClassLoader en palabras simples, es una clase responsable de cargar en memoria nuestra clase principal y todas aquellas clases que necesite.

Recursos, nombres y contexto

Un recurso es identificado por una cadena de caracteres la cual se compone de subcadenas de caracteres separados por slashes (/), seguido por el nombre del recurso, es decir, el nombre del recurso es el nombre del recurso más la ruta (path) absoluta o relativa. Cada subcadena debe ser un identificador Java válido.  El nombre del recurso puede ser de la forma shortName o shortName.extension. Ambos shortName y extensión deben ser identificadores Java.
Aquí una referencia completa  de identificadores válidos en Java:
https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html
El nombre del recurso es independiente de la implementación de Java, en particular el separador path, el cual siempre será un slash (/). Sin embargo, la implementación de Java controla los detalles de como los recursos son mapeados en un archivo, base de datos u otro objeto capaz de contener al recurso.
Nota: La interpretación del nombre del recurso es relativo a la instancia del class loader. Los métodos implementados por la clase ClassLoader hacen esta interpretación.

Como localiza Java los recursos

Java buscará el recurso dentro del "ambiente" de la aplicación, consideramos "ambiente" a todos los jars y directorios que se encuentren en el Classpath. La búsqueda y carga de recursos en Java es llamado independiente de la localización porque no es relevante donde el código está corriendo, basta tener el ambiente correcto para encontrar los recursos.
Las clases ClassLoader y Class nos proveen métodos para buscar recursos deseados, es necesario comprender bien el contexto de uso de cada uno de ellos para evitarnos problemas en un futuro y para decidir cual método usar.

Usando métodos de la clase java.lang.Class, búsqueda relativa y absoluta


La clase Class nos proporciona los siguientes dos metodos para la carga de recursos.

public URL getResource(String name)
public InputStream getResourceAsStream(String name)

El metodo getResource() retorna una instancia URL para el recurso. Si el recurso no existe o no está visible debido a consideraciones de seguridad, el metodo retorna null.

Si el código cliente necesita leer el contenido del recurso como una instancia InputStream, se puede hacer una llamada al metodo openStream() de la instancia URL.  Mejor aun, puedes hacer uso del metodo getResourceAsStream() de la clase Class, ambas formas son equivalentes, la unica diferencia es que el método getResourceAsStream() atrapa la excepción IOException y retorna una instancia null de InputStream.
Incluso podemos ir más lejos, si sabemos que el recurso a leer es una imagen podemos obtener el contenido llamando al metodo getContent() de la clase URL, este metodo nos devuelve una instancia de la clase awt.image.ImageProducer y apartir de aquí podemos pintar la imagen en un Component

Los metodos getResource y getResourceAsStream encuentran un recurso a partir del nombre proporcionado, esta busqueda puede ser relativa al paquete del objeto Class o absoluta. Si el recurso con el nombre especificado no se encuentra retornan una instancia null. Hay un conjunto de reglas que se aplican a la busqueda de recursos, estas reglas son implementadas por el ClassLoader de la instancia Class.
Los metodos  getResource y getResourceAsStream de la clase Class delegan la tarea a los métodos de la clase ClassLoader, no sin antes resolver el nombre del recurso de acuerdo a ciertas reglas.

Resolver el nombre del recurso consiste en lo siguiente: si el nombre del recurso no es absoluto, se obtiene el nombre del paquete de la clase asociada al objeto Class, se reemplazan todos los caracteres "." por "/"  y se le antepone al nombre del recurso. En otro caso, si el recurso es absoluto solo se elimina el caracter inicial "/". El nombre de un recurso se considera absoluto si empieza con "/".

Nota: Absoluto respecto a nuestro ambiente, el cual es definido por el ClassLoader y no absoluto con respecto al sistema de archivos del sistema operativo.

Nota: Recordar que después de resolver el nombre del recurso, los métodos de la clase Class delegan la tarea a los métodos de la clase ClassLoader

Usando métodos de la clase ClassLoader

La clase ClassLoader tiene dos metodos para localizar y leer recursos

public URL getResource(String name)
public InputStream getResourceAsStream(String name)

Repito, estos dos métodos son usados por los métodos de la clase Class. En un ambiente Java nos vamos a encontrar con más de un ClassLoader, pudiendo haber una relación entre ellos, cada ClassLoader tiene asociado un directorio al que tiene acceso para cargar las clases, siendo el System Class Loader el que tiene acceso a una lista de directorios, sí, me refiero al Classpath. Es importante conocer cuantos ClassLoader pueden haber en un ambiente Java y como estos están relacionados.

Hay una articulo en la web que explica detalladamente el tema de los ClassLoader, coincido con el autor, así que antes de continuar ver el concepto de ClassLoader 

En resumen, cuando ejecutamos una clase en  la JVM, al menos tres ClassLoader son usados.
  1. Bootstrap class loader.
  2. Extensións class loader.
  3. System class loader

El bootstrap class loader carga las librerías (jars) del núcleo de Java localizado en el directorio <JAVA_HOME>/lib. Esta clase es parte del núcleo de la JVM, esta escrito en código nativo.

El extensions class loader carga las librerías (jars) y directorios que se encuentren en el directorio de extensiones (<JAVA_HOME>/lib/ext, u otro directorio especificado por la propiedad java.ext.dirs ) Esta implementado por la clase sun.misc.Launcher$ExtClassLoader.

El system class loader carga las librerías (jars) y directorios encontrados en el Classpath. Es implementado por la clase sun.misc.Launcher$AppClassLoader.

Las instancias Class Loader siguen una jeraquía, una instancia de Bootstrap class loader puede ser padre de una instancia de Extension class loader, y esta puede ser padre de una instancia de System class loader.
Cuando buscamos un recurso este se busca de arriba hacia abajo, por ejemplo, si a una instancia de System class loader le pedimos un recurso, este se lo pedirá a su padre y su padre se lo pedirá a su padre, así hasta llegar al padre de todos. Si el padre no tiene el recurso se buscará en el hijo, si este no lo tiene se lo pedirá a su hijo, así hasta llegar al System class loader. Todos los Class Loader buscan el recurso de forma absoluta, absoluta a cada uno de los  jar o directorios asociado.

Ahora si, con todos los fundamentos mencionados, es momento de ir a la practica.

Localizar un recurso ubicado en el mismo paquete donde se encuentra la clase que lo necesita

Tengo el siguiente proyecto ya compilado y estructurado como lo muestra la imagen


Vamos a localizar el recurso "duke_wave.png" el cual se encuentra en el mismo paquete que la clase "ResourceLocator". Este recurso está ubicado en dos lugares, dentro de mi proyecto, el cual tiene la ruta absoluta "C:\devel\src\personal\tutorials\tutorials\src\com\rlopez\tutorials\resources" , absoluta en relación al sistema de archivos del Sistema Operativo.
Una vez compilemos el proyecto, explicitamente o ya sea que Netbeans lo haga de forma automática, vamos a tener otro recurso "duke_wave.png", el cual estará ubicado en la ruta absoluta "C:\devel\src\personal\tutorials\tutorials\build\classes\com\rlopez\tutorials\resources", absoluta en relación al sistema de archivos del Sistema Operativo.

Para localizar nuestro recurso lo podemos hacer de dos formas, relativa a nuestra clase o absoluto a nuestro ambiente.

Búsqueda relativa a nuestra clase

public static URL getRelativeResource(String resourceName){
   Class clazz = ResourceLocator.class;
   URL url = clazz.getResource(resourceName);
   return url;
}

Búsqueda absoluta en nuestro ambiente

Al ejecutar la clase main desde Netbeans, se agrega el directorio "C:\devel\src\personal\tutorials\tutorials\build\classes\"al classpath de la aplicación, este directorio pasa a ser parte del ambiente de la aplicación.

public static URL getAbsoluteResource(String resourceName){
   Class clazz = ResourceLocator.class;
   String rpath = "/com/rlopez/tutorials/resources/" + resourceName; 
   URL url = clazz.getResource(rpath);
   return url;
}

Haciendo uso de nuestros métodos

/*
 * Tutorials
 * Copyright (C) 20017 Roberto Lopez marcos.roberto.lopez@gmail.com
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 * Roberto Lopez
 * CDMX, México
 * Email: marcos.roberto.lopez@gmail.com
 */

package com.rlopez.tutorials.resources;

import java.net.URL;
/**
 *
 * @author Roberto Lopez
 */
public class ResourceLocator {
 
 public static void main(String args[]){
  System.out.println("The App Classpath:" + System.getProperty("java.class.path"));
  System.out.println("Test get resource using relative way");
  URL url = ResourceLocator.getRelativeResource("duke_wave.png");
  System.out.println("Resource [Relative]:" + url.getFile());
  
  System.out.println("Test get resource using Absolute way");
  URL urlAbs = ResourceLocator.getAbsoluteResource("duke_wave.png");
  System.out.println("Resource [Absolute]:" + urlAbs.getFile());
 }
 
 public static URL getRelativeResource(String resourceName){
  Class clazz = ResourceLocator.class;
  URL url = clazz.getResource(resourceName);
  return url;
 }
 
 public static URL getAbsoluteResource(String resourceName){
  Class clazz = ResourceLocator.class;
  String rpath = "/com/rlopez/tutorials/resources/" + resourceName;
  URL url = clazz.getResource(rpath);
  return url;
 }
}

Run:
The App Classpath:C:\devel\src\personal\tutorials\tutorials\build\classes
Test get resource using relative way
Resource [Relative]:/C:/devel/src/personal/tutorials/tutorials/build/classes/com/rlopez/
tutorials/resources/duke_wave.png
Test get resource using Absolute way
Resource [Absolute]:/C:/devel/src/personal/tutorials/tutorials/build/classes/com/rlopez/
tutorials/resources/duke_wave.png


Localizar un recurso en otro paquete dentro del mismo jar donde se encuentra la clase que necesita leer el recurso
Modificamos el proyecto agregando un nuevo paquete

Nuevamente vamos a usar los métodos que definimos anteriormente y vamos a buscar el recurso de forma relativa y absoluta.
En la búsqueda relativa iremos al directorio superior con el comando ".." y hemos realizado una modificación a la búsqueda absoluta.

/*
 * Tutorials
 * Copyright (C) 20017 Roberto Lopez marcos.roberto.lopez@gmail.com
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 * Roberto Lopez
 * CDMX, México
 * Email: marcos.roberto.lopez@gmail.com
 */

package com.rlopez.tutorials.resources;

import java.net.URL;
/**
 *
 * @author Roberto Lopez
 */
public class ResourceLocator {
 
 public static void main(String args[]){
  System.out.println("The App Classpath:" + System.getProperty("java.class.path"));
  System.out.println("Test get resource using relative way");
  URL url = ResourceLocator.getRelativeResource("../images/duke_wave.png");
  System.out.println("Resource [Relative]:" + url.getFile());
  
  System.out.println("Test get resource using Absolute way");
  URL urlAbs = ResourceLocator.getAbsoluteResource("/com/rlopez/tutorials/images/
duke_wave.png");
  System.out.println("Resource [Absolute]:" + urlAbs.getFile());
 }
 
 public static URL getRelativeResource(String resourceName){
  Class clazz = ResourceLocator.class;
  URL url = clazz.getResource(resourceName);
  return url;
 }
 
 public static URL getAbsoluteResource(String resourceName){
  Class clazz = ResourceLocator.class;
  if(!resourceName.startsWith("/")){
   resourceName = "/" + resourceName;
  }
  URL url = clazz.getResource(resourceName);
  return url;
 }
}

run:
The App Classpath:C:\devel\src\personal\tutorials\tutorials\build\classes
Test get resource using relative way
Resource [Relative]:/C:/devel/src/personal/tutorials/tutorials/build/classes/com/rlopez/
tutorials/images/duke_wave.png
Test get resource using Absolute way
Resource [Absolute]:/C:/devel/src/personal/tutorials/tutorials/build/classes/com/rlopez/
tutorials/images/duke_wave.png

En un paquete dentro de un jar distinto al jar donde se encuentra la clase que necesita leer el recurso



Localizar un recurso en un directorio, donde el directorio se encuentra en el classpath.

Pendiente

Localizar un recurso en algún lugar arbitrario dentro de una aplicación web y fuera del jar donde se encuentra la clase que necesita leer el recurso

Pendiente

Ultimas consideraciones
Pendiente

Referencia:
http://www.thinkplexx.com/
http://docs.oracle.com/javase
http://docs.oracle.com/javase/7