Archive for the ‘Programación’ Category

h1

Errores comunes en Java

9 octubre 2009

Desde que empecé a programar en Java y aprendiendo de los errores de otros, he visto una serie de errores comunes, sí todos nos equivocamos, somos humanos, y lo más seguro es que de la siguiente lista, más de uno de los errores lo hayamos vivido en nuestras carnes y si estamos empezando en Java, seguro que algún día, nos pase.

1) Olvidar que los índices en Java empiezan en cero

Los arrays y las listas empiezan en cero, si por lo que sea estamos iterando y en nuestro bucle esto no lo tenemos en cuenta, lo más seguro es que nos salte una excepción del tipo: ArrayIndexOutBounds exception.

2) NullPointerException

Uno de los mayores quebraderos de cabeza, acceder a métodos o atributos en una referencia que está nula. Si el objeto no ha sido inicializado o ha sio inicializado a null la llamada al método o acceso a los atributos no será válido.

3) Comparación VS asignación

Este error puede ser de lógica o de sintaxis, para comparar dos referencias se usa el operador de igualdad que es ==, para asignar un valor a una variable se usa el operador de asignación que es =, donde el valor se pone a la derecha y la variable a asignarle dicho valor a la izquierda.

Si nos equivocamos lo más seguro es que nuestro compilador diga: “Can’t convert xxx to boolean”, dónde xxx es el tipo que se esta asignando en vez de comparar.

4) Comparar objetos con == en vez de con equals

Si usamos el operador ==, lo que estamos comparando son las referencias de los objetos, lo que estamos preguntando es si los dos referencias apuntan al mismo objeto. Para comparar objetos hay que usar el método equals.

h1

Strings en Java

24 agosto 2009

Si tenemos el siguiente código:

public class Warp {
public static void main(String[] args) {
System.out.println("¿Hola cómo estás?");
}
private static final String HOLA = "¿Hola cómo estás?";
private static final Warper warper = new Warper();
}

Si nos preguntan cuál es el resultado de ejecutar este código sabiendo que la clase Wraper no produce ningún resultad. ¿Qué responderías? Si la
respuesta es otra a parte de: “No lo sé, depende de lo que haga Wraper”

En este caso el resultado sería:

C:> java Warp <ENTER>
“Java es sexy”

El código de la clase Wraper:

import java.lang.reflect.*;

public class Warper {
private static Field stringValue;
static {
// String tiene un atributo privado char[] llamado value
try {
stringValue = String.class.getDeclaredField("value");
} catch(NoSuchFieldException ex) {
// Por si la VM tiene un nombre diferente para el atributo
Field[] all = String.class.getDeclaredFields();
for (int i=0; stringValue == null &amp;&amp; i&lt;all.length; i++) {
if (all[i].getType().equals(char[].class)) {
stringValue = all[i];
}
}
}
if (stringValue != null) {
stringValue.setAccessible(true); // Combertir el atributo
}
}
public Warper() {
try {
stringValue.set(
"¿Hola cómo estás?",
"Java es sexy".
toCharArray());
stringValue.set("Adios", "Hola".toCharArray());
} catch(IllegalAccessException ex) {}
}
}

La pregunta ahora es: ¿Cómo es esto posible? ¿Cómo puede manipularse una cadena en una parte distinta del programa? Para entender este caso tenemos mirar
la especificación de java, la cuál dice:

“Each string literal is a reference to an instance of class String. String objects have a constant value. String literals-or, more generally, strings that are the values of constant
expressions-are “interned” so as to share unique instances, using the method String.intern.”

Evidentemente, usaremos menos memoria, si usamos dos Strings que son equivalentes apuntando al mismo objeto. Además, la especificación también dice:

1. Literal strings within the same class in the same package represent references to the same String object.
2. Literal strings within different classes in the same package represent references to the same String object.
3. Literal strings within different classes in different packages likewise represent references to the same String object.
4. Strings computed by constant expressions are computed at compile time and then treated as if they were literals.
5. Strings computed by concatenation at run time are newly created and therefore distinct.

Esto quiere decir, que si una clase de otro paquete juguetea con una cadena “interned” podemos tener un pequeño problema.

El siguiente ejemplo tiene que ver con el HashCode, que por motivos de rendimiento se cachea. Veamos el ejemplo:

public class CachingHashcode {
public static void main(String[] args) {
java.util.Map map = new java.util.HashMap();
map.put("Hola", "Has encontrado el valor");
new Warper();
System.out.println(map.get("Hola"));
System.out.println(map);
}
private static final String greeting = "Hola";
}

En JDK 1.3 el resultado es:

Has encontrado el valor
{Hola !=Has encotrado el valor}

En JDK 1.2 el resultado es:

null
{Hola !=Has encotrado el valor}

