h1

Aprende scrum en menos de 10 minutos

9 octubre 2009
Anuncios
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

¿Cuál es la diferencia entre common/lib y shared/lib en Tomcat?

8 octubre 2009

En common/lib están los archivos jar que se por las aplicaciones web y el propio servidor, mientras que en shared/lib tenemos las librerías que son accesibles sólo para las aplicaciones web.

h1

Instalación del tomcat

25 agosto 2009

bin – arranque, cierre, y otros scripts y ejecutables
temp – archivos temporales
conf – archivos XML y los correspondientes DTD para la configuración de apache-tomcat el mas importante es server.xml.
logs – archivos de registro (log) de apache-tomcat.
webapps – directorio que contiene las aplicaciones web
work – almacenamiento temporal de ficheros y directorios

  • Creación de la variable de entorno JAVA_HOME apuntando al directorio del JDK
  • vblentornoParada y arranque del tomcat:
    $CATALINA_HOME/bin/startup = arrancar
    $CATALINA_HOME/bin/shutdown = detener
    Seguidamente abrimos un navegador web y escribimos la URL
    http://{host}:{port}/ = donde {host}{port} representa el hostname y el puerto donde corre apache-tomcat, entonces quedaría http://localhost:8080/.
  • Para poder acceder a las aplicaciones de gestión y administración de apache-tomcat es necesario crear un usuario accediendo al siguiente directorio:    $CATALINA_HOME/conf/tomcat-users.xml
    <?xml version=’1.0′ encoding=’utf-8′?>
    <tomcat-users>
    <role rolename=”tomcat”/>
    <role rolename=”role1″/>
    <role rolename=”manager”/>
    <role rolename=”admin”/>
    <user username=”tomcat” password=”tomcat” roles=”tomcat”/>
  • <user username=”both” password=”tomcat” roles=”tomcat,role1″/>

    <user username=”role1″ password=”tomcat” roles=”role1″/>
    <user username=”TomcatAdmin” password=”tcpass“  roles=”admin,manager”/>

    </tomcat-users>
    Para acceder al manager la url es: localhost:8080/manager/html y para acceder a la administración es: localhost:8080/admin/

bin – arranque, cierre, y otros scripts y ejecutables
temp – archivos temporales
conf – archivos XML y los correspondientes DTD para la configuración de apache-tomcat el mas importante es server.xml.
logs – archivos de registro (log) de apache-tomcat.
webapps – directorio que contiene las aplicaciones web
work – almacenamiento temporal de ficheros y directorios
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”