martes, 10 de julio de 2012

Memory Leaks y Eclipse Memory Analyzer - parte 1

Hola a todos,

Se acercan mis vacaciones, he estado buscando cosas interesantes que contar, ya dije al principio que la idea de este blog era publicar cosas que yo considero "interesantes" y no os engañéis, en la vida de un programador de gestión (por lo menos en la vida de los que yo conozco...), no hay muchos momentos brillantes al año, la verdad es que el trabajo es muy repetitivo, es una pena!!

En fin, este año, lo que llevo de año, tuve un pequeño problema con un pase a producción. Un día (qué recuerdos...) hacemos el típico pase chorra a producción, nada del otro mundo, un par de pequeños cambios, uno más o menos gordo, pero nada de qué preocuparse, además, se había probado correctamente en pre-producción. El caso, se sube a producción, se prueba, todo correcto y hora y media después, llamada mortal !!! "Antonio, el servidor se ha caído...", sudores fríos recorrían mi cuerpo serrano. Bueno, no pasa nada!!! se reinicia y punto (algunos ya estaban moscas con el pase.... jajajajajaja). Una hora después.... "Antonio, se ha vuelto a caer..." vale, esto no es normal, me dije a mi mismo....como hemos hecho un pase, lo echamos para atrás y reiniciando que es gerundio.... :-((((

En estos casos todo el mundo comienza a hacerse preguntas, en estos casos, muchos, en lugar de buscar soluciones, se encargan de confirmar que el error JAMÁS puede ser por su culpa... jajajajajajaja, pero es lo "normal", yo siempre he dicho que me encanta ver la reacción de la gente en una "cagadita" de pase a producción, ves a los que se quitan el marrón de encima, ves a los que se alegran de que la hayas cagado, ves a los que pierden el culo por enviar mails a todo el mundo de que hay un error y no es suyo,  ves a los que parece que el error no tiene nada que ver con ellos, aunque hayan participado activamente en algún cambio del pase y ves a los que sin tener nada que ver, ayudan y a los que tienen que ver con el pase se responsabilizan.... no hay nada como un error gordo en producción, para saber de que tipo de personas estás rodeado (esto es un consejo...).

Como casi siempre, procedimiento estándar, ponemos el .war del pase en el entorno de pre-producción (después de comprobar que producción ya no se caía.... aquí muchos ya respiraron más tranquilos al saber que no era su culpa... jajajajajajaja) y comenzamos a hacer las pruebas otra vez, ¿resultado? todo correcto, esto me da mucha rabia!!!!, a mi me gusta, como a todos, que si algo falla, falle en todos los entornos, no hay nada peor que no poder reproducir un problema!!!, a lo que iba, como estaba claro que era "algo" que pasa en producción y que en integración no somos capaces de hacer, ¿qué puede ser? nos preguntamos, hemos modificado cosas de las reservas y cosas de consulta de usuarios, tiene que ser algo de eso, seguro!! nos decíamos a nosotros mismos.

En este caso, y con la tranquilidad de que el pase no era urgente y ya no se estaba reiniciando el servidor, me pregunté ¿qué ha llenado la memoria? Ah sí!!! el error era que se había llenado la memoria!!! ¿podemos verlo? ¿podemos saber qué había antes de llenarse? ¿podemos saber "algo"?.

Bueno, por suerte para mi, cuando se llena la memoria, el servidor web deja un fichero llamado head.hprof (si está correctamente configurado....) con lo que había en la memoria antes de colapsarse, bueno, un inicio!!!, no está mal!!! (a todo esto mis compañeros comenzaban a comentar los cambios y haciendo subidas controladas a producción para ver si alguno de esos cambios era el que provocaba la saturación de la memoria...sin éxito absoluto...el típico ensayo/error), por lo que ya tenía algo qué investigar. Investigué qué era este fichero, porqué se generaba, miles de páginas de Internet que explicaban el problema y muy pocas la solución, todas hacían referencia al famoso Memory Leaks (fugas de memoria...), el error que parecía ocurría en mi servidor, todas hablando de teorías hermosas, rinbombantes y elegantes de porqué se producen fugas de memoria (porque se programa mal, básicamente!!!!), pero pocas hablando de como se detectan esas fugas de memoria. Aún así, en alguna de ellas (una, la más clara que encontré.....), hablaba de que la única forma para solucionar el problema era ver el famoso fichero generado por el servidor antes de fallar y ahí nos daría una idea de qué es lo que había en la memoria antes de fallar.

Lo malo de los ficheros .hprof es que son tan grandes, como la memoria de servidor, en nuestro caso, tuvimos más suerte porque el fichero sólo es de 2GB (sí yo también flipé con la poca memoria que tenemos en producción!!! pero es lo que hay... jajajajaja), pero bueno, como contaba antes, en una de esas páginas, se hablaba que con el programa Eclipse Memory Analyzer era posible ver el contenido de ese fichero de forma gráfica, navegar entre los datos y hacerse una idea clara sobre el posible error. A todo esto, íbamos de fracaso en fracaso comentando los cambios y subiendo a producción.......

Aquí os dejo (y así me quedé yo el viernes antes de irme a casa...) angustiado por un error que no aparecía y no éramos capaces de reproducir, con un pase que no pude hacer a producción y que comenzó el jueves, con pequeños cambios comentados en el código de lo añadido al pase que seguían produciendo fugas de memoria y con la esperanza de encontrar un manual de como utilizar e interpretar los resultados del EMA el fin de semana para intentar arreglar el problema el lunes. No se a vosotros, pero a mi esta cosas consiguen "picarme", son estas cosas que hacen que llegues a casa y continúes buscando información y ejemplos por internet, y creo que el día que no sea así, debería dejar de programar (un día os contaré mi visión sobre capacidad y actitud en otra entrada....).

El próximo día continuo!!!! chao!!!

miércoles, 11 de mayo de 2011

IBATIS + CLOBS + Memoria Temporal

Antes que nada, un abrazo para toda la gente de Murcia, muchos ánimos!!!!

Estoy que lo tiro!!! una nueva entrada sin apenas dejar pasar un par de días para que dijerais la anterior... jajaja...el caso, un día, mis coleguitas del departamento de DataCenter, vamos, los administradores de la base de datos, me vienen a ver (hace un tiempo ya, hará más de un año.....) y me comentan que han de reiniciar los Tomcats de producción cada 2 horas, porque se llena la memoria temporal y no se libera, realmente, lo que querían decir es que YO, estoy llenando la memoria temporal  y YO no la libero nunca.... jajajajaja.... se llena, se llena, se llena y nunca se libera..... que ¿qué VOY a hacer para arreglarlo? me preguntan.....

Evidentemente no hace falta que os cuente, que hasta ese día, no tenía n.p.i de que estaba llenando la memoria temporal y por supuesto, de que por ese motivo se estuviesen reiniciando los Tomcats.... jajajajaja.... el caso, les pido tiempo para que me dejen buscar por internet el problema ¿y porqué no? también la solución....viva google!!!!!. Tiempo me dieron, no me puedo quejar, cuando pude ponerme a mirar que pasaba, ya había pasado casi un año.... jajajajajaja (son muy pacientes, las cosas como son....), pero es cierto que no podía ponerme antes con ello, lo juro (soy un programador muy ocupado..... y sólo!!!).

Tengo que deciros que esta vez no he encontrado por internet nada en plan copy/paste, pero sí algunas ayudas, sobre todo la de los compañeros de dataCenter, que me indicaron que en oracle, ellos hicieron la consulta, el problema estaba asociado a --> freeTemporary(); que si era capaz de hacer un freeTemporary() desde java, asunto resuelto...... en un principio, yo no era capaz de hacer ese freeTemporary() desde java, porque se supone que esto lo tenía que hacer IBATIS. Yo trabajo con IBATIS como framework de persistencia contra la base de datos, además, los procesos "gordos" devuelven la información en CLOBs, no puedo trabajar con String porque mis mensajes son enormes y superan en base de datos los 4000 caracteres (no es una limitación de Java, es de base de datos...). IBatis, se supone que debería ayudarme a trabajar con el CLOB, y lo hace, pero tiene/tenía un problema, no liberaba la memoria temporal. ¿qué solución se propone?, una muy sencilla y una muy a mano.... jajajajajaja, crear tu propio manejador de CLOBS. Vale, yo aquí, ya me había hecho caquita encima!!!! ¿como? mi propio manejador? me preguntaba a mi mismo, uffffffffffffff, madre mía!!! esto no lo hago yo en mi vida!!! (esto me lo decía para mis adentros, jamás lo comenté con nadie...jajajajajaja). Pues después de buscar por internet, ver unas 200 páginas webs y 4.500 foros..... lo encontré!!!!!! no, no encontré la solución, pero sí lo que tenía que hacer (ahora lo explico) y como este foro es para compartir este tipo de cosas, no tenía más remedio que publicarlo. Básicamente se trata de "sustituir" lo que hace IBATIS por defecto, por lo que tu le dices a IBATIS que haga, un ejemplo muy sencillo, tu puedes trabajar con boolean, IBATIS siempre devolverá true/false, imagina que a ti te molesta eso y tu quieres que el boolean devuelva 0/1 o verdadero/falso, ¿vale? pues te creas tu propio manejador de boolean y cambias el código para que al devolver true, tu lo cambias por lo que quieras, igual con el false.... no sé si me explico..... para mi ejemplo es "igual", pero en mi caso, no cambio el valor, sino que además de hacer lo que ya hace, además, libero la memoria. Para hacer esto:

En mi ficherito sql-map-config.xml añadimos estas dos líneas (aquí especificamos que para manejar los CLOB lo haga con mi clase....)

<typeAlias alias="OracleDateHandler" type="com.riu.rumbonet.common.utils.ClobTypeHandlerCallback"/>
<typeHandler callback="OracleDateHandler" jdbcType="CLOB" javaType="java.lang.String"/>

y la clase que tuve que crear.....

import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.sql.Types;

import oracle.sql.CLOB;

import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;

public class ClobTypeHandlerCallback implements TypeHandlerCallback {
       
        public Object getResult(ResultGetter getter) throws SQLException {
               
                CLOB clob = (CLOB) getter.getClob();

                Reader reader = null;
                StringBuffer result = new StringBuffer(1000);

                try {
       
                        reader = clob.getCharacterStream();
       
                        char[] buffer = new char[clob.getBufferSize()];
                        int read = 0;
                        int buffLen = buffer.length;
       
                        while((read = reader.read(buffer, 0, buffLen)) > 0 ) {
                        result.append(buffer, 0, read);
                        }

                        clob.freeTemporary();
                       
                } catch (IOException e1) {
                        throw new SQLException("Fallo al leer CLOB: " + e1.getMessage());
                } finally {
                        if (reader != null) {
                                try {
                                reader.close();
                                } catch (IOException ignore) {}
                        }
                }

                return result.toString

        }

        public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
       
                String str = parameter.toString();
                if (str != null) {
                 setter.setString(str);
                }else{
                        setter.setNull(Types.CLOB);
                }

                //System.out.println("CLOBTypeHandlerCallback: " + (parameter != null ? parameter.getClass() : null));

        }

        public Object valueOf(String s) {
                return s;
        }

}


Lo más importante es esta función --->clob.freeTemporary();


Para poder ver en base de datos lo que os digo, apuntad esta consulta.
SELECT A.BLOCKS,A.*
FROM V$SORT_USAGE A,V$SESSION B
WHERE B.SADDR =A.SESSION_ADDR

Creo que no me dejo nada, después de subir a producción este cambio y hacer pruebas, ya no hace falta reiniciar los Tomcats en producción. Yuhuuuuuuu!!! un pequeño pasito más en la aplicación!!!! de eso se trata este trabajo, pequeños cambios que significan mucho.

Espero no haberos aburrido, y gracias por estar ahí.

Besos,

lunes, 9 de mayo de 2011

Una aplicación, dos bases de datos. Viajes a las entrañas de mi proyecto (Tercera Parte)

Hola a todos. Seguro que muchos de vosotros no habíais podido dormir hasta hoy!!! lo sé, he tardado mucho en desvelar el misterio, pero como ocurre en la vida real, lo bueno se hace esperar..... y tomando prestadas dos frases que no son ni mucho menos mías (son del que mea colonia....) ¿quién es el puto jefe? ¿quién es el puto amo?, pues no, no es Mourinho, soy yo...ajajajajajajajajaja. El experimento de una aplicación y dos bases de datos, perfecto y a la primera.

Os lo digo en serio, estas son las típicas cosas por las que mola trabajar como programador, una mejora de rendimiento en las consultas de disponibilidad del 50% y en definitiva un pequeño cambio que hace que todo vaya un poquito mejor cada día. Por eso amo este trabajo, por estas pequeñas cosas, poco a poco se pulen las aplicaciones, poco a poco se añaden correcciones y cada vez más nos vamos acercando a la cuadratura de círculo. Estoy especialmente orgulloso de haber hecho este pequeño cambio y más orgulloso aún de que haya significado un ahorro de rendimiento tan grande, pensareis que es una tontería, pero este pequeño cambio hace que en lugar de comprar más máquina, no haya que hacerlo y eso, que parece una "chorrada" es muy importante en una empresa.

Los cambios han sido "sencillos":
1. Modificar el fichero context.xml del tomcat para añadir un nuevo Resource, el que ya existía apuntando a la base de datos que ya existía y se ha de crear un nuevo Resource apuntando a la base de datos nueva.
2. En el fichero web.xml de nuestra aplicación, además del resource-ref que ya existe, hemos añadido un nuevo resource-ref, no hace falta decir que cada resource-ref utiliza uno de los definidos en el contex.xml.
3. En mi fichero application-context-datasource, hemos tenido que crear el "dataSource2" apuntando al resource-ref nuevo.
4. En mi fichero application-context-common, hemos creado un "sqlMapClient2" que estaba asociado al "dataSource2" y además le hemos dicho a este "sqlMapClient2" que trabaje con el fichero de consultas de la aplicación (tenemos un fichero de consultas por cada módulo).
5. Luego, en el código, únicamente hay que decirle si utilizar un sqlMapClient u otro en función del Dao que se usa.

No os quiero aburrir, pero si alguien quiere datos más concretos, que me envíe un mail y yo le indico lo que quiera encantado, pero vamos, que no voy a contarle más cosas, que lo que está ya en internet. Pero si no le basta o lo quiere más masticadito, ya sabéis donde encontrarme.

En fin, no os aburro más, a los que habéis leído las dos partes anteriores gracias, a los que no, hacedlo por favor.... jajajajaja

lunes, 28 de febrero de 2011

Los logs de la aplicación

Todos los programadores, antes o después, necesitamos registrar lo que pasa en nuestras aplicaciones, necesitamos conocer por donde pasan nuestros programas, con qué valores han ejecutado las funciones nuestros usuarios, etc, etc... En la aplicación con la que trabajo hacemos esto con Log4j, en este post no voy a explicar que es y que deja de ser Log4j, eso lo podeis ver aquí, en este post os voy a explicar algo que he tenido que buscar estos días porque una mala configuración de Log4j puede afectar al rendimiento de la aplicación.

En mi último pase, el pase a producción que tanto os he mencionado en mis dos últimos post, lo tenía todo listo, todo listo!!! lo prometo, pero ¿qué se me olvidó?, configurar correctamente Log4j para que los mensajes en nuestro log sólo mostrase los mensajes de tipo FATAL y dejé los logs a DEBUG.... casi nada!!! esto, que se soluciona cambiando el log4j.properties, no tiene mucha más implicación, pero resulta que dejar los logs "abiertos" en el entorno de producción, afecta de manera sobresaliente al rendimiento de la aplicación. La gente de sistemas se dió cuenta del problema, modificó el fichero Log4j, reinició la aplicación y 10 min. la web estaba funcionando como siempre. No todo el mundo se dió cuenta de esta pérdida de funcionalidad, pero a las dos horas, para que veais como afecta, llegó un momento en que devolvíamos mensajes de "conecction time out". Sólo por escribir logs!!!! flipante!!!!

Lo dicho, corregimos el log4j en producción y en caliente (Gracias, gente de sistemas..... qué haría yo sin vosotros!!!!) y bueno, me didiqué a buscar como afectan los logs, como afecta Log4j a una aplicación en función de rendimiento.... sí, ya sé, ¿como es posible que un programador utilice Log4j y no haya mirado esto? pues muy sencillo, yo entré a trabajar en mi empresa, me dijeron, mira, aquí para los logs lo hacemos así, y así se ha quedado hasta hoy, vamos, que no hemos tenido necesidad de hacer más y hasta hoy no he tenido la curiosidad de saber como afecta al rendimiento Log4j.... vamos, que hasta ahora he funcionado a base de actos de fé ..." en desarrollo DEBUG, en producción FATAL" y así hemos vivido durante muuuuuuuchoooooo tiempo. En fin, que me pongo a buscar y ahí va lo que he visto:

1. Dejar el modo DEBUG sólo para desarrollo.....ajajajajajajajajaja

2. Es recomendable consultar si el nivel del log está activo con --> logger.isDebugEnabled(), logger.isInfoEnabled(), etc, etc..

3. El peso de añadir una traza dentro del programa ralentiza su ejecución entre 5 y 50 nanosegundos mínimo.

Yo creo que era este último..... me da que era este...... jajajajajaja, en serio, en el modo DEBUG, además de los logs que yo pongo, los que se muestran por IBATIS, ACEGI, etc, etc, para cada mensaje que nos llega en desarrollo imprimimos miles de mensajes y eso es lo que hace el restraso y a mayor número de peticiones un colapso en los servidores. En fin, espero que como yo, hayais descubierto algo más....Por cierto, una adelanto, el pase del otro día, excepto por esto de lo logs, perfecto!!!. Esta semana ponemos en marcha la nueva base de datos y según vaya el tema os cuento.

martes, 22 de febrero de 2011

Una aplicación, dos bases de datos. Viajes a las entrañas de mi proyecto (Segunda Parte)

Para todos los que estabais expectantes.... que seguro que erais muchos!!!!!!..... jajajajajajajajaja, es broma, que sepais que a mi vuelta de vacaciones, los compañeros han probado los cambios que dejé en nuestro entorno de integración (pre-producción) y todo ha ido bien.... ufffffff (sudores fríos he tenido en mis vacaciones a la nieve...).

¿Como puede ser? (os estaréis preguntando) un pase tan importante ¿y tu te has ido a la nieve? sí, yo soy así!!!!, un día os contaré una historia titulada "Desidia, un cáncer a erradicar".....jajajajajajajajaja, el caso, que los compañeros lo han probado y aparentemente todo ha ido bien......yuhuuuuuuuuuuuuuuuuuu!!!!!
Claro que si tenemos en cuenta el dicho de uno de mis profesores de informática "Si una aplicación se sube a producción y no falla, es que no la han probado, si se sube a producción, la han probado y no falla, es que la han probado mal".....jajajajajajajaja. Continúo, el caso, que mañana subimos a las 8 de la mañana a producción.... emoción, intriga, dolor de barriga!!!! si en los próximos días va todo bien, os redacto la última entrada sobre este tema ¿y si va mal? (os preguntareis de nuevo....) no puede ir mal, pero cuando digo que no puede, es que literalmente, no puede ir mal.... es decir, o me cubro de gloria o me cubro de mi##da hasta arriba y me quedo en  el trabajo hasta que vaya bien.... por lo que seguramente os escribiré que antes o después fue todo bien todo.... esperemos que sea más "antes" que "después".

¿Dormiré esta noche? (esto me lo pregunto yo....) hoy sí, seguro, mañana....... ya veremos!!!!!

sábado, 12 de febrero de 2011

Una aplicación, dos bases de datos. Viajes a las entrañas de mi proyecto (Primera Parte)

Que no haya publicado más cosas hasta hoy, es sencillamente porque intento respetar la idea básica de este blog, que es una y muy sencilla, publicar únicamente cosas que creo me han sido útiles en mi trabajo, en mi vida "informática" y que quizás les puedan servir a otros compañeros, por eso, como la vida de un programador es programar cada día, en unas ocasiones mejor en otras peor, pero no siempre tenemos la suerte de desarrollar pequeñas joyas de código dignas de compartir o ni siquiera desarrollar, ir a buscar a google pequeñas joyas de código dignas de un buen copy/paste..... pues eso, que no siempre puedo escribir en el blog, porque buena parte de mi trabajo es mantener aplicaciones donde únicamente, al final, se precisan INSERT's, UPDATE's y DELETE's sobre la base de datos....jajajajajajajaja. Pero dos, tres, cuatro veces al año, estás metido en un proyecto nuevo y ahí sí, ahí podemos desarrollar (dentro de unos márgenes) toda nuestra capacidad e imaginación.

Este año, en mi empresa, tenemos muchos proyectos nuevos, cosa que después de unos años muy duros, la verdad es que se agradece, vamos, es como si hubiera entrado un bocanada de aire nuevo en el dpto. de informática. Algunos de estos proyectos son integrar varias pasarelas de pagos, actualizar la versión del sistema de business intelligence (inteligencia de negocio), remodelar el look & feel (lo que pintamos en el navegador....jajajajajajaja pero en el dpto. de Marketing lo llaman así.... jajajajajajajaja) de algunas webs que ya estaban bastante desfasadas, etc, etc, en definitiva, que nos vamos a divertir!!!!!, por supuesto, seguir dando mantenimiento a las aplicaciones que ya existen y de vez en cuando participar de forma intermitente en otros proyectos, que sin ser de mi departamento, le afectan en un 20, 25%.

Unos de esos proyecto de los que no es "mio" pero si que tengo que participar yo (me afecta en un 30% más o menos....jajajajajaja), es el famoso "desdoblamiento de la base de datos". Básicamente la historia comienza así. Me citan para una reunión con unas cuantas personas de la empresa, todas de informática y de distintos departamentos, desarrollo (el mio) y datacenter (sistemas) y en la charla, os la resumo, básicamente se me informa que por un problema de rendimiento, no de ahora, pero sí de futuro rendimiento de la base de datos actual, han decidido replicar cierta información a otra nueva base de datos, y que, yo estaba en esa reunión para darles soluciones a esta propuesta. Para que lo entendáis, la base de datos con la que yo trabajo, es una base de datos que únicamente se utilizaba para meter precios y que a través de nuestro B2B, B2C, Call Center, Integraciones XML y alguna cosas más, se consultaban y se hacían reservas, luego, todas esas reservas "viajaban" a los dos AS400 que teníamos y poco más. El año pasado, dejamos de trabajar con los AS y toda la gestión de la empresa se hace sobre "mi base de datos"....jajajajajajajaja. Como otro de los proyectos en los que estoy metido es el de las integraciones XML y para este proyecto, se espera un gran crecimiento, en base a esas estadísticas de crecimiento, la gente de sistemas dijo que no, que la base de datos actual, no iba a poder soportar la carga y que tendríamos que "desviar" las consultas gordas, las des disponibilidad y precio a otra base de datos y dejar la base de datos actual únicamente para grabar las reservas...... a lo que a mi respecta significa que, mi programa, tendría que consultar disponibilidad en una base de datos y grabar la reserva (si llega a grabarse) en otra, ufffff (sudores fríos.....).

Yo veo dos soluciones, la menos elegante, instalar un nuevo tomcat en el nuevo servidor de la nueva base de datos, desplegar mi aplicación en ese tomcat y nada más, simplemente decir a todos los clientes que a la hora de consultar precios ataquen a la url 1 y para grabar a la url 2..... cutre, pero funcionar, funcionará.... pero  también presento otra más elegante, hacer que mi aplicación, sólo cambiando la configuración, para la consulta de precios se vaya a la base de datos nueva y para el resto de operaciones (login(), grabarReserva(), etc, etc.... ) se mantenga utilizando la que ya existe. Evidentemente yo les comento que aunque mi proyecto trabaja con Spring, Acegi, Ibatis, etc, etc... yo en la vida he tenido necesidad de tocar la configuración de base de datos, sí, aunque no lo creáis, tengo más cosas que hacer en el curro que estar mirando como se configura algo que nunca ha fallado y nunca he tenido necesidad de tocar!!!!....jajajajajaja les pido que me den un tiempo prudencial para ver como está montado el cotarro y ver si soy capaz de conseguir esto, es decir, una aplicación, dos bases de datos!!!!

Hasta hace relativamente poco tiempo, más o menos 2 años, no he tenido la necesidad de saber como como estaba montado mi proyecto, pero por necesidades de la empresa, me he tenido que meter a ello, siempre ayudándome de internet (en mi caso porque estaba más sólo que la una....), más de instinto que lamentablemente inteligencia (un día me gustaría hablar de instinto del programador....ajajajajajajajajaja). Claro, todo es ponerse, pero siempre pasa igual, ¿cuantos compañeros vuestros serían capaces de configurar Hibernate en el proyecto que trabajan? ¿cuantos cambiar la configuración para que acceda a un LDAP? por ejemplo, unos repondréis, todos!!!, tardarán lo que tarden en encontrar un manual en internet.....ajajajajajajaja eso, creo que, por experiencia es medianamente cierto!!!, otros respondereis que ¿para qué? más de la mitad de los programadores de un proyecto no necesitan saber eso... y también teneis parte de razón, pero el caso, que a mi me ha tocado, me ha tocado viajar a la entrañas de mi proyecto.

Termino, no os aburro más, en la segunda parte os explicaré técnicamente lo que he hecho y si al final, después de hacer las pruebas y todo ha funcionado realmente. Espero que esta introducción os haya gustado.Hasta la próxima!!!!

El TFC de María, avanza a pasos agigantados

Todavía no me está permitido escribir nada del proyecto de final de carrera de mi mujer...jajajajaja, me estoy saltando la reglas... jajajajaja, pero bueno, que sepáis (seguro que ahora dormís mucho más tranquilos) que está casi, casi, listo, este proyecto lo lleva más en secreto que el experimento filadelfia...jajajajajjaja. evidentemente le falta documentar, a si que aún corremos el riesgo de que no lo acabe nunca, pero bueno, la programación está en su totalidad y ahora sólo hace falta que se ponga a escribir como una loca.

No os digo nada más porque va a leer esto y necesito seguir viviendo (le da mucha vergüenza que publique cosas en, y cito textualmente "mi estúpido blog".... jajajajajajajajaja)