Esto ocurre porque en JDL 1.3 el HashCode se cachea, si se calcula una vez, no se recalcula y si cambian los valores de los campos, el HashCode sigue
siendo el mismo.

h1

Vector VS ArrayList

22 agosto 2009

Una duda que siempre me salta: ¿ uso un Vector o un ArrayList? y la respuesta es…..depende, no hay una respuesta fácil, si es lo que búscamos, como siempre en el mundo de la programación la respuesta es DEPENDE.

En este tema en concreto hay que tener en cuenta los siguientes factores:

  • API: Ambas clases son muy parecidas, desde el punto de vista de la API aunque existen algunas diferencia
  • Crecimiento de las listas: Tanto los vectores como los arraylist guardan los datos en un array. Al ir metiendo datos en el array puede llegar el caso que se quede sin sitio para uno más, por lo que hay que incementar el tamaño del array, mientras que el vector dobla su tamaño original, el arraylist lo incrementa en un 50%. Puede darse el caso que suframos un gran impacto de rendimiento si se está cambiando el tamaño continuamente. Por lo que se suele establecer un tamaño inicial lo suficientemente grande, así no sufrimos la penalización de  aumentar el tamaño. En este sentido, los vectores tienen una pequeña ventaja, se le puede indicar el valor del incremento.
  • Patrones de uso:  A la hora de obtener elementos de una posición especifica, o añadir o elminiar elementos al final del array, tanto el vector como el arraylist, tienen un gran rendimiento, pero para cualquier otro caso, es decir, eliminar y añadir elementos de cualquier otro sitio, es menos efecitvo, con lo que es mejor incluso usar otra clase, por ejemplo, LinkedList, aunque este genera un poco más de “basura.”
  • Sincronización: Los vectores están sincronizados, por lo que son “thread safe” , si no necesitamos esta caracteristica, es mejor usar un ArrayList, así no pagamos el precio de la sincronización.
h1

Conceptos: Gestores de portales, contenedor de portlets, portlet

20 agosto 2009
  • Gestor de portales:
    • “Es una aplicación web que normalmente provee de personalización, SSO, gestión de contenido y la capa de presentación a los sistemas de información.”
  • Contenedor de portlets
    • “Un contenedor de portlets ejecuta los portlets y provee del entorno de trabajo que necesitan. Un contenedor de portlets alberga los portlets y gestionan su ciclo de vida.”
    • “Un contenedor de portlets recibe las peticiones de los portales y las ejecuta en los portlets que contiene.”
  • Portlet
    • “Es un componente web en java que es gestionado por un contenedor de portelts que procesa las peticiones y genera contenido dinámico. Los portlets se usan como plugins para los gestores de portales aportando una interfaz de usuario a la capa de presentación a los sistemas de información”
h1

Portlet Taglibs

11 agosto 2009

Los taglibs disponibles para el JSR-168 son:

  • defineObjects: Define las variables para acceder a los objetos del portlet, tales como el RenderRequest y RenderResponse.
  • actionUrl: Dispara un actionRequest con los parámetros que se indiquen.

<portlet:actionURL windowState=”maximized” portletMode=”edit”>
<portlet:param name=”action” value=”editStocks”>
</portlet:actionURL>

  • renderURL: Dispara un renderRequest con los parámetros que se indiquen.
  • Param: Indica los parámetros de los actionRequest y renderRequest.
  • NameSpace:  Asocia un nombre único al portlet, evitando conflictos con otros elementos del portal.
    <script>
    function <portlet:namespace />myFunction() {
    alert(“<portlet:namespace />myButton was clicked” );
    }
    </script> <input type=”button” id=”<portlet:namespace />myButton“    onclick=”<portlet:namespace />myFunction();”>
  • Inclusión:
    <%@ taglib uri=”http://java.sun.com/portlet&#8221; prefix=”portlet” %>
ndefineObjects
üDefine las variables para acceder a los objetos del portlet, tales como el RenderRequest y RenderResponse.
nactionUrl
üDispara un actionRequest con los parámetros que se indiquen.

<portlet:actionURL windowState=”maximizedportletMode=”edit“>

<portlet:param name=”actionvalue=”editStocks“>

</portlet:actionURL>

nrenderURL
üDispara un renderRequest con los parámetros que se indiquen.
nParam

Indica los parámetros de los actionRequest y renderRequest.

h1

Generador Seam

4 abril 2009

Me ha tocado uno de esos proyectos guapos que primero te dicen que va a ser una tecnología, después otra y al final, te toca una que no conoces y te das cuenta de que te han “enmaronao”. En esta ocasión se trata de una aplicación en JBoss Seam, después de dar unas cuantas vueltas he visto que JBoss Seam tiene el cual te genera el esqueleto de la aplicación y si tienes la base de datos creada, te permite usar ingeniería inversa para la creación de las clases. A continucación explicaré brevemente como se usa esta herramienta. El código generado te vale tanto para eclise como para netbeans.

