Archive for December, 2005

Workshops

Aunque algunos me dirán que existen varios en España, la verdad es que no lo tengo tan claro. Quizás existen eventos comerciales que utilizan la palabra Workshop, pero no creo que estemos hablando de lo mismo (aunque alguno ha habido, lo reconozco). Yo hablo de los workshops que tienen lugar en otros países, por ejemplo Estados Unidos, dónde bien una empresa, bien un profesional reconocido, ofrece sesiones de entre 4 horas y 3 días para aprender en profundidad “xxx”.

No es que en Linking Paths lo sepamos todo, ni que yo sea un profesional más reconocido que otros, simplemente la creación de una serie de workshops itinerantes es una idea que hemos barajado en el pasado, y que vuelve recurrentemente al enlazarse con nuestra actividad formativa.

La idea sería alquilar locales con distintas ciudades españolas, con una periodicidad mensual (una ciudad por mes, no un workshop por mes y ciudad) e impartir durante 2-3 días una serie de sesiones o workshops sobre temas más o menos interesantes. Desde el uso correcto de Ant, Hibernate o Java Server Faces, hasta como desarrollar una aplicación web entera con Java, o como hacerlo con Ruby On Rails.

Linking Paths se encargaría de organizarlo desde el punto de vista logístico, así como intentaríamos ir incorporando a profesionales para ayudar a impartirlo. Por ejemplo, que mejor persona para hablar sobre aplicaciones de escritorio con EclipseRCP que Martín Pérez, creador de jLibrary, de Ruby on Rails que Aitor García, una de las primeras personas en ponerlo en producción real en España, o de JSF que Bruno Aranda, miembro de MyFaces. Por citar algunos, y dejando claro que estos tres nombres representan una idea, no que ellos apoyen la idea ni que deseen participar.


Por supuesto para hacer esto se tendrían que tener muchas cosas en cuenta, entre ellas y sobre todo, el interés del público (expresado sobre todo en reservas tramitadas con antelación), pero siempre se puede hacer la prueba.

La verdad es que la falta de tiempo me hace tener dudas de como llevarlo a cabo. Al menos quizás no de la forma pensada originalmente. No sé si se pueden encontrar partners actuando Linking Paths como catalizador, o si simplemente es una idea que me viene a la cabeza porque aún no me he acabado de adaptar a la vida en España.

Calidad de la Información: El efecto dominó

Siguiendo con las ideas sobre herramientas para medir la calidad de la información, hay un efecto curioso que se ve repetido en multitud de foros técnicos (y no tan técnicos). Le llamamos el efecto dominó, y se basa en la filosofía que Goebbels, ministro de propaganda nazi, utilizaba para convencer de sus atrocidades al pueblo:

“Si una mentira se repite las suficientes veces, acaba convirtiéndose en la verdad”



Básicamente consiste en lo siguiente:

Alguien, llamemosle trollA, en determinado momento lanza una sentencia fatídica y solemne en un foro técnico: “X es lento” ¿respecto a qué?, “el lenguaje X no se usa para nada” ¿?, “X no es nada productivo” defíname productividad…etc. Creo que los lectores de este blog tienen claro a qué tipo de sentencias nos referimos. Las motivaciones humanas son demasiado complejas para que nos atrevamos a decir porqué lo hacen: ignorancia, ganas de tocar las gónadas o simplemente que ellos mismos ya están sufriendo el efecto dominó. Generalmente ese tipo de comentarios suelen ser ignorados por miembros del foro, con lo cual no suelen ser rebatidos (por pereza o hartazgo), pero lamentablemente quedan reflejados para la posteridad.
El siguiente paso del efecto dominó es que alguien inexperto en la materia y con poco criterio para separar el grano de la paja, lee ese comentario y sin saber muy bien porqué lo toma como bueno. El tercer paso ya es inevitable, el interfecto postea la misma opinión en el mismo foro o en otros y la bola sigue creciendo imparable. El tópico adquiere categoría de información, y como “aparece muchas veces”, ya es dado por bueno.


Para que todo esto se dé es necesario un caldo de cultivo especial que desgraciadamente es el que existe: hay que opinar aunque no se tenga idea. Hay que opinar por que sí, porque tener opinión “mola” aunque se ignore el tema a tratar. No sé pero creo que las famosas tertulias de radio y televisión han ayudado a que lo importante sea el acto de opinar, ya ni siquiera la opinión en sí.

