Archivos del sitio
Serialicefa (Customiza tu Serializacion)
Segunda parte de Maldita Serializacion, la serie(lizacion) que causa sensa(liza)cion.
Como todos sabreis, no todos los objetos son serializables. Las instancias de Object, por ejemplo no son serializables. Y tampoco lo son los Thread, o los Socket.
Tambien sabreis todos que para Serializar un objeto que implemente una instancia de alguna clase no serializable, esta debe estar marcada como transient.
Lo que quizas no sea tan obvio es como sacar partido a lo explicado mi post anterior sobre serializacion. Como customizar nuestra serializacion, para que por ejemplo se rearranque un Thread al restaurar el objeto persistido.
El uso de writeObject y readObject como vimos anteriormente sobreescriben los comportamientos por defecto de la persistencia y restauracion de objetos por serializacion:
//Persistencia
//Dentro de try-catch
fos = new FileOutputStream(nombrefichero);
out = new ObjectOutputStream(fos);
out.writeObject(foo);
out.close();
//[...]
//Restuaracion
//Dentro de try-catch
fis = new FileInputStream(nombrefichero);
in = new ObjectInputStream(fis);
Foo foo = (Foo)in.readObject();
in.close();
Asi podemos hacer q nuestro foo al ser restaurado re-arranque determinado Thread:
private transient Thread t=new Thread(){
@Override
public void run() {
//Por ejemplo
MotorReglas.cache();
}
}
private void writeObject(ObjectOutputStream out) throws IOException{
//Escribe los campos no static ni transient de la clase actual en el stream.
//Debe ser llamado solo desde el metodo writeObject de la clase
//que esta siendo serializada.
//Lanza un NotActiveException si se llama desde otro lugar.
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
//Lee los campos que no son static ni transient
//de la clase actual en el stream.
//Debe ser llamado unicamente desde el metodo readObject
//de la clase que esta siendo deserializada.
//Lanza un NotActiveException si se llama de otra forma.
in.defaultReadObject();
// Aqui restauramos las instancias transitient
t.start();
}
Y por ultimo, para que seais auntenticas criaturas del renacimiento:
http://www.cefatoys.com/web/estaticosvideos/video01.html
Hala pues,
Maldita Serializacion
Lo de la serializacion es eso que usamos en Java para persistir un objeto. Basicamente hacemos que nuestra clase implemente: java.io.Serializable
Pero supongamos que en algun caso queremos que nuestra clase padre sea serializable, se pueda persistir, pero que la persistencia no sea heredada por alguna clase hija? O simplemente que queremos extender una clase existente en alguna libreria, que es serializable, pero no queremos que nuestra nueva clase lo sea.
Como detener la serializacion heredada?
Hay un truco bastante extraño para hacerlo asi:
Tenemos que declarar los metodos:
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
Estos metodos, al ser privados no pueden ser llamados desde fuera, ni ser heredados, ni ser sobreescritos, ni basicamente nada, pero son accesibles para la maquina virtual.
En una clase que implemente Serializable estos metodos, de existir, son llamados por la JVM a la hora de persistir y recuperar el objeto.
Por tanto para detener la serializacion simplemente tenemos que implementar en aquellas clases donde no queremos serializacion esos dos metodos, y lanzar un NotSerializableException.
private void writeObject(ObjectOutputStream out) throws IOException
{
throw new NotSerializableException("Cerrado por vacaciones!");
}
private void readObject(ObjectInputStream in) throws IOException
{
throw new NotSerializableException("Cerrado por vacaciones!");
}
Sencillo pero extraño. Y util, en algunos escenarios.
Hala pues,
Detectar a bajo nivel si un fichero es UTF-8 desde Java
Aunque inicialmente parece una tarea muy sencilla, los que hayan tenido que detectar si un fichero es UTF-8 se habrán dado cuenta que el tema no es ta obvio como parece.
Primero una introducción teórica
Los ficheros se almacenan como arrays de bytes que posteriormente son asociados a caracteres, para hacer esta asociación se utilizan diferentes codificaciones ( ASCII, ISO-8859-1,UTF-8,etc).
Para poder establecer una relación entre su código y cualquier carácter utilizado por cualquier lenguaje del mundo se creo Unicode, que no es mas que una gigantesca asociación código numérico-grafía para permitir su representación informática.
Dentro de este contexto, UTF-8 no es mas que una forma de codificar un texto Unicode para permitir su serialización en ficheros o flujos de datos.
Ya que Unicode intenta asociar códigos a todos los caracteres esenciales, necesitamos mas de un byte para codificarlos, por lo que UTF-8 recurre a una estructura variable de entre 1 a 4 bytes para codificar los diferentes caracteres.
Este tamaño variable es el motivo por el que en ocasiones los ficheros guardados con un formato se ven con caracteres extraños al recuperarlos utilizando la codificación incorrecta.
Aproximación al Algorítmo
El proceso es muy sencillo, basta leer el fichero byte a byte e ir comprobando que todos los bytes cumplen con lo especificado en el estandar UTF-8.
- Si el byte leído es menor que 0111 1111 (0×7F) es un byte válido. En este caso el byte representa un caracter UTF-8 (de 1 byte).
- Si el byte leído coincide con la mascara 110xxxxx, compruebo que el siguiente byte cumple con la mascara 10xxxxxx. En este caso los dos bytes leídos forman el carácter UTF-8.
- De forma similar se pueden detectar si son caracteres de 3 o 4 bytes.
Si en algún momento del procesamiento del fichero, alguna de las condiciones no se cumple, el fichero no es UTF-8, en otro caso tiene una codificación compatible con UTF-8.
Aunque seguro que existen implementaciones mucho mas eficientes en Java, después de algunas búsquedas en Internet no encontré nada, por lo que me lance a programar mi propio validador.
Recorte de código para detectar si un fichero está codificado en UTF-8
Mwahahaha!
[…] podría significar reescribir las leyes de la fisica….
… sí, sí, superinteresante, seguro….
¡Superlaser!
http://www.wired.com/gadgets/miscellaneous/magazine/15-12/st_antimatter
Que gran lugar para …pensar
Sin intención de resultar grosero a las mentes sensibles, quiero hacer una oda al mejor momento de reflexión.
Si te encuentras con un problema insalvable, lo mejor es retirarse a reflexionar…

