feed twitter facebook LinkedIn facebook

Java » Guía Completa Javamelody: Monitoreo de aplicaciones web

julio 31, 2012 por Emmanuel Sio Sin Comentarios Imprimir Imprimir

Javamelody es una herramienta destinada a monitorear servidores de aplicación Java o Java EE en ambientes de QA y producción. Es importante tener en cuenta que no es una herramienta para simular pedidos de usuarios, sino que se debe utilizar para medir y calcular estadísticas que surgen de la operatoria de la aplicación por todos los usuarios.

Requisitos de Javamelody

Se requiere tener instaladas las siguientes versiones de Java:

  • 1.5 como mínimo
  • 1.6 o 1.7 para las siguientes funciones: heap dump, memory histogram, stack traces and system load average
  • JDK o JRE de Sun o JRockit de Oracle/BEA o J9 de IBM

Versiones de Servidor:

  • JavaEE 1.4
  • Tomcat 5.5, 6 o 7
  • GlassFish v2 o v3
  • JBoss 4, 5, 6 o 7
  • Jonas 4 o 5
  • Jetty 6 o 7
  • WebLogic 9, 10, 11

Instalación de Javamelody

La instalación es realmente sencilla. Solamente basta copiar dos archivos en la carpeta WEB-INF/lib de la aplicación que deseamos monitorear. Luego debemos editar el archivo web.xml agregando algunas pocas líneas de código.

Instalación Paso a Paso

Los siguientes pasos son los básicos, donde elegimos a Tomcat como servidor de ejemplo.

Pasos:
a) Descargar el archivo javamelody-x.x.x.zip de la web del proyecto.
b) Descomprimir el archivo zip.
c) Copiar los archivos javamelody-x.x.x.jar y jrobin.x.x.x.jar al directorio WEB-INF/lib que está dentro del directorio webapps/nuestra-aplicación.
d) Agregamos las siguientes líneas en el archivo WEB-INF/web.xml de la aplicación.

  1. <filter>
  2. <filter-name>monitoring</filter-name>
  3. <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>monitoring</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>
  9. <listener>
  10. <listener-class>net.bull.javamelody.SessionListener</listener-class>
  11. </listener>

e) Si queremos tener informes en PDF debemos copiar a WEB-INF/lib el archivo itext-2.1.7.jar. Este paso es opcional.

Si necesitan más customizaciones pueden obtenerlos del sitio de google code donde se encuentra alojado todo el proyecto de Javamelody. Pueden visitarlo aquí.

Primeros resultados

Podemos acceder a nuestra herramienta a través de:

http://<host>/<my-context>/monitoring

  • <host> : nombre del servidor donde la aplicación web está instalada, seguido posiblemente por el puerto (por ejemplo localhost:8080).
  • <my-context>: Es el nombre del contexto de la aplicación web.

Seguridad

La página de monitoreo no tiene datos como usuario y password para ser usados como login. Por ello, antes de usar Javamelody en producción puede ser necesario que deseemos restringir el acceso a esta página. Esta tarea recae en nosotros mismos, donde una de las posibilidades es realizar un login customizado. Javamelody nos ayuda dándonos la posibilidad de restringir su acceso a través de una expresión regular tomando como parámetro la dirección IP del cliente. Esto podemos lograrlo a través de allowed-addr-pattern. Por ejemplo: “192\.168\..*|123\.123\.123\.123” para permitir las IP que se encuentren en el rango “192.168.*.*” mas cualquier pc que se encuentre detrás de una puerta de enlace 123.123.123.123.
Hay que tener en cuenta que si usamos un servidor proxy http como Apache, la dirección IP del cliente será la de Apache. Por ello, no debes usar allowed-addr-pattern en este caso o, si es ese el caso, no usar Apache para acceder a esta página, o  habilitar mod_proxy_ajp para que el servidor monitoreado sepa las direcciones IP de los clientes.

Ejemplo de httpd conf con ajp:

  1. <location /webapp>
  2. ProxyPass ajp://localhost:8080/webapp
  3. </location>

Otra opción que tenemos es la utilización de roles. Si en nuestro archivo web.xml ya hemos definido roles, entonces podemos habilitarlos para que solo ellos puedan acceder a la página de monitoring.

Ejemplo utilizando roles:

  1. <login-config>
  2. <auth-method>BASIC</auth-method>
  3. <realm-name>Monitoring</realm-name>
  4. </login-config>
  5. <security-role>
  6. <role-name>monitoring</role-name>
  7. </security-role>
  8. <security-constraint>
  9. <web-resource-collection>
  10. <web-resource-name>Monitoring</web-resource-name>
  11. <url-pattern>/monitoring</url-pattern>
  12. </web-resource-collection>
  13. <auth-constraint>
  14. <role-name>monitoring</role-name>
  15. </auth-constraint>
  16. <!-- if SSL enabled (SSL and certificate must then be configured in the server)
  17.   <user-data-constraint>
  18. <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  19. </user-data-constraint>
  20. -->
  21. </security-constraint>