Las posibles soluciones para parar en cierta forma el efecto dominó pueden ser las valoraciones de otros usuarios a los comentarios, pero ya no tanto la valoración positiva o negativa de “me gusta o no me gusta”, sino un tipo de medida “técnica”, en la que la valoración de expertos en la materia tenga más “peso” que otras. Y que la única forma de ser considerado como experto en la materia sea a lo largo del tiempo, siendo la comunidad que visita esa página la que otorgue ese calificativo por participación en foros, valoraciones “técnicas” positivas de otros miembros. Vamos, la “meritocracia” Hacker.


Existen ya muchos sitios que aplican un esquema parecido, generalmente a través de cinturones de colores a semejanza de las artes marciales, y el símil no me puede parecer mejor: un artista marcial sólo demuestra su nivel a lo largo del tiempo y del entrenamiento y cuando otros artistas marciales de mayor nivel juzgan su trabajo. Así que el futuro “webbot” (que por ahora sólo está en nuestra cabeza ;-)) de medida de la calidad de la información debería tener en cuenta ese parámetro como un indicador de calidad bastante aceptable.

J2ME: Lo que no cuentan los libros ni los tutoriales o Cosas que nunca te dije

Recientemente nos hemos visto sumergidos en el desarrollo de aplicaciones para dispositivos móviles con J2ME, y tras algunos dolores de cabeza hemos salido a flote. Y digo esto porque no esperábamos la cantidad de problemas con los que nos íbamos a encontrar y la escasa documentación de los infinitos bugs que existe en Internet. Como no quiero que al siguiente le pase lo mismo que a mí, que a veces parecía que estaba jugando al http://www.googlewhack.com/, pienso compartir parte de las cosas que he descubierto en algunos posts en el blog. Y digo parte porque me debo a la confidencialidad con el cliente.
Y la primera en la frente.

PORQUE EL con.openInputStream COMO APARECE EN TODOS LOS LIBROS Y TUTORIALES NO FUNCIONA Pues eso, que te compras un libro sobre j2me, lo estudias y tan panchito te pones a crearte tu primer midlet con conexiones a servidor web. Para ello y como aparece en Toooodos los libros y tutoriales te decides a poner:

HttpConnection con = (HttpConnection) Connector.open(url, Connector.READ, true);
con.setRequestMethod(HttpConnection.GET);
InputStream in = con.openInputStream();


Bonito verdad? Pues bien, te vas a encontrar que en GRAN cantidad de móviles NO FUNCIONA. Así de claro y de alto. Y diría que no es simplemente un problema de bugs, sino de la propia especificación MIDP2.0, y me explico:
Lo primero que debes saber es que en algunos libros y/o tutoriales te recomiendan que resulta bonito crear un thread de peticiones por red, para que la pantalla siga respondiendo a los comandos del usuario. Bien, no es que sea bonito, es que es TOTAL Y ABSOLUTAMENTE NECESARIO.

La mayoría de los teléfonos suelen pedir permiso al usuario para usar el “airtime” (o tiempo de conexión por red, y menos mal que lo hacen dadas las tarifas de los operadores ;-)); eso suele suceder cuando realizamos la llamada Connector.open(), osea cuando ya hemos empezado a realizar la petición, o sea el control del programa está en esa llamada NO ATENDIENDO a la pantalla. Con lo cual cuando te pregunte, si no has creado un thread paralelo al thread que atiende los comandos, para las peticiones de red, tu usuario se quedará mirando esta pantalla hasta que se aburra, sin posibilidad de hacer nada más.

¿No es muy buena “experiencia de usuario”, no? ;-)

Usar otro thread para las peticiones de red no es una opción, sino una obligación



Bien pues aprendido esto, cambiamos nuestro código, y las cosas “parece” que empiezan a funcionar ;-):


// En algun lugar de tu midlet
NetRequest request = new NetRequest();
request.start();
...