Un físico teórico muestra sus nuevos resultados a un colega.
Contrariamente al tópico no tuvo la inspiración mientras dormía.
No estoy seguro de que esto se pueda catalogar dentro de la programación en flujo, pero desde luego se acerca mucho.
Tenéis muchos mas dibujos en : http://www.thescientificcartoonist.com
Extraño bug al recuperar una sesión mail desde JNDI en Tomcat 5.5.x
Os cuento un extraño bug con el que me ha tocado pelear hoy, el problema solo afecta a las versiones de Tomcat 5.5.20-5.5.23, pero me ha causado un pequeño quebradero de cabeza.
El problema es que en las versiones afectadas, y debido a un problema en el proceso de empaquetado, la clase org.apache.naming.factory.MailSessionFactory no este disponible en el jar common/lib/naming-factory.jar.
Por este motivo al ejecutar un código que funciona perfectamente en Tomcat 5.5.19 en Tomcat 5.5.23 nos encontramos con la siguiente excepción:
Caused by: java.lang.ClassNotFoundException: org.apache.naming.factory.MailSessionFactory
Referencia concreta al bug es:
http://issues.apache.org/bugzilla/show_bug.cgi?id=40668
Busca esto rápido
Encuentra lo que buscas de forma sencilla usando el buscador.
Categorías
Encuentra artículos a través de sus "tags"
Archivos mensuales
Encuentra artículos según el mes en el que fueron escritos.
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007