Los usuarios deben estar definidos en el servidor de aplicación y deben tener asignado el rol de monitoring para tener acceso a los reportes. Un ejemplo de cómo configurarlo sería del siguiente modo:

  1. <?xml version='1.0' encoding='utf-8'?>
  2. <tomcat-users>
  3. <role rolename="monitoring"/>
  4. <user username="monitoring" password="monitoring" roles="monitoring"/>
  5. </tomcat-users>

Activación consultas SQL

Si dentro de nuestra aplicación utilizamos Hibernate, entonces la siguiente línea de configuración puede ser utilizada para poder activar el rastreo de las consultas SQL realizadas.

Para ello buscamos el archivo hibernate.cfg.xml y agregamos la siguiente línea:

  1. <property name="hibernate.jdbc.factory_class">net.bull.javamelody.HibernateBatcherFactory</property>

Esto habilita que Javamelody detecte cada consulta realizada y nos muestre el tiempo total de ejecución, la cantidad de veces que se ejecutó dicha consulta, el máximo tiempo de ejecución, desviación standard y el % de error del sistema.

Generación de reportes PDF

Para generar reportes en PDF como también en HTML, debemos agregar la librería iText v2.1.x. Para ello buscamos el archivo iText-2.x.x.jar, ubicado en src/test/test-webapp/WEB-INF/ lib dentro de javamelody.zip y copiarlo dentro del directorio WEB-INF/lib .

Suplementos en web.xml

Para evitar monitorear algunas url determinadas podemos usar url-pattern dentro del archivo web.xml.

Por ejemplo, usamos filter-mappings y url-patterns para monitorear solamente urls como /servlet1/* y /servlet2/* pero no otras como /static/*

  1. <filter>
  2. <filter-name>monitoring</filter-name>
  3. <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>monitoring</filter-name>
  7. <url-pattern>/servlet1/*</url-pattern>
  8. </filter-mapping>
  9. <filter-mapping>
  10. <filter-name>monitoring</filter-name>
  11. <url-pattern>/servlet2/*</url-pattern>
  12. </filter-mapping>
  13. <filter-mapping>
  14. <filter-name>monitoring</filter-name>
  15. <url-pattern>/monitoring</url-pattern>
  16. </filter-mapping>
  17. <listener>
  18. <listener-class>net.bull.javamelody.SessionListener</listener-class>
  19. </listener>

Es importante tener en cuenta que url-pattern debe contener la url /monitoring para tener reportes.
Como alternativa, se puede usar un único /* url-pattern y un parámetro de filtro con una expresión regular antes del tag .

Por ejemplo:

  1. <filter>
  2. <filter-name>monitoring</filter-name>
  3. <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
  4. <init-param>
  5. <param-name>url-exclude-pattern</param-name>
  6. <param-value>/static/.*</param-value>
  7. </init-param>
  8. </filter>
  9.  
  10. <filter-mapping>
  11. <filter-name>monitoring</filter-name>
  12. <url-pattern>/*</url-pattern>
  13. </filter-mapping>
  14.  
  15. <listener>
  16. <listener-class>net.bull.javamelody.SessionListener</listener-class>
  17. </listener>

Esto ha sido todo sobre la instalación de JavaMelody. Esperamos que les sea útil a la hora de tener una guía completa para su instalación.

Java » Comprobar conexión a Internet con Java

Hace algún tiempo necesitaba una aplicación que cada determinado tiempo compruebe el estado de la conexión, entonces desarrolle una aplicación en Java muy simple que cada cierto tiempo verifique el estado de conexión. Lo que voy a exponer aquí solo es la parte de código Java que se encarga de la comprobar la conexión, nada más. Luego podrá usted incluirlo en una aplicación más grande y con sus propios fines si le parece útil el pequeño código expuesto.

Para este sencillo programa Java vamos a utilizar la clase Socket, así que veamos lo necesario de ella para los fines de la aplicación. También es necesario trabajar con excepciones pero creo que a este tema le corresponde un post por sí solo.

Clase Socket de Java: Es un conector TCP/IP diseñado para conectarse a servidores e iniciar intercambios bajo protocolo. La creación de un objeto Socket establece implícitamente una conexión entre cliente y servidor. Ahora pasemos al código:

Antes que nada importamos el paquete java.net y ponemos los comentarios de documentación habituales:

  1. import java.net.Socket;
  2. /**
  3. * @(#)ComprobarConexionJava.java
  4. *
  5. * ComprobarConexionJava application
  6. *
  7. * @author Christian G. Gimenez
  8. * @version 1.00 2012/6/27
  9. */