Para empezar debemos descargarnos la última versión de JBoss seam, actualmente es la 2.1.1.GA y lo descomprimimos en el directorio que deseemos. Entonces ejecutamos las siguientes sentencias:

[JBOSS_SEAM_HOME]\seam setup

Entonces aparecerá por pantalla un mensaje y empezará a realizar algunas preguntas de configuración:

Buildfile: C:\Projects\jboss-seam\seam-gen\build.xml

setup:
    [echo] Welcome to seam-gen 🙂
    [input] Enter your Java project workspace [C:/Projects]
    Introduce tu directorio de proyectos (workspace)

    [input] Enter your JBoss home directory [C:/Program Files/jboss-4.0.5.GA]
    Introduce el directorio en el que se encuentra JBoss

    [input] Enter the project name [myproject]
    Introduce el nombre del proyecto
helloworld
    [input] Is this project deployed as an EAR (with EJB components) or a WAR (with no EJB support) [ear] (ear,war,)
    Quieres que el archivo de despliegue sea un war o un ear

    [input] Enter the Java package name for your session beans [com.mydomain.helloworld] 
    Introduce el nombre del paquete para los beans de session
org.jboss.helloworld
    [input] Enter the Java package name for your entity beans [org.jboss.helloworld]
    Introduce el nombre del paquete para los beans de las entidades
    [input] Enter the Java package name for your test cases [org.jboss.helloworld.test] 
    Introduce el nombre de paquete para los tests

    [input] What kind of database are you using? [hsql] (hsql,mysql,oracle,postgres,mssql,db2,sybase,)
   ¿Qué tipo de base de datos vas a usar?
mysql
    [input] Enter the Hibernate dialect for your database [org.hibernate.dialect.MySQLDialect]
    Introduce el dialecto de la base de datos

    [input] Enter the filesystem path to the JDBC driver jar [lib/hsqldb.jar] 
    Introducela ruta al driver JDBC
../../mysql-connector.jar
    [input] Enter JDBC driver class for your database [com.mysql.jdbc.Driver]
    Introduce el nombre de la clase del driver JDBC

    [input] Enter the JDBC URL for your database [jdbc:mysql:///test] 
    Introduce la URL de la base de datos

    [input] Enter database username [sa] 
    Introduce el usuario de la base de datos
gavin
    [input] Enter database password [] 
    Introduce la clave de la base de datos

    [input] Are you working with tables that already exist in the database? [n] (y,n,)
    ¿Estás trabajando con tablas que ya existen en la base de datos?
y
    [input] Do you want to drop and recreate the database tables and data in import.sql each time you deploy? [n] (y,n,) 
    ¿Quieres que se creen las tablas cada vez que se ejecute el war?
n
[propertyfile] Creating new property file: C:\Projects\jboss-seam\seam-gen\build.properties
     [echo] Installing JDBC driver jar to JBoss server
     [echo] Type 'seam new-project' to create the new project

BUILD SUCCESSFUL
Total time: 1 minute 17 seconds

A continuación pasamos a crear el proyecto en nuestro workspace:
[JBOSS_SEAM_HOME]\seam new-project

Cuando finalice el proceso nos saldrá un mensaje confirmando que se ha creado el proyecto con existo. Finalmente, si tenemos la base de datos ya creada, pasaremos a
usar la ingenieria inversa para crear los pojos y los dao.

[JBOSS_SEAM_HOME]\seam generate-entities

Al igual que antes nos mostrará por pantalla el log, indicanco al final si todo ha ido bien.

Para terminar importamos el proyecto al eclipse o a netbeans y c´est fini.

Espero que os sirva de ayuda.
h1

jQuery´s interesantes I

24 marzo 2009

Hoy haciendo una aplicación de gestión, dónde se realizaba un crud, hice la típica función confirm de javascript y pensé, seguro que hay algo
que quede mucho mejor que enriquezca la experiencia de un usuario. Me puse a buscar y encontré un plugin de jQuery que proporcionaba
una forma configurable para mostrar los alerts, confirmaciones y demás que todos hemos usado en nuestras aplicaciones.

Gracias a este plugin podemos sustituir la funcionalidad proporcionada por las funciones:  alert(), confirm() y prompt(). De esta forma podemos personaliar
mediante css los mensajes y podiendo establecer un título personalizado para cada cuadro de diálogo. Dichos cuadros simulan un cuadro de diálogo modal, el cual
se posiciona en función del tamañó del navegador.

De momento tiene algunos fallos que son:

1) No se puede presionar intro o escape para aceptar o cancelar una acción.
2) El plugin de drag&drop no funciona en Opera
3) IE6 se conforma de forma diferente, ya que no soporta: postion : fixed

Ver la demo: página de la demo