Archivo de la etiqueta: Error

Incidencias de class loader

En el lenguaje de programación Java, para identificar una clase especifica se tienen en cuenta principalmente 2 cosas: El nombre del package en el que se encuentra y el propio nombre de la clase. Mediante estos 2 valores, el sistema de class loaders de la máquina virtual identifica y carga la diferentes clases según sean necesarias durante la ejecución de una aplicación. Este mecanismo tiene un problema bastante conocido cuando más de una clase con el mismo nombre y package se encuentran contenidas en ficheros jar o directorios diferentes. Este fenómeno es una de las variantes del denominado Jar Hell que en este caso concreto consiste en que no todas las clases pertenecientes al mismo package que son cargadas por el sistema de class loaders proceden de la misma ubicación (directorio de clases o fichero jar), lo que puede ocasionar incompatibilidades o errores inesperados si estas no pertenecen a la misma versión de código.

La especificación de Java define un mecanismo denominado package sealing que puede aplicarse opcionalmente para garantizar que todas las clases pertenecientes a un mismo package son cargadas desde el mismo fichero jar. En caso de que la máquina virtual en un momento determinado intente cargar una clase de un package definido como sellado y esta pertenezca a un fichero jar distinto al del resto de clases del mismo package ya cargadas, se producirá un error advirtiendo de ello. Desafortunadamente, no todas las librerías hacen uso de este mecanismo, por lo que a veces es complicado ver si esta puede ser la causa de un error determinado.

En este artículo se exponen diferentes casuísticas derivadas de este fenómeno y de como identificar la causa de un error de este tipo para poder solucionarlo.

Seguir leyendo Incidencias de class loader

NoClassDefFoundError en la inicialización de una clase Java

Los bloques de código estático en el lenguaje de programación Java són un mecanismo de inicialización de los recursos estáticos de una clase
que se ejecuta en el momento en que se interactua con dicha clase por primera vez. Un fallo producido dentro de dichos bloques estáticos puede provocar
errores inesperados en la ejecución del programa. En este post se habla de una de la posibles consecuencias de un error de este tipo y de cómo puede
ser identificado.

Seguir leyendo NoClassDefFoundError en la inicialización de una clase Java

Error NullPointerException al evaluar una expresión ternaria

Descripción de error

Se produce un error de tipo NullPointerException al evaluar una expresión ternaria donde se mezclan valores de tipo primitivo (int, long, double…) con sus correspondientes tipos Wrapper (Integer, Long, Double) si el valor de resultante de la expresión es null.

Cuando la expresión condicional evalua y se asigna un valor no nulo, en este caso el segundo operando de la expresión, la operación funciona correctamente:

long val1 = 1;
		
Long valor2 = val1==1 ? val1 : (Long)null;
System.out.println("VALOR2 is null -> " + (valor2 != null));

VALOR2 is null -> true

En cambio, cuando se evalúa la condición y el valor resultante es null, tercer operando en el ejemplo, aunque este último se trate como un tipo objeto, se produce un error:

long val1 = 2;

Long valor2 = val1==1 ? val1 : (Long)null;
System.out.println("VALOR2 is null -> " + (valor2 != null));

Exception in thread "main" java.lang.NullPointerException

Solución propuesta

El error se produce porque en las expresiones ternarias de este tipo, el compilador escoge como tipo de retorno el valor primitivo, en el caso de los ejemplos anteriores el tipo long en lugar del tipo wrapper Long. Por esta razón, aunque se especifique una conversión explicita al tipo adecuado cuando se utiliza un valor nulo, siempre se producirá un error si ese es el resultado de la operación ya que el tipo primitivo no admite este tipo de valores.

La solución simple a este error es trasformar en todos los casos el valor resultante a un tipo wrapper. En el ejemplo, el segundo miembro de la operación es transformado a Long mediante el método valueOf para que todos los operandos sean de este tipo, que si admite valores nulos. El compilador escogerá este tipo para el resultado de la operación ya que es el único presente en las 2 alternativas, tanto si se cumple la condición como si no.

long val1 = 2;
		
Long valor2 = val1==1 ? Long.valueOf(val1) : (Long)null;
System.out.println("VALOR2 is null -> " + (valor2 != null));

VALOR2 is null -> false

 

Referencias

Error al tratar un dato de tipo CLOB con Hibernate en una base de datos PostgreSQL

Descripción de error

Se produce un error al recuperar datos de tipo LOB de una entidad a través de la capa de persistencia basada en JPA Hibernate si la base de datos subyacente es PostgreSQLSe produce un error de tipo:

org.postgresql.util.PSQLException: Bad value for type long

La configuración de los campos de una entidad incialmente es la siguiente:

@Basic(fetch=FetchType.LAZY)
@Lob
protected String stringLargeValue;

Entorno

  • JDK: 1.6. Es posible que ocurra también en versiones posteriores (No probado)
  • Framework de persistencia: JPA con Hibernate 3.6. No se ha probado con la versión 4 ni posteriores.
  • Base de datos: PostgreSQL 9.2.4, Es posible que ocurra también en versiones posteriores (No probado)

Solución propuesta

Parece ser que hay una falta de entendimiento entre Hibernate 3.6 y el driver de PostgreSQL porque lo que uno entiende como dato (Hibernate) el otro lo entiende como el puntero de tipo long para acceder a este (PostgreSQL) por lo que al hacer la extracción de datos este intenta hacer una conversión y provoca el error. Una posible solución se basa en configurar la propiedad de tipo LOB de la entidad con la anotación @Type de la siguiente manera para indicarle a Hibernate como debe tratar el valor recuperado:

@Basic(fetch=FetchType.LAZY)
@Lob
@Type(type="org.hibernate.type.TextType")
protected String stringLargeValue;