Luego tenemos la signatura de la clase y del método main de Java, toda la acción va a estar dentro del método main:

  1. public class ComprobarConexionJava {
  2. public static void main(String[] args) {

Lo siguiente que vamos a hacer es definir dos variables, de tipo String e int que contendrán una dirección web y un puerto respectivamente:

  1. String dirWeb = "www.lineadecodigo.com";
  2. int puerto = 80;

A continuación, viene algo fundamental para el funcionamiento de esta pequeña aplicación, cuando definimos una variable de tipo Socket y creamos el objeto de dicho tipo lo hacemos dentro de un bloque try, de no ser así vamos a tener problemas a la hora de compilar nuestra aplicación:

  1. try{
  2. Socket s = new Socket(dirWeb, puerto);
  3.  

Ahora utilizamos un if para llamar al método isConnected() de la clase Socket, este método devolverá un valor booleano, dependiendo de éste devolveremos un mensaje correspondiente al estado de la conexión:

  1. if(s.isConnected()){
  2. System.out.println("Conexión establecida con la dirección: " + dirWeb + " a travéz del puerto: " + puerto);
  3. }

Por último vamos a escribir el bloque catch correspondiente al bloque catch que utilizamos arriba, a este bloque lo utilizamos para comunicar el fallo al conectarse en caso que exista tal fallo.

  1.  
  2. }catch(Exception e){
  3. System.err.println("No se pudo establecer conexión con: " + dirWeb + " a travez del puerto: " + puerto);
  4. }

Eso es todo, como ven es muy simple. Espero lo encuentren útil en algún momento.

Java » Gráficos de torta y barras con JFreeChart

mayo 31, 2012 por Feffo 1 Comentario Imprimir Imprimir

El otro día veíamos como crear, de una forma sencilla, un gráfico con JFreeChart. Hoy les presento una forma muy fácil para crear y mostrar un gráfico de torta y uno de barras en Java con JFreeChart.

Recordar que lo primero es descargarse las librerías de JFreeChart. Vamos a necesitar las siguientes librerías JFreeChart y JCommon

Una vez que estén importados los respectivos .jar podremos comenzar a ver el código.

Una forma fácil que se me ocurrió para mostrarles el funcionamiento de esta librería fue crear unos 10000 números aleatorios entre 0 y 9 y llevar un registro de cuantas veces apareció cada número. Para esto tenemos el siguiente código:

  1. Random rnd = new Random(System.currentTimeMillis());
  2. // Establece una semilla para el random
  3. int[] array = new int[10];
  4. for (int i = 0; i < 10000; i++)
  5. array[rnd.nextInt(10)]++;

Cada vez que el random da un numero, se aumenta en uno la cantidad de veces que fue dado. Una vez finalizado el algoritmo tenemos un arreglo donde en cada índice se indica cuantas veces surgió ese índice del random.

Luego, procederemos a crear el gráfico de torta en base a nuestro arreglo con JFreeChart. Lo tendremos todo en el método crearGraficoTorta.

  1. private static JPanel crearGraficoTorta(int[] array) {...}

Lo primero será crear un dataset donde vamos a almacenar las distintas 'porciones' de la torta. Es por ello que utilizamos una clase DefaultPieDataSet de JFreeChart.

  1. DefaultPieDataset dataset = new DefaultPieDataset();
  2. for (int i = 0; i < array.length; i++)
  3. dataset.setValue("Valor " + i + ": " + array[i], array[i]);

Utilizamos un bucle for para agregar las 'porciones' a nuestro grafico de torta. El ultimo parametro indica el valor de la torta que ocupa cada porcion.

Luego, en base a este dataset, creamos nuestro gráfico. Utilizamos la factoría de creación de gráficos de JFreeChart, la ChartFactory.

  1. JFreeChart chart = ChartFactory.createPieChart("Repeticion de randoms",
  2. dataset, true, true, true);

Podemos hacer algunas mejoras sobre el propio gráfico con JFreeChart como añadirle un fondo o quitar la leyenda:

  1. chart.setBackgroundPaint(Color.white);
  2. chart.removeLegend();

Finalmente, retornamos un panel que contenga a esa torta.

Ahora, procederemos a crear el gráfico de barras en base a nuestro arreglo.

  1. private static JPanel crearGraficoBarras(int[] array) {...}

Volvemos a crear un dataset donde vamos a almacenar las distintas 'barras'. En este caso es un DefaultCategoryDataSet.

  1. DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  2. String serie = "Numeros";
  3. for (int i = 0; i < array.length; i++)
  4. dataset.addValue(array[i], serie, "" + i);</pre<
  5.  
  6. Vemos que <strong>los valores son añadidos al DataSet con un addValue()</strong>.
  7.  
  8. Una vez completado el dataset, se crea el grafico de barras en base a el.
  9.  
  10. <pre lang="java">JFreeChart chart = ChartFactory.createBarChart("Repeticion de randoms", null,
  11. null, dataset, PlotOrientation.HORIZONTAL, true, true, false);

Para terminar debemos agregar los gráficos a un frame para poder verlos:

  1. JFrame frame = new JFrame("CrearGraficos - LineaDeCodigo");
  2. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  3. frame.setLayout(new GridLayout(2, 1));
  4. frame.add(crearGraficoTorta(array));
  5. frame.add(crearGraficoBarras(array));
  6. frame.pack();
  7. frame.setLocationRelativeTo(null);
  8. frame.setVisible(true);

En este código hemos añadido los gráficos mediante el método .add() del JFrame. Adicionalmente hemos redimensionado el tamaño del frame, al minimo posible con el método .pack() y centrado el frame con .setLocationRelativeTo(null).

Nuestro resultado final para crear gráficos de torta y barras con JFreeChart nos quedará de la siguiente forma:

Una vez que saben como hacer uno de estos gráficos con JFreeChart, el resto (Líneas de Tiempo, Gráficos XY, etc.) son básicamente el mismo procedimiento con algunos detalles con respecto al dataset de cada tipo.

Java » Gráficos en Java con JFreeChart

mayo 30, 2012 por Pablo Ruiz 3 Comentarios Imprimir Imprimir

Mientras tanto hago el análisis de mi proyecto de título me he visto en la necesidad de buscar algunas librerías gráficas para que me faciliten el trabajo en Java, es así que he llegado a JFreeChart, librería para estadísticas gráficas. Hoy por hoy les explicaré lo sencillo que resulta crear un gráfico con JFreeChart.

Lo primero que tenemos que hacer es agregar la librerías de JFreeChart, si no las tenemos, podemos acceder a ellas desde la página de sus programadores.

Principalmente trabajaremos con dos librerías que son jcommon-1.0.16.jar y jfreechart-1.0.13.jar

Las librerías quedarán así en tu proyecto:

Una vez que hayamos agregado las librerías de JFreeChart cremos un proyecto nuevo y agregamos un JFrame. Este JFrame puede servir directamente como un gráfico, pero en éste ejemplo lo he usado para agregar un botón que hará la llamada del gráfico en un nuevo JFrame.

Nos vamos a el JFrame que ya agregamos, y añadimos sobre él un botón, el cual llamará al gráfico. Visualmente debería quedar algo así:

Lo primero será declarar un atributo JFrame dentro de nuestra clase, la cual hemos llamado GraficosJFreeChart:

  1. JFrame frame = new JFrame("Probando JFreeChart");

El constructor de JFreeChart inicializaremos el JFrame, cambiaremos su tamaño y posición en la pantalla:

  1. frame.setSize(500, 270);
  2. frame.setLocationRelativeTo(getRootPane());
  3. this.setLocationRelativeTo(getRootPane());

Cabe destacar que cuando hacemos referencia a "this" estamos haciendo referencia a la ventana de la clase principal en éste caso la primera que agregamos.

La acción de click sobre el botón será la que lance toda la ejecución y carga de los gráficos JFreeChart.

  1. private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {...}

Lo primero que haremos con los gráficos JFreeChart es crear un DataSet, que es dónde vamos a meter los datos que representaremos gráficamente. Para ello utilizamos un DefaultCategoryDataset y añadimos los valores mediante el método .addValue().

  1. DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  2. dataset.addValue(1.0, "Row 1", "Column 1");
  3. dataset.addValue(5.0, "Row 1", "Column 2");
  4. dataset.addValue(3.0, "Row 1", "Column 3");
  5. dataset.addValue(2.0, "Row 2", "Column 1");
  6. dataset.addValue(3.0, "Row 2", "Column 2");
  7. dataset.addValue(2.0, "Row 2", "Column 3");
  8. dataset.addValue(10.0,"Row 3", "Column 4");
  9. dataset.addValue(10.0,"Row 3", "Column 4");

Destaquemos que las llamadas al método addValue() se agregan un valor, un fila y una columna determinada. ¿Estas pensando en una base de datos? Sí, fácilmente podrían salir los datos de una base de datos. Quizás mas adelante lo expliquemos.

Una vez que tenemos el DataSet relleno nos dedicaremos a generar el gráfico. Los gráficos en JFreeChart se generan mediante la factoría CharFactory. En este caso, como queremos crear un gráfico de barras utilizamos el método .createBarChart().

  1. JFreeChart chart = ChartFactory.createBarChart(
  2. "Ejemplo básico para Linea de Codigo",
  3. "Categorías",
  4. "Valores",
  5. dataset,
  6. PlotOrientation.VERTICAL,
  7. true,
  8. true,
  9. true
  10. );

En la creación del gráfico al método createBarChart le pasamos el título, los valores de los textos de los ejes, si queremos que haya leyenda,... y lo más importante el DataSet con los datos.

El gráfico creado hay que mostrarlo. Para mostrar un gráfico en JFreeChart hay que ponerlo en un Panel. Así que creamos un panel con la clase ChartPanel al cual le pasamos como parámetro el gráfico que acabamos de crear. Después mostramos el panel en el JFrame.

  1. ChartPanel chartPanel = new ChartPanel(chart, false);
  2. frame.setContentPane(chartPanel);
  3. frame.setVisible(true);

Ya tenemos nuestro primer gráfico con Java y JFreeChart.

Java » Calcular el número feliz con Java

mayo 5, 2012 por Víctor Cuervo 1 Comentario Imprimir Imprimir

Ayer hablábamos en el grupo de Facebook sobre Java en Español (¿¿Qué todavía no estás apuntado???) sobre el cálculo de el número feliz con Java. Pero, ¿qué es un número feliz? Si seguimos la descripción de la wikipedia sobre el número feliz, este es aquel que, de forma iterativa, en la suma de sus dígitos acaba resultando un 1.

Es decir, para el caso del número 7, que es un número feliz, la secuencia sería la siguiente:

72 = 49
42 + 92 = 97
92 + 72 = 130
12 + 32 + 02 = 10
12 + 02 = 1

Así que nos ponemos manos a la obra para resolver este planteamiento de el número feliz con Java.

Lo primero que vemos es que hay que extraer los dígitos del número. Esto ya lo explicábamos en el artículo Dígitos de un número con Java. Así que es bueno que lo leas en detalle. Si bien, lo que hacemos es utilizar divisiones y el módulo del 10 (división y resto) para ir extrayendo los números del dígito.

  1. public static int[] digitosNumero(int iNumero){
  2.  
  3. // Creamos un array del tamaño del número de dígitos del número
  4. String x = Integer.toString(iNumero);
  5. int[] iNumeros = new int[x.length()];
  6.  
  7. // Método que devuelve los dígitos de un número
  8. int iDigito = 0;
  9. while (iNumero>0){
  10. iNumeros[iDigito] = iNumero%10;
  11. iNumero = iNumero/10;
  12. iDigito++;
  13. }
  14.  
  15. return iNumeros;
  16.  
  17. }

Al final hemos construido un método que dado un entero nos devuelve un array con los dígitos de dicho número.

Lo siguiente será, por cada dígito del número hacer la suma de los cuadrados de los dígitos. Para calcular los cuadrados utilizamos el método .pow() de la clase Math.

Recuerda que la clase Math es estática y no hace falta instanciarla.

El código de esta suma de dígitos al cuadrado sería:

  1. int[] iNumeros = digitosNumero(iNumero);
  2. iSuma = 0;
  3. for (int x=0;x<iNumeros.length;x++)
  4. iSuma += Math.pow(iNumeros[x],2);

Ahora hay que validar si la suma es un uno o si no saldremos del bucle. En el caso de que no sea un uno volvemos a llamar a la función digitosNumero para que nos vuelva a "trocear" el nuevo número.

  1. while (iSuma!=1){
  2. iSuma = 0;
  3.  
  4. for (int x=0;x<iNumeros.length;x++)
  5. iSuma += Math.pow(iNumeros[x],2);
  6.  
  7. iNumeros = digitosNumero(iSuma);
  8. }

Con esto ya tendríamos nuestro código que calcule si un número es un número feliz con Java terminado. Pero hay una cosa que se puede mejorar, y es que si el número no es feliz se mete en una secuencia infinita de calculos, ya que nunca encontrará el 1. Si bien, podemos cortar este bucle si se repite un número en la secuencia, ya que volverá a la misma secuencia.

Veamos el caso del número 2:

22 = 4
42 = 16
12 + 62 = 37
32 + 72 = 58
52 + 82 = 89
82 + 92 = 145
12 + 42 + 52 = 42
42 + 22 = 20
22 + 02 = 4

Al llegar al número 4 que ya estaba en la serie, todo se volverá a repetir de forma infinita. Es por ello que en este punto habría que cortar el cálculo.

Para implementar esto lo que hemos hecho es añadir un conjunto, es decir, un Set al programa, al cual vamos metiendo los números, siempre y cuando el número sumado no esté. Ya que si esta significará que la secuencia se vuelve a repetir y hay que salir del bucle.

Instanciamos el Set mediante una clase HashSet.

  1. Set<Integer> iCalculados = new HashSet<Integer>();

Y en mitad del bucle hacemos la comprobación o inserción en el conjunto. Para ello utilizamos los métodos .contains y .add

  1. if (iCalculados.contains(new Integer(iSuma)))
  2. bRepetido = true;
  3. else
  4. iCalculados.add(new Integer(iSuma));

Vemos que aparece una variable bRepetido y es que esta será el flag que utilicemos para salirnos del bucle. Así que finalmente nuestro bucle de cálculo quedará de la siguiente forma:

  1. while ((iSuma!=1) && !(bRepetido)){
  2. iSuma = 0;
  3. for (int x=0;x<iNumeros.length;x++)
  4. iSuma += Math.pow(iNumeros[x],2);
  5. iNumeros = digitosNumero(iSuma);
  6.  
  7. // Controlamos si ha salido un número repetido. Para no entrar en el bucle.
  8. if (iCalculados.contains(new Integer(iSuma)))
  9. bRepetido = true;
  10. else
  11. iCalculados.add(new Integer(iSuma));
  12. }

Ya solo nos quedará imprimir si el número es un número feliz o no. Esto nos lo cuenta la variable bRepetido. :-D

  1. if (bRepetido)
  2. System.out.println(iNumero + " NO es un número feliz");
  3. else
  4. System.out.println(iNumero + " SI es un número feliz");

Java » Listar ficheros ocultos de un directorio con Java

mayo 4, 2012 por Víctor Cuervo 1 Comentario Imprimir Imprimir

Estaba haciendo unas pruebas con ficheros y no había caído en que el directorio con el que estaba trabajando tenía algunos ficheros ocultos que no estaba moviendo. Y me he dicho, porqué no escribir unas pequeñas líneas de código con Java para listar los ficheros ocultos de un directorio. Y es que el programa es muy sencillo.

Te recomiendo que empieces echando un ojo al artículo que explica como listar los ficheros de un directorio con Java. Ya que la base del listado de ficheros está en ese ejemplo.

Lo siguiente será saber que el método que nos dice si un fichero es oculto o no es .isHidden(). Algo que, por otro lado, cabía esperar. Así que listemos los ficheros del directorio.

  1. String sDirectorio = "d:\\test";
  2. File f = new File(sDirectorio);
  3.  
  4. if (f.exists()){
  5. File[] ficheros = f.listFiles();
  6. for (int x=0;x<ficheros.length;x++){
  7. System.out.println(ficheros[x].getName());
  8. }
  9. } else{
  10. System.out.println("No existe ese directorio");
  11. }

Con este código hemos listado todos los ficheros. Si queremos listar los ocultos añadimos el método .isHidden() sobre el objeto File sobre el que estamos iterando.

  1. if (f.exists()){
  2. File[] ficheros = f.listFiles();
  3. for (int x=0;x<ficheros.length;x++){
  4. if (ficheros[x].isHidden())
  5. System.out.println(ficheros[x].getName());
  6. }
  7. } else{
  8. System.out.println("No existe ese directorio");
  9. }

Algo muy sencillo y útil para no dejarnos o encontrar esos ficheros ocultos.

En los siguientes artículos intentaremos hablar de todas las novedades que trae Java SE 7 sobre la gestión de ficheros.

Java » Usando las clases HashSet y HashMap

abril 11, 2012 por Emmanuel Ramos 4 Comentarios Imprimir Imprimir

Antes de iniciar a explicar el codigo, tengo que señalar que tanto la clase HashSet como la clase HashMap tienen una ventaja la cual es, que los valores que se van insertando en la coleccion internamente no tendran un orden especifico, esto se debe a que estas clases realizan un ordenamiento interno mediante el hashcode de el elemento(Objeto), por lo cual no sabremos que elemento traerá.

Esto nos da una ventaja para nosotros que es poder sobrescribir el metodo .hashCode() y .equals() para asi, si tenemos un objeto que tienen sus mismas caracteristicas y mismo hashcode no se agregue a la colección , una de las principales ventajas de este metodo es la rapidez en la insercion de los elemento si tenemos cientos de elementosque agregar, esta coleccion es la indicada para este trabajo.

El algoritmo de busqueda de un elemento en la colecion es el siguiente

  1. Encuentra el elemento (Objeto) mediante el hashcode. Imagínense varios personas en un salon con la misma edad.
  2. Ya que encontro el elemento mediante el hashcode se realiza la comparacion si el objeto es igual mediante el método .equals(). Imaginen que en ese mismo salon se esta buscando a una persona con un nombre y apellido especifico.

Lo primero será definir un objeto de tipo Alumnos.

  1. public class Alumnos {
  2. private int age;
  3. private String name;
  4.  
  5. Alumnos(String name, int age){
  6. this.name = name;
  7. this.age = age;
  8. }
  9. }

Las variables age y name serán las necesarias para que se comparen los objetos y su hashcode.

Lo siguiente que haremos será insertar los objetos Alumnos en un HashSet.

  1. Alumnos person1 = new Alumnos("Juan",18);
  2. Alumnos person2 = new Alumnos("Miguel",25);
  3. Alumnos person3 = new Alumnos("Luis",18);
  4. Alumnos person4 = new Alumnos("Luis",18);
  5.  
  6. HashSet<Alumnos> personas = new HashSet<Alumnos>();
  7. personas.add(person1);
  8. personas.add(person2);
  9. personas.add(person3);
  10. personas.add(person4);

Si verificamos el tamaño del HashSet alumnos veremos que nos devuelve "4", ya que por defecto el HashSet no realiza ninguna comparación.

  1. System.out.println(personas.size());

Ahora agregamos 4 objetos alumno a un HashMap.

  1. Map<Alumnos,String> m = new HashMap<Alumnos,String>();
  2.  
  3. m.put(person1, "valor1");
  4. m.put(person2, "valor2");
  5. m.put(person3, "valor1");
  6. m.put(person4, "mi valor");

El método .size() nos devolvera un tamaño de "4" ya que el HashMap tampoco realiza ninguna comparación. De igual manerá el método .keySet() devuelve todos los elementos del HashMap.

  1. System.out.println(m.keySet());
  2. System.out.println(m.size());

Ahora vamos a cambiar el comportamiento de la clase Alumnos para que al insertarlo en un HashMap o en un HashSet se valide si el elemento insertado ya existe.

Sobrescribimos el método .equals() de tal manera que dos objetos Alumno serán iguales si coinciden sus nombres.

  1. @Override
  2. public boolean equals(Object o) {
  3. if (o instanceof Alumnos) {
  4. Alumnos p = (Alumnos)o;
  5. return this.name.equals(p.name);
  6. } else {
  7. return false;
  8. }
  9. }

De igual manera sobrescribimos el método .hashCode(). Para generar el hascode utilizamos la variable edad y la longitud del String, consiguiendo así un entero.

  1. @Override
  2. public int hashCode() {
  3. return age * this.name.length();
  4. }

Ahora, una vez sobrescritos los métodos .hashCode() y .equals(), si verificamos el tamaño del HashSet alumnos veremos que nos devuelve "3" ya que, si hay un elemento igual, el metodo .add() devolvera false.

  1. Map<Alumnos,String> m = new HashMap<Alumnos,String>();

De igual manera el método .size() sobre el HashMap.keySet() los nombres de 3 alumnos ya que el método .put() habrá devuelto false al insertar objetos iguales.

  1. System.out.println(m.keySet());
  2. System.out.println(m.size());

Una cosa que hay que tener en cuenta es que si se sobreescribe solo uno de sus metodos ya sea .hashCode() o .equals() no tendremos el comportamiento deseado. Hay que sobrescribir los dos.

Java » Como ejecutar un comando del sistema desde Java

abril 9, 2012 por Feffo 14 Comentarios Imprimir Imprimir

Hoy les traigo una forma de poder ejecutar un comando de consola en Java. La clave para ejecutar un comando en Java esta en los métodos exec(String command) y exec(String[] cmdarray).

La diferencia entre estos dos métodos Java es que el primero esta destinado a ejecutar comandos sin argumentos:

  1. try {
  2. String cmd = "halt"; //Comando de apagado en linux
  3. Runtime.getRuntime().exec(cmd);
  4. } catch (IOException ioe) {
  5. System.out.println (ioe);
  6. }

Y el segundo si, solo que deben poner cada 'palabra' en un índice distinto en el arreglo Java:

  1. try {
  2. String [] cmd = {"shutdown","-s","-t", "10"}; //Comando de apagado en windows
  3. Runtime.getRuntime().exec(cmd);
  4. } catch (IOException ioe) {
  5. System.out.println (ioe);
  6. }

Recordar que el comando se va a ejecutar en un proceso Java aparte.

Otra cosa a tener en cuenta es el retorno que brindan estos métodos. Para ello tenemos el objeto de tipo Process.

La clase Process posee algunos métodos interesantes, en especial el metodo public abstract InputStream getInputStream(), ya que con él podemos obtener un Stream para poder leer lo que el comando que ejecutamos escribío en la consola.

  1. Process process = Runtime.getRuntime().exec("lsb_release -a");
  2. InputStream inputstream = process.getInputStream();
  3. BufferedInputStream bufferedinputstream = new BufferedInputStream(inputstream);

En mi caso, obtuve el siguiente texto al leer las lineas del buffer.

Distributor ID:	Ubuntu
Description:	Ubuntu 11.10
Release:	11.10
Codename:	oneiric

Espero que les haya gustado el artículo.

Java » Convertir un número a texto con Java

abril 8, 2012 por Víctor Cuervo 3 Comentarios Imprimir Imprimir

Vamos a ver como construir un método con Java al cual le pasemos un número de tres dígitos: unidades, decenas y centenas y nos lo transforme a texto. Es decir, el 534 nos lo transforme en "quinientos treinta y cuatro", es el proceso de convertir un número a texto con Java.

Lo primero para convertir un número a texto con Java será crear métodos de apoyo. El primer método de apoyo es el que dado una unidad nos la transforma en texto.

  1. public static String unidadEnTexto(int iNumero){
  2. // Método que dado un número me lo devuelve en texto
  3. switch(iNumero){
  4. case 1:
  5. return "uno";
  6. case 2:
  7. return "dos";
  8. case 3:
  9. return "tres";
  10. case 4:
  11. return "cuatro";
  12. case 5:
  13. return "cinco";
  14. case 6:
  15. return "seis";
  16. case 7:
  17. return "siete";
  18. case 8:
  19. return "ocho";
  20. case 9:
  21. return "nueve";
  22. case 0:
  23. return "cero";
  24. default:
  25. return "";
  26. }
  27. }

El siguiente será el de las decenas. Es decir, le pasaremos un número que represente las decenas y nos devolverá el texto. Si le pasamos un 2 nos devolverá "veinte".

  1. public static String decenaEnTexto(int iDecena){
  2. switch (iDecena){
  3. case 1:
  4. return "diez";
  5. case 2:
  6. return "veinte";
  7. case 3:
  8. return "treinta";
  9. case 4:
  10. return "cuarenta";
  11. case 5:
  12. return "cincuenta";
  13. case 6:
  14. return "sesenta";
  15. case 7:
  16. return "setenta";
  17. case 8:
  18. return "ochenta";
  19. case 9:
  20. return "noventa";
  21. default:
  22. return "";
  23. }
  24. }

Todas las decenas las podemos montar con el texto de la decena y el texto de la unidad, añadiendo un "y" en medio. Así 22 sería "veinte y dos". Hay un caso especial a tener en cuenta y este es el de las decenas del diez. Así que para ese caso nos montamos otro método de apoyo.

  1. public static String decenas(int iDecena){
  2. switch (iDecena){
  3. case 11:
  4. return "once";
  5. case 12:
  6. return "doce";
  7. case 13:
  8. return "trece";
  9. case 14:
  10. return "catorce";
  11. case 15:
  12. return "quince";
  13. case 16:
  14. return "dieciseis";
  15. case 17:
  16. return "diecisiete";
  17. case 18:
  18. return "dieciocho";
  19. case 19:
  20. return "diecinueve";
  21. default:
  22. return "";
  23. }
  24. }

Y lo último igual para las centenas. Si bien es verdad que aquí solo se nos devolverá el relativo a los cientos, quinientos y novecientos. Ya que para el testo de centenas lo podemos montar mediante la unidad y añadiendo el sufijo cientos. Así tendremos dos-cientos, tres-cientos,...

  1. public static String centenaEnTexto(int iCentena){
  2. switch (iCentena){
  3. case 1:
  4. return "ciento";
  5. case 5:
  6. return "quinientos";
  7. case 9:
  8. return "novecientos";
  9. default:
  10. return "";
  11. }
  12. }

Ahora solo nos queda desmontar el número e ir llamando a las funciones de apoyo necesarias. Para ir obteniendo por dígitos nos apoyamos en el módulo y división de 10. Ya que el módulo nos deja el dígito y la división el resto del número.

Así, para las unidades sería:

  1. int iUnidad = iNumero%10;
  2. iNumero = iNumero/10;
  3. sTexto = unidadEnTexto(iUnidad);

La conversión de la unidad ha sido sencilla ya que solo hemos tenido que llamar al método unidadEnTexto.

Vamos con las decenas, para obtener la decena el mismo mecanismo que antes.

  1. int iDecena = iNumero%10;
  2. iNumero = iNumero/10;
  3.  
  4. if ((iUnidad==0) && (iDecena>0))
  5. sTexto = decenaEnTexto(iDecena);
  6. else if (iDecena==1)
  7. sTexto = decenas(10+iUnidad);
  8. else if (iDecena > 1)
  9. sTexto = decenaEnTexto(iDecena) + " y " + sTexto;

Aqui tenemos tres casos.

  • Si la unidad era un cero, pedimos la decena y será el texto único.
  • Si la decena empieza por uno, caso especial y por lo tantto llamamos al método de las decenas.
  • Otros casos componemos con la decena y la unidad juntas con un "y".

El último caso, las centenas.

  1. int iCentena = iNumero%10;
  2.  
  3. if ((iCentena!=1) && (iCentena!=5) && (iCentena!=9) && (iCentena!=0))
  4. sTexto = unidadEnTexto(iCentena) + "cientos" + " " + sTexto;
  5. else if ((iCentena==1) || (iCentena==5) || (iCentena==9))
  6. sTexto = centenaEnTexto(iCentena) + " " + sTexto;

En este caso solo hay el dilema del 1, 5 y 9. Así que un if y solucionado. El resto de las centenas las montamos con la unidad en texto más el texto "cientos".

Así, finalmente, hemos dejado en sTexto el resultado de convertir un número a texto con Java

Java » Acceder a un directorio de un FTP con Java

marzo 22, 2012 por Víctor Cuervo 3 Comentarios Imprimir Imprimir

Ya vimos en un ejemplo los pasos que hay que seguir para conectarse a un FTP mediante un programa en Java. Con ese código veíamos como acceder al directorio raíz del FTP. Para ello utilizábamos las librerías Apache Commons.

Ahora vamos a ver cómo podemos acceder con Java a un directorio concreto del FTP para acceder a su información.

Lo primero de todo será conectarnos al FTP. Así que creamos una clase FTPClient.

  1. FTPClient client = new FTPClient();
  2. client.connect(sFTP);
  3. boolean login = client.login(sUser,sPassword);

Los métodos connect() y login() nos permiten establecer la conexión y el login sobre el servidor del FTP.

Una vez conectados al servidor FTP podemos ver el directorio al que estamos conectados mediante el método printWorkingDirectory().

  1. System.out.println(client.printWorkingDirectory());

Ahora pasaremos a cambiar de directorio dentro del servidor. En este caso vamos a apoyarnos en el método changeWorkingDirectory() indicándole el directorio al que queremos cambiar como parámetro.

  1. client.changeWorkingDirectory("\\httpdocs");
  2. System.out.println(client.printWorkingDirectory());

De esta forma y después de acceder al directorio, ya podemos operar sobre él.

Para finalizar nuestro código Java no podemos olvidarnos de desconectarnos del servidor.

  1. client.logout();
  2. client.disconnect();