jueves, junio 28, 2007

Sobre Applets, latencia y bugs

jueves, junio 28, 2007 por Martín

En todas las tecnologías hay bugs. Es natural, ya que se supone que errar es humano. Pero dentro de los bugs, tenemos bugs en minúsculas y BUGS en mayúsculas. Son estos últimos los que pueden echar al traste con el éxito de una tecnología.

La semana pasada me encontré cara a cara con uno de estos últimos. Uno de estos que le pueden sacar los colores a cualquier empresa y que te hacen preguntarte, ¿pero como demonios ha estado este bug sin resolver durante diez años? Porque hay bugs, como en este caso, que realmente influyen en una plataforma, y que silenciosamente pueden estar minando la adopción de la misma contribuyendo en gran parte a que no tenga el éxito que debería tener. Son bugs justo dentro del corazón de la arquitectura.

Pero voy al grano. Imaginaros un Applet. Como muchos sabéis, un Applet se ejecuta en el navegador del usuario. La primera vez que se ejecuta el navegador se descarga todos los recursos necesarios, para que en sucesivas ejecuciones del Applet ya no sea necesario realizar este paso, y sea como lanzar un programa local con el consecuente aumento de rendimiento.

Pero, ¿qué pasa cuando el Applet no encuentra un recurso? Es decir, por ejemplo si utilizamos reflection para cargar una clase con un simple Class.forName("org.foo.Sample"); o cuando buscamos un fichero de propiedades Class.getClassLoader.getResource("test.properties") . Pues en este caso el comportamiento del ClassLoader del Java Plugin (AppletClassLoader) es el siguiente:
  • Intentar cargar el recurso localmente.
  • Si el recurso no está disponible, entonces cargar el recurso remotamente del lugar desde donde se descargó todo el contenido.
  • Si no encuentra nada, simplemente lanzar un ClassNotFoundException.

El problema de este comportamiento, aparentemente normal y que huele a implementación inicial pensando en una carga perezosa de clases, es que cae en una de las falacias de la computación más habituales: asumir que la latencia es cero.

Alguno pensará, "bueno hombre, no es tan grave, total por un par de llamadas remotas que se hagan". El problema, es que no son un par. Swing (y esta es otra), por ejemplo, para todo JavaBean intentará cargar dinámicamente un objeto BeanInfo con el nombre del Bean. Así que por ejemplo si tienes un botón MyJButton, Swing intentará cargar MyJButtonBeanInfo cuando vaya a renderizar el botón. ¡Imaginaros esto para todos los componentes web de tu interfaz! Decenas, o cientos, de llamadas remotas destinadas a finalizar con un 404 porque no será capaz de encontrar esos recursos.

Lo realmente chocante en este bug es que ¿no se daba cuenta la gente de Sun que los Applets están pensados para Internet? Internet, señores, que no intranets. Que en Internet a lo mejor estás haciendo una demo a gente que está a decenas de miles de kilometros de ti y donde la latencia es más de 300 milisegundos en round-trip. Hagamos la cuenta fácil, 300 * 100 = 30 segundos desperdiciados en llamadas 404, y eso asumiendo una latencia bastante optimista. ¿Cómo se puede pretender que una tecnología tenga éxito si ya de antemano la diseñas para el fracaso?

Bueno, la buena noticia al final es que el bug está solucionado. La mala noticia es que lo han solucionado sólo en el JDK 6. Eso sí, en la página del bug podréis ver como afirman que se solucionó en el JDK 5. Pero va a ser que no, y eso que he probado con al menos tres revisiones. (4,6,11)

¿Y cómo se arregla el bug? Claro, porque resulta que en el bug report se han limitado a decir que está solucionado, pero no han hecho explícita la solución. Una idea muy brillante si tenemos en cuenta que estamos hablando de las clases del Java Plugin, que ni siquiera vienen incluidas en el código fuente del JDK cuando te lo descargas. Pues nada, que no me quedó otra que mirar dentro del OpenJDK y ver como lo habían solucionado. Es algo tan simple como añadir el siguiente parámetro al applet:
<param name="codebase_lookup" value="false"/>

¿Complicadísimo verdad? Pues aquí tenéis una de las razones por las que los Applets no han triunfado y que les ha llevado diez años corregir, y eso que mirando el código fuente del JDK estimaría que se trata de un cambio de unas 15 líneas más o menos echando por lo alto.

Pues nada, así está Java en el UI.

P.S. Una cosa que se me olvidaba comentar. Si os pica la curiosidad y queréis investigar el bug, la mejor forma de hacerlo es utilizar un capturador de tráfico web como Charles y un simulador de latencia como Shunra.

comments

0 Respuestas a "Sobre Applets, latencia y bugs"