public class NetRequest extends Thread{
....
HttpConnection con = (HttpConnection) Connector.open(url, Connector.READ, true);
con.setRequestMethod(HttpConnection.GET);
InputStream in = con.openInputStream();


Y digo “parece”, porque efectivamente (si usas un emulador, benditos sean que siguen viviendo en el país del Edén) abres tu conexión, y obtienes el InputStream que querías, y lo puedes usar en que te de la gana. A no ser que seas un blade runner y te decidas a hacer los tests que en Linking Paths hicimos. En un momento dado, desde el emulador (el WTK de Sun), desconectábamos el equipo de la red. Alguno pensará, ¿para qué? Hombre pues teniendo en cuenta la cobertura de los móviles se trata de una situación bastante probable ¿no?; pero es que además como veremos en algunos teléfonos, existen algunos divertidos bugs en su implementación de openInputStream().


Bueno, pues si acertábamos en el momento clave (indicado abajo), EL THREAD DE RED SE QUEDABA BLOQUEADO EN EL MÉTODO openInputStream(), sin saltar ningún tipo de Excepción (ni la IOEXception, ni la OyesQueMeHeQuedadoSinConexionException):

HttpConnection con = (HttpConnection) Connector.open(url, Connector.READ, true);
con.setRequestMethod(HttpConnection.GET);

// Aqui la conexión de red se va a hacer gargaras
InputStream in = con.openInputStream();



Glups!, Se quedaba bloqueado para siempre, jamás de los jamases. ¿Pero y los temporizadores de red que a su bien tuvieron enseñarme en la Escuela de Ingenieros? ¿No saltan? Pues no, NO SALTA NINGÚN TIPO DE TEMPORIZACIÓN DE RED, y eso aunque pongas Connector.open(url, Connector.READ, true). Para ver realmente donde está el problema debemos ir a la especificación MIDP2.0, que en su API, respecto a Connector:


“An optional third parameter is a boolean flag that indicates if the calling code can handle timeout exceptions. If this flag is set, the protocol implementation may throw an InterruptedIOException when it detects a timeout condition. This flag is only a hint to the protocol handler, and it does not guarantee that such exceptions will actually be thrown. If this parameter is not set, no timeout exceptions will be thrown.”

Por resumir: si le dices a un fabricante de móviles que puede hacerlo o no, y que no está obligado, te apuesto lo que quieras a que no lo hará. Y en todos los móviles que lo hemos probado (unos 10) ocurre que NO EXISTEN TEMPORIZADORES DE RED PARA HTTP.

Y aunque la especificación no diga nada sobre este método opnInputStream(), también ocurre lo mismo con inputStream.read(), y si miramos la especificación:
“This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.”
Con lo cual sospechamos que esa actitud blockeante es inherente a los InputStream. Con lo cual tenemos una paradoja muy interesante:

Si se cierra la conexión al abrir o al leer de un InputStream, por cualquier causa, no se lanza ninguna excepción, y como no existen temporizadores, el bloqueo del thread es permanente



Y no es que ocurra con algún móvil arcaico, ocurre en todas las gamas modernas, incluso en el emulador de móviles MIDP2 de Sun (el WTK). Podéis comprobarlo, dando por ejemplo un sleep de varios segundos para que os de tiempo a cerrar la conexión en el momento justo. Ahh, se me olvidaba, si alguien pretende solucionar el bloqueo en el read() llamando antes al método avalaible(), que se olvide. Es un método que siempre devuelve cero ;-) (¿Verdad que te empiezan a gustar los estándares?;-))


Para nuestro cliente hemos encontrado ciertos “work-arounds” para que la aplicación no se quedase parada en ese thread, pero lamentablemente es confidencial. Sólamente comentaré varias cosas:

  • Como el método stop() de los threads ya está deprecado (y no es para nada recomendable), sólamente un thread se puede matar a si mismo. Eso en la práctica se consigue con algún tipo de booleano en el run, que se pone a false cuando se quiere parar la ejecución. Si el thread está en un bucle, podemos parar su ejecución controlando el valor de esa variable. Lamentablemente cuando estamos en plena llamada openInputStream (que en algunos móviles puede tardar varios segundos), no estamos en un bucle, y si se produce el problema ahí, esta técnica no funciona

  • Existen algunos móviles (como el Samsung SGH-D500) que simplemente se bloquean cuando intentas hacer una conexión a url distintas: referencia , Verdad que es divertido? Para esos casos, hemos descubierto que intentando de nuevo las conexiones, el bloqueo del primer thread desaparece, obteniendo ahora dos conexiones, la antiguamente bloqueada y la nueva

  • Llamar a connection.close() desde otro thread paralelo, a veces funciona (haciendo que salte una IOException), y a veces no (Simplemente no pasando nada, y quedando el thread bloqueado)

  • Muchos teléfonos tienen un límite máximo en el número de conexiones y de threads que pueden existir en un momento determinado, así que el problema puede ser aún mayor


  • La verdadera solución vendría porque en la próxima especificación de MIDP, se obligara realmente a los fabricantes a crear temporizadores de red (como es lógico), o que los métodos openInputStream o read realmente recibieran IOEXception, que no lo reciben. Pero la verdad no sé quien está metido en esa especificación, porque este tipo de errores nos dejan perplejos.
    Pues nada, a disfrutar de j2me, y a rezar porque ningún móvil pierda la conexión de red o tengáis que hacer un midlet de red para los Samsung. Eso o contratar a LP para dar solución ;-)



    Close
    E-mail It