Issuu on Google+

Portada SoloP 162:Portada SoloP 162

17/6/08

11:53

Página 1

C IN D CL -R UY OE M

LA PRIMERA REVISTA DE PROGRAMACIÓN EN CASTELLANO

Precio: 6 € (España) (IVA incluido)

DE REGALO Solo Programadores número 160 en formato pdf

AÑO XIV. 2.ª ÉPOCA

• Nº 162 •

UNA PUBLICACIÓN DE:

REVISTAS PROFESIONALES S.L.

Programación con múltiples hilos Vamos a comenzar a generar código y ejemplos concretos para conseguir tener el control de múltiples hilos de ejecución acorde a la cantidad de núcleos de procesamiento disponibles.

JAVAHISPANO Actualidad Java REDES RSS con Java (III) MIDDLEWARE Scrum (II) DISPOSITIVOS MÓVILES J2ME (III) Virus en móviles COMUNIDAD .NET Arrastrar y soltar VÍDEO-TUTORIAL Busca las minas

Noticias, Opinión, Dudas y CD-ROM


03 Editorial 162:03 Editorial 162

Número 162 Edi ta : R EVISTAS PR OF ESIO N AL ES S. L . solop@revistasprofesionales.com C/ Valentin Beato 42, 3ª 28037 - Madrid www.revistasprofesionales.com •••••••••••••••••••••••••••••••••• E d it o r Agustín Buelta •••••••••••••••••••••••••••••••••• Co o rdi n aci ó n Técn i ca -R e da cci ó n Ricardo Álvarez •••••••••••••••••••••••••••••••••• C o la b o r a d o r e s Abraham Otero, Juan Martos, Jorge Rubira, Guillem Alsina, Adolfo Aladro, Aitor Almeida, David Sainz, Gastón Hillar, Javier Holguera, Nicolás Velasquez, Pep Lluis •••••••••••••••••••••••••••••••••• M a q u e t a ci ó n Alfonso Sabán / Raúl Clavijo •••••••••••••••••••••••••••••••••• D e p a r t a m e n t o d e P u b l ici d a d Felipe Ribagorda Tel.: 91 304 87 64 D e l e g a c i ón e n B a r c e l o n a C/ Rocafort, 241/243, 5º 1ª Mariano Sánchez Tel.: 93 322 12 38 •••••••••••••••••••••••••••••••••• D p t o. S u s c r i p c i o n e s Tel: 91 304 87 64 Fax: 91 327 13 03 ••••••••••••••••••••••••••••••••••• I m p re si ó n L.M.S. Solución Gráfica ideasimpresion@telefonica.net ••••••••••••••••••••••••••••••••••• D i s t r i b u ció n

Coedis S.L. C/ Alcorcón nº 9 - 28850 Torrejón de Ardoz (Madrid) Teléfono 91 676 96 62

DISTR I B U CION EN MEX ICO DIMSA - C/ Mariano Escobedo, 218 Col. Anáhuac. 11320 México, D.F. D ISTR IB U CIO N EN AR GEN TIN A Capital Federal: Distrimachisa Interior: York Agencysa - Tlf: (5411) 433 150 51 •••••••••••••••••••••••••••••••••• Quedan expresamente prohibidas la reproducción, la distribución y la comunicación pública de todo o parte de los textos contenidos en esta publicación, por cualquier medio y en cualquier soporte, y para cualquier fin, incluyendo la realización de resúmenes de prensa comerciales, sin la autorización expresa de esta Editorial, conforme a lo dispuesto en la vigente Ley de Propiedad Intelectual. La infracción de la presente prohibición será perseguida penalmente. Depósito legal: M-26827-1994 P R IN TED IN SPAIN P.V.P. 6 euros

16/6/08

12:41

Página 3

EDITORIAL De nuevo, acometemos las tan esperadas vacaciones, algunos con la ilusión de la playa, montaña, deportes, etc. y otros con la ilusión contenida de poseer el tan deseado iPhone. Pues bien, parece que para el mes de Julio podremos acceder al juguetito deseado de última generación a un precio mucho menor que en su fecha de lanzamiento. Aún más, ¿gratis bajo ciertas condiciones?, habrá que esperar. De lo que no cabe duda es que la introducción en el mercado de este dispositivo supondrá un vuelco y cambio de actitud ante la habitual costumbre de cambiar periódicamente de modelo de móvil. No cabe duda de que este nuevo personaje entre la PDA, teléfono móvil, ¿juguete?, supondrá un cambio en las costumbres de los usuarios que gustan dejar el móvil en la barra del bar junto al del cliente contiguo, a modo de comparación.

SUMARIO

REDES 20

RSS con Java (III)

14 32

Scrum (II) Programación con múltiples hilos (II)

26 46

J2ME (III) Virus en móviles

54

Arrastrar y soltar

64

Busca las minas

MIDDLEWARE

DISPOSITIVOS MÓVILES COMUNIDAD .NET

VIDEO-TUTORIAL Y ADEMÁS. . . 04 12 58 60 66

Noticias javaHispano Opinión Dudas Contenido del CD-Rom


noticias:NOTICIAS

16/6/08

10:30

Página 4

NOTICIAS

Europa da el primer paso para regular los blogs Una directiva de la Comisión Europea insta a los bloggers a identificarse públicamente en sus respectivas páginas para garantizar a los internautas que conocen la identidad de quienes publican la información. A juicio de la Comisión, Internet sufre un "exceso de información" en el que es muy fácil extender mentiras e informaciones falsas o insidiosas. La Comisión Europea vuelve a meterse en camisa de once varas, esta vez tocando un tema relativo a la libertad de expresión en la Red de redes y, más concretamente, lo que casi unánimemente se ha considerado como el principal artífice de lo que Internet es hoy: el anonimato. Si bien hay formas de rastrear quien ha escrito qué en Internet, las posibilidades de ser totalmente anónimo y escribir lo que se quiera en un blog o página web han existido, existen y existirán siempre. Y eso precisamente ha sido el origen de algunos abusos pero también de la principal grandeza de Internet, una red al menos en teoría- libre en la que todo el mundo tiene posibilidades de expresarse y debatir las opiniones de los otros. Del filtrado de estas opiniones se encarga todo el conjunto de internautas, una "inteligencia colectiva" que se encarga de discriminar lo que es cierto de lo que no lo es, lo que es útil de lo inútil, y así sucesivamente. La Comisión Europea decidió proponer la creación de un censo voluntario de bloggers con el objetivo de generar confianza en el lector. Esta iniciativa se basa en un documento presentado al Parlamento Europeo por la eurodiputada estonia Marianne Mikko y cuyo título es "Informe sobre la concentración y el pluralismo de los medios de comunicación en la Unión Europea". David Corral, periodista del rotativo español El País, afirma[1] que la nacionalidad de la eurodiputada puede ser una explicación a la presentación de esta iniciativa. Las relaciones de las repúblicas bálticas (Lituania, Letonia y Estonia) con Rusia han sido tensas desde la independencia de estos tres pequeños estados de la Europa oriental respecto a la antigua URSS. Desde el retorno a la independencia perdida en 1940, las tensiones entre la mayoría estonia y la amplia minoría rusa (una cuarta parte de la población) han desembocado en ciertos intentos "desrusificadores" del país, con episodios como la retirada de un monumento a las tropas soviéticas en Tallín[2] (la capital del país), que provocó no tan solo las iras de la comunidad ruso-estonia, sino también las protestas del gobierno ruso. En tal ambiente de crispación, no es rara la intoxicación informativa que no solamente ha SOLO PROGRAMADORES nº 162

4

sido llevada a cabo en los medios de prensa oficiales, sino también en la Internet rusa y estonia por parte de bloggers independientes. El gobierno estonio ha aludido varias veces a un complot organizado por el gobierno del país vecino para intoxicar la información que reciben los estonios a través de Internet, por lo que la medida podría ser entendida cómo un primer intento para pasar más adelante a controlar mucho más estrechamente la identidad y procedencia de quienes escriben las informaciones. Naturalmente, no podemos esperar que esta sea una medida aislada y que se quede aquí la cosa; un censo voluntario sirve de poca cosa a quienes quieren controlar lo que se publica en la Red, así que deberíamos ver esta propuesta como la primera piedra de un grueso muro que se está empezando a levantar. Como siempre que se habla de estos temas de control de los contenidos, encontramos dos posturas diametralmente enfrentadas: aquellos que abogan por la máxima libertad apelando a la auto-regulación del medio, algo que ha funcionado desde los primeros tiempos de Internet, y los que ven esta libertad como algo mal entendido que debe ser regulado de alguna forma. Posturas tan o más irreconciliables como los que tildan al P2P de una simple herramienta y aquellos que acusan a este sistema de facilitar la piratería de contenidos. Lo cierto es que al final de todo, volvemos a encontrarnos con una vieja y conocida cuestión, ya que si alguien controla a los bloggers, ¿quién controla a los que controlan? [1] http://www.elpais.com/articulo/internet/ Eurocamara/sienta/bases/regular/blogs/el peputec/20080610elpepunet_1/Tes [2] http://www.elpais.com/articulo/internacional/ Crisis/Rusia/Estonia/retirada/monumento/sovietico/ Tallin/elpepuint/20070427elpepuint_12/Tes

Nvidia quiere parte del pastel del mercado de los microchips para dispositivos móviles La compañía, conocida en todo el mundo como una de las líderes indiscutibles de tecnologías gráficas (especialmente para el mercado de los videojuegos), lanzará una línea de microprocesadores bajo el nombre Tegra que competirá con los Atom de Intel para los dispositivos de tipo MID.

Los MID (Mobile Internet Device) son una invención de Intel, aunque rápidamente la designación se ha tomado como genérica para cualquier dispositivo ultraportátil orientado eminentemente a la conexión a la Red de redes e independientemente de que pueda además gozar de otras funcionalidades. Pese a que la definición de Intel incluye a GNU/Linux como sistema operativo, los primeros dispositivos que pueden tener la consideración de MID son los UMPC's que trabajan con Microsoft Windows. El de los MID's es un terreno con un gran futuro pese a que hoy en día aún sea un mercado casi virgen en muchos países. Es por ello que además de Intel, otras empresas quieren su pedacito de una tarta que promete traer muchos beneficios a quien pueda hacerse un hueco en el mercado. Y una de estas compañías es Nvidia, especializada en GPU's -Graphics Processing Unit, chips para tarjetas gráficas-, que ha presentado recientemente su plataforma Tegra[1], un sistema completo en un sólo chip, con lo que con un único componente se consigue toda la funcionalidad de una computadora o PDA. El lanzamiento comercial de los primeros dispositivos que utilizarán la plataforma Tegra se realizará a finales de este año, y serán los smartphones basados en el chip Tegra APX 2500 y que emplean Windows Mobile como sistema operativo. Este microprocesador fue presentado el pasado Febrero. Los últimos desarrollos son los Tegra 600 y 650[2], pensados para dispositivos más potentes tipo MID. El corazón de esta plataforma es la arquitectura ARM de 32 bits. De cara al futuro próximo, Tegra integrará procesadores dedicados para vídeo de alta definición en dispositivos móviles, o procesadores de audio para crear una familia lo más completa posible. [1] http://www.nvidia.com/page/handheld.html [2] http://www.nvidia.com/object/io_1212391 368499.html

Apple presenta la segunda generación del iPhone Conectividad 3G tal y como se esperaba y el nuevo servicio MobileMe que proporciona correo 'push' y otras funcionalidades, lo más destacado de una presentación muy esperada. www.revistasprofesionales.com


noticias:NOTICIAS

16/6/08

10:30

Página 5

NOTICIAS

Lo nuevo: 3G y...

Steve Jobs no decepcionó a todos aquellos que esperaban la presentación de la nueva generación del aclamado teléfono móvil de Apple, el iPhone. La Red de redes había vivido estos últimos días como siempre que se acerca uno de los grandes acontecimientos de la compañía de Cupertino, con más expectación si cabe por la rumorología que desde hacía algunas semanas se había disparado. El interés ha sido excepcionalmente alto en España, uno de los principales mercados europeos al que aún le faltaba la presencia de un teléfono que ha pasado a convertirse en un gádget objeto de deseo. En este sentido, la importación "paralela" ha funcionado muy bien gracias a las diversas herramientas para liberar el iPhone y hacerlo útil para cualquier país y operadora. No pocas personas han aprovechado la fortaleza del Euro frente al dólar para visitar los Estados Unidos, trayendo iPhones para ellos y para amigos que se los han encargado. Incluso se han podido adquirir a través de Internet en comercios "paralegales". Telefónica fue desde el primer momento la operadora a la que, pese al secretismo con el que se han llevado a cabo todas las negociaciones, todo el mundo apuntaba como la elegida por Apple para traer el iPhone a España. Posiblemente para contribuir a la expectación, la misma Telefónica se encargaba de distribuir la semana pasada una escueta nota de prensa en la que confirmaba que vendería el teléfono, pero sin revelar si sería la nueva generación ni qué funcionalidades tendría en dicho caso. No obstante, la proximidad de este anuncio con la conferencia de desarrolladores de Apple hizo más que sospechar a la prensa y los aficionados. www.revistasprofesionales.com

Se rumoreaba desde hacía días que la principal nueva capacidad del segundo iPhone[3] sería la conectividad 3G, y así ha sido aunque no la única. Un elemento que algunos echaron en falta en la presentación de la primera generación del teléfono, el GPS, hace acto de presencia en esta nueva revisión para facilitar las aplicaciones de geoposicionamiento. En el primer iPhone se incluía Google Maps, que sigue estando presente en este renovado terminal, pero ahora con la posibilidad añadida de utilizar el GPS para situarnos en el mapa. La utilización de la conexión 3G propicia que el nuevo iPhone sea más veloz en las conexiones de datos, dicho de otro modo, en la conexión a Internet. A partir de ahora descargar el correo electrónico o navegar por la Web será casi tan rápido como con nuestro sobremesa o portátil habitual. El nuevo iPhone es compatible con redes Wi-Fi, 3G y EDGE para datos, y telefonía móvil GSM cuatribanda y HSDPA tribanda para las comunicaciones de voz. Otra ventaja es que podemos atender una llamada de voz mientras navegamos por la Red. Otro añadido es la versión 2.0 del software del iPhone, más enfocada que la versión anterior al mundo empresarial y que cuenta con compatibilidad con Microsoft Exchange ActiveSync, redes VPN de Cisco, además de poder descargar aplicaciones de terceras partes de la App Store. Estas aplicaciones han sido construidas con el iPhone SDK, disponible gratuitamente en el sitio web de Apple, e inicialmente el servicio estará disponible en 62 países. No todas las aplicaciones de la App Store serán de pago; también podremos encontrar programas freeware (gratuitos) y probablemente (aunque sea más adelante) software libre. La misma App Store notificará a los usuarios si hay disponibles actualizaciones de las aplicaciones que tenga en su teléfono.

Otras novedades del iPhone 3G son:   

 

Permite el traslado y borrado de un conjunto de múltiples mensajes de email Nueva calculadora científica Herramientas de control paterno (parental control en inglés) para restringir o bloquear el acceso a determinados contenidos violentos o sexualmente explícitos Posibilidad de guardar las imágenes que encontremos en una página web Autonomía estimada de 10 horas de conversación telefónica en redes 2G y de 5 horas usando 3G, hasta 5 ó 6 horas de navegación Web, hasta 7 horas de repro-

ducción de vídeo y hasta 24 horas de reproducción de audio.

Tiembla BlackBerry... Si bien la compañía canadiense RIM parecía no temerle al iPhone[1], con el nuevo servicio MobileMe[2] sí podría tener algún motivo de inquietud. Una de las principales virtudes de la BlackBerry, especialmente cuando salió al mercado, era que el usuario no debía ir a buscar el correo electrónico al servidor, sino que gracias a su innovador método 'push', era el correo el que iba al terminal. Este sistema fue posteriormente adoptado por el resto de sistemas operativos para telefonía móvil y proveedores de servicio/operadoras. Así, smartphones con Palm OS o Windows Mobile incorporan esta posibilidad. Si bien la orientación inicial del iPhone parecía el público más joven e informal o los profesionales liberales, su adopción por parte del mundo empresarial ha provocado una reorientación de parte de las novedades hacia este segmento, como es el caso del aquí comentado MobileMe, un sistema que no solamente permite la descarga del correo en modo 'push', sino que va un paso más allá para proporcionar también sincronización de los contactos y agendas con otros dispositivos (cómo un Mac de sobremesa o portátil) o la posibilidad de subir las fotografías tomadas con el teléfono a un servicio de galería fotográfica similar a Flickr. El servicio iDisk también está disponible a través de MobileMe, de forma que podemos crear un repositorio de archivos propios en línea para utilizarlos desde nuestro iPhone. El precio de MobileMe con un espacio de almacenamiento de 20 GB. online será de unos 70-80 dólares/Euros dependiendo del país y operadora (en España, por ejemplo, será de 79 Euros IVA incluido). El precio del nuevo iPhone es algo que va a dar mucho que hablar, pues a diferencia del primer modelo cuando salió, su coste es excepcionalmente barato: 199 dólares para el modelo de 8 GB. y 299 para el de 16 GB., aunque el precio puede tener truco al no estar incluido en él el contrato con la operadora. La disponibilidad del nuevo iPhone 3G se producirá paulatinamente durante todo este año en más de 70 países, entre los que se encuentran Estados Unidos -naturalmente-, España -llegará el 11 de Julio de la mano de Telefónica, algo que hace una semana escasa que se conoce con seguridad-, México, Alemania, Reino Unido, Francia, Japón o Suiza entre otros. [1] http://ww2.grn.es/merce/2007/blackberry.html [2] http://www.apple.com/mobileme/ [3] http://www.apple.com/iphone/ 5

SOLO PROGRAMADORES nº 162


noticias:NOTICIAS

16/6/08

10:30

Página 6

NOTICIAS

Nuevos Eee PC

Así será el próximo Mac OS X Se llamará Snow Leopard (Leopardo de las Nieves o Irbis), y no incluirá un gran número de nuevas prestaciones sino que se centrará en mejorar el rendimiento que ofrece el sistema. La Worldwide Developers Conference de Apple[1] no solamente nos ha legado el nuevo iPhone 3G aunque esta haya sido la novedad que más portadas y artículos ha acaparado. Desde hacía unos días se rumoreaba en Internet que Steve Jobs también desvelaría algunas de las claves del próximo Mac OS X, como así ha sido al fin. La rumorología ha acertado con su nombre: Snow Leopard, Leopardo de las Nieves en inglés. Los muchachos de Steve Jobs no han querido introducir nuevas y espectaculares funcionalidades en esta versión, algo que sí pasó en la versión 10.5 "Leopard" respecto a la anterior 10.4, sino que parecen querer darle un descanso al usuario y simplemente mejorar aquello que han conseguido. Una de las principales novedades de esta nueva versión será el soporte para Microsoft Exchange, algo con lo que ya cuenta el iPhone y que parece dirigido a la yugular de los sistemas Windows y Linux en el desktop para captar mayor número de usuarios empresariales, especialmente en Europa que sigue siendo mayoritariamente el talón de Aquiles de la compañía de Cupertino, ya que sus máquinas tienen en el viejo continente la imagen de estar dirigidas a profesionales liberales y diseñadores gráficos/productores de medios. El soporte para Exchange en su versión 2007 estará disponible en las aplicaciones Mail, iCal y libreta de direcciones. SOLO PROGRAMADORES nº 162

6

Otras novedades con las que contará Mac OS X 10.6 serán: 

Soporte para cantidades de memoria RAM de hasta 16 TB. (Terabytes)  Tecnología Grand Central que aprovecha al máximo las modernas CPU's multinucleo  QuickTime X, nueva implementación del conocido reproductor multimedia de la compañía de Cupertino con soporte para más códecs  OpenCL (Open Compute Library), tecnología que permite aprovechar la GPU de la tarjeta gráfica para la realización de cálculos de propósito general No se han dado fechas de entrega de Snow Leopard, pero podríamos tener que esperar hasta un año para poder verlo en acción en nuestras máquinas.

Más información: Página de "preview" de Apple para Snow Leopard: http://www.apple.com/macosx/snowleopard/ [1] http://developer.apple.com/wwdc/

El primer PC ultraportable de Asus que recibió el nombre Eee dio paso a una nueva línea de productos que todavía nos están empezando a llegar pero que prometen un futuro en el que las tecnologías informáticas serán mucho más asequibles a todos los bolsillos y nos acompañarán allá donde vayamos. Antes del Eee PC, el único proyecto de máquina ultraportable que tenía disponibilidad en los principales mercados era el XO de OLPC, y por ello podemos considerar que la computadora de Asus abrió un mercado para el que entonces solamente contábamos con proyectos y anuncios de futuros lanzamientos. Y estamos hablando ¡de solamente hace unos pocos meses! Desde entonces, la fama y éxito del Eee PC han ido creciendo paulatinamente hasta el punto de que en un momento determinado Asus se planteó explotarlos con nuevas máquinas y diseños. Así, modelos de ultraportátil Eee con mayor capacidad de almacenamiento, una pantalla más grande y algunas versiones equipadas con Windows XP salieron al mercado. Los nuevos modelos[2] 901, 1000 y 1000H del Eee PC montan pantallas de 8,9" el primero y 10 o 12" los dos últimos, memorias de estado sólido de alta capacidad (desde 12 hasta 40 GB) o discos duros (hasta 80 GB), y se basan en el procesador Intel Atom para dispositivos móviles en vez de los Celeron de la misma compañía californiana (y huyendo de los VIA, compañía que es competencia directa de Asus en otros campos). La memoria RAM también se amplía desde los 512 MB. hasta el gigabyte o los dos "gigas" de las configuraciones más holgadas. La tarjeta de red inalámbrica cumple con el estándar 802.11n y la webcam es de 1,3 Mpx. en todos los nuevos modelos. El ya tradicional color blanco de la carcasa también se mantiene, y

Asus presenta interfaz de usuario futurista y nuevos modelos de Eee PC en el Computex 2008 VirtualReal es una interfaz minimalista que se controla a través de movimientos del usuario captados con la webcam de la computadora. La firma taiwanesa también ha presentado nuevos modelos de su exitosa línea Eee. La feria tecnológica Computex 2008[1] celebrada recientemente en la capital de la isla-estado de Taiwan, Taipei, ha dejado cómo principal nota destacable las presentaciones de nuevos productos de Asus, una de las compañías de dimensión global que en este evento jugaba en casa. www.revistasprofesionales.com


noticias:NOTICIAS

16/6/08

10:30

Página 7

NOTICIAS

las baterías incluidas son de seis celdas, lo que les da mayor autonomía.

VirtualReal, nada nuevo pero a la vez espectacular Este es el nombre que Asus le ha puesto a su nuevo diseño de interfaz de usuario minimalista[3], que incluye lo justo y necesario para controlar las funcionalidades de software y máquinas. Pero realmente, lo innovador no es esto, sino la forma en que se trabaja con esta nueva interfaz. De hecho, el control a través de movimientos de las manos captados con la webcam tampoco tiene nada nuevo, pero Asus puede ser la primera en utilizar esta tecnología en la interfaz de un producto informático, ya que hasta ahora solamente se ha utilizado en el mundo de los videojuegos (eyeToy para PlayStation) y experimentalmente. El funcionamiento es espectacular, y la compañía taiwanesa lo compara con una famosa escena de la película Minority Report en la que el protagonista (John Anderton, interpretado por el actor Tom Cruise) utiliza una computadora dándole instrucciones y accediendo a información mediante el movimiento de sus manos con una interfaz virtual. Asus no llega tan lejos, pero sin lugar a dudas el resultado es espectacular y nos adelanta a un futuro no tan lejano en el que nos sentaremos a unos metros de distancia del monitor de nuestra computadora para realizar tareas solamente moviendo las manos y/o dictándole órdenes y textos por voz. Por el momento se desconoce la fecha exacta en que todas estas tecnologías estarán disponibles en el mercado para el público final, tanto los nuevos modelos de Eee PC cómo la interfaz VirtualReal. [1] http://www.computextaipei.com.tw/ [2] http://www.asus.com/news_show.aspx? id=11617 [3] http://www.asus.com/news_show.aspx? id=11678

Google Earth, ahora en el navegador La compañía del buscador hace posible a los usuarios de los navegadores Firefox e Internet Explorer utilizar Google Earth sin tener que instalar el programa en su computadora, además de proporcionar a los webmásters una nueva herramienta a su alcance. Mediante un plug-in para los navegadores web y una API abierta, Google hace llegar su software Earth más allá de un sólo programa y, al igual que ya hizo en su momenwww.revistasprofesionales.com

to con Maps, facilita a los programadores de "mashups" integrar este espectacular programa con el que pueden verse todo tipo de edificaciones en 3D en sus propias creaciones. Google Earth[1] es un software multiplataforma (Windows, Mac OS X y Linux) gratuito que mediante fotografías de satélite permite dar un paseo virtual por cualquier rincón del planeta Tierra. En las últimas versiones, a esto se le añaden las reconstrucciones en 3D de edificios y accidentes geológicos como montañas o cañones. La espectacularidad del programa le ha granjeado fama incluso por encima de productos de la competencia como los de Microsoft, que algunos sectores de la crítica alaban como superiores. Lo presentado permite a los programadores de páginas web insertar en sus creaciones una ventana con el contenido de Google Earth y la misma interactividad para navegar que si utilizásemos el mismo software que, al fin y al cabo, descarga

todos los contenidos que muestra desde la Red. Los mismos usuarios de Google Earth pueden contribuir a incrementar el contenido del servicio mediante la reconstrucción virtual de edificios y otros elementos que existan en el paisaje real. Y los programadores web o diseñadores de sitios podrán incluir el acceso a todas las funcionalidades de este software con tan solo copiar unas pocas líneas de código. Una utilidad que rápidamente puede verse a este sistema es la geolocalización; actualmente es una práctica muy común que los comercios, instituciones y otros organismos públicos y privados, muestren su localización en un applet de Google Maps embebido en su página web. A partir de ahora, y además de ver las rutas en tres dimensiones, podremos ofrecer a nuestros visitantes la opción de poder ver "sobre el terreno" el sitio donde nos encontramos. Los sitios de viajes probablemente serán los principales usuarios de este nuevo servicio de Google, al poder mostrar a los potenciales compradores de paquetes turísticos, exactamente el lugar que van a visitar reconstruido virtualmente y en tres dimensiones desde su propia página web. Por el momento, el plug-in para Google Earth en el browser está disponible solamente para Firefox 2.x e Internet Explorer 6 y 7 bajo Windows. Se espera que esté disponible en breve para otras plataformas cómo GNU/Linux y Mac OS X. El anuncio de esta iniciativa se realizó en el pasado Google I/O, encuentro para desarrolladores celebrado en la localidad californiana de San Francisco los días 28 y 29 de Mayo. Más información: Nota de prensa de Google http://www.google.com/intl/en/press/annc/ earthapi_20080528.html [1] http://earth.google.com/ 7

SOLO PROGRAMADORES nº 162


noticias:NOTICIAS

16/6/08

10:30

Página 8

NOTICIAS

IBM libera la versión 1.0 de su suite ofimática gratuita Buscará un puesto en el mercado rivalizando con el Office de Microsoft y su alternativa libre, el cada vez más popular OpenOffice. El moderno Lotus Symphony[1] busca recuperar el prestigio y la cuota de mercado que en el pasado tuvieron sus aplicaciones, algo difícil en un panorama ofimático dominado por Microsoft Office en sus versiones para Windows y Mac OS X, y con un "outsider" tan potente como OpenOffice que cada vez araña más cuota de mercado gracias al uso de formatos de fichero abiertos y a su gratuidad, cosas que lo convierten en una excelente opción para los vendedores y distribuidores como valor añadido a sus ventas.

Lotus fue una marca de reconocido prestigio en su momento, inventora del concepto moderno de hoja de cálculo con su producto 1-2-3, el cual sirvió de modelo a muchos otros desarrollos posteriores entre los que se cuenta el Excel de Microsoft. Otro producto emblemático de esta suite cuando estuvo ya en poder de IBM (allá por 1995) fue el procesador de textos Ami Pro. El nuevo Lotus Symphony es un software gratuito disponible para dos de las principales plataformas informáticas actuales: Windows y Linux. Para más adelante se anunció una versión para Mac OS X, de la cual aún no tenemos ninguna noticia. La interfaz de usuario es espectacular en ambos sistemas operativos, y es un "cruce" entre la de OpenOffice y la de Microsoft Office 2003. Por lo que respecta a los formatos de documento, Lotus Symphony 1.0 utiliza por defecto los formatos abiertos OpenDocument para todas sus aplicaciones, pudiendo por lo tanto intercambiar documentos del procesador de textos, hoja de cálculo o programa de presentaciones con otras suites ofimáticas que utilizan el mismo formato como OpenOffice o KOffice. La interoperatividad con Microsoft Office no se ha olvidado, y el software es capaz de reconocer y trabajar con los formatos propietarios de esta suite hasta la versión 2003, no estando soportados los ficheros Open XML. Tampoco se ha dejado de lado la SOLO PROGRAMADORES nº 162

8

interacción con Lotus SmartSuite, el viejo paquete de aplicaciones ofimáticas de IBM. La primera versión estable, que sucede a la beta lanzada a finales de 2007 y que mejora algunos aspectos corrigiendo los bugs detectados, puede ser descargada gratuitamente desde el sitio web[1] del programa. La cantidad de peticiones que ha recibido estos días hacen que a veces sea difícil llegar de forma efectiva a descargarlo. Esperemos que IBM pronto ponga remedio a esta cuestión. [1] http://symphony.lotus.com/

Adobe presenta Acrobat 9 La compatibilidad con el formato Flash permitirá la creación de libros electrónicos mucho más interactivos que los que tenemos hoy en día, sin lugar a dudas un punto muy importante a favor de la compañía norteamericana. Adobe ha querido unir dos de sus tecnologías líderes de mercado como son los documentos electrónicos PDF y los contenidos multimedia (audio, vídeo, animaciones informáticas,...) Flash en esta nueva versión de Acrobat[1], su software para la creación de documentos PDF. No hay que confundir este paquete, que nos sirve para crear y editar documentos en el formato PDF, con Adobe Reader, un programa que solamente nos permite la lectura de documentos y no su creación o edición. Este último puede descargarse gratuitamente desde Internet, mientras que el primero es un paquete comercial. No obstante, es probable que con la aparición de Acrobat 9 en breve estemos disfrutando de una nueva versión de Reader, que en este caso también sería la novena.

La integración de Flash en Acrobat nos permite incrustar animaciones en este formato multimedia en nuestros documentos PDF. Este es un paso importante, pues dota a los documentos electrónicos de una funcionalidad mucho más potente que sus homólogos en papel como es la de exhibir contenido no estático y diferente al puramente visual. Así, en un artículo sobre un concierto de una publicación electrónica, ya no solamente nos limitaremos a ver las fotografías del acto, sino que podremos introducirnos aún más en el ambiente gracias a los vídeos y animaciones incluidas en el PDF o la música que va sonando mientras leemos. Para disfrutar de estos efectos será necesario contar con la próxima generación de programa lector, el antes comentado Reader 9, a presentar en un futuro próximo.

Acrobat.com Paralelamente al anuncio de Acrobat 9, Adobe también ha presentado la beta pública de Acrobat.com[2], un servicio online colaborativo que permite a varios usuarios simultáneamente y desde localizaciones remotas trabajar sobre un mismo documento PDF. La inscripción mientras dura la fase beta es libre y gratuita.

Como herramientas, el sitio dispone de un editor de textos online (al estilo de Google Docs) llamado Buzzword, una utilidad para la realización de videoconferencias y compartición de escritorio llamada ConnectNow, un repositorio de archivos, y una API para programadores. Todo ello, naturalmente, contando con la posibilidad de exportar el trabajo hecho a formato PDF. Este servicio se une a Photoshop Express para hacer entrar a Adobe por la puerta grande en la Web 2.0, la era de los servicios en línea. Además, los usuarios de Acrobat 9 lo podrán utilizar conjuntamente con la popular aplicación de Adobe para guardar sus archivos. [1] http://www.adobe.com/products/acrobat/ ?promoid=CSFUC [2] https://www.acrobat.com/ www.revistasprofesionales.com


noticias:NOTICIAS

16/6/08

10:30

Página 9

NOTICIAS

VIA Technologies ofrece diseño abierto de ultraportátil VIA OpenBook[1] incluye una plataforma de referencia y los diseños para la construcción de determinadas piezas bajo una licencia Creative Commons, de manera que la plataforma es altamente personalizable para cualquier fabricante o integrador. Sumidos en una auténtica avalancha de computadoras ultraportátiles, VIA Technologies (fabricante taiwanés de hardware) ha presentado no ya un modelo concreto de uno de estos aparatos, sino toda una plataforma que va a permitir a pequeños integradores y revendedores disponer de una gama propia de ultraportátiles.

Efectivamente, lo que "diseño abierto" significa es que VIA solamente realiza una parte de la máquina, liberando las instrucciones para que el cliente construya el resto. La parte que proporciona VIA es la estructura electrónica y la chapa interna, mientras que opciones como la conectividad WiMAX o 3G pueden ser seleccionadas por el cliente. Pero lo que de verdad dota de potencia comercial a esta plataforma es que se han liberado bajo una licencia Creative Commons los planos en CAD de cómo deben ser las tapas de plástico de los portátiles y demás elementos externos, de forma que cualquier fabricante o integrador puede encargar su propio diseño que sea compatible para personalizar también externamente la apariencia de su gama de máquinas ultraportables. Tecnológicamente, la plataforma OpenBook se apoya en las tecnologías de VIA: la gama de procesadores C7 (compatibles con la familia x86 de Intel), las placas base y los chipsets de la compañía. La pantalla del VIA OpenBook es de 8,9" y soporta resoluciones de hasta 1024x600. [1] http://www.viaopenbook.com/

notebooks y sobremesas de medias y altas prestaciones. La compañía es considerada el tercer vendedor de computadoras del mundo tras HP y Dell.

Según afirma vnunet.com[1], una de las publicaciones de referencia para los negocios relacionados con las nuevas tecnologías, diversos directivos del fabricante taiwanés de computadoras Acer, han afirmado que la compañía aumentará su apuesta por Linux en un futuro próximo. Actualmente, esta multinacional ya ofrece GNU/Linux como sistema operativo para sus computadoras ultraportátiles, pero la apuesta es llevarlo a nuevas gamas de portátiles y sobremesas. La publicación online cita concretamente a Gianpiero Morbello, vicepresidente de marketing e imagen de marca, y a David Drummond, director mánager de Acer en el Reino Unido. Este último hizo referencia al precio extra que supone Windows en una computadora, afirmando que si contamos

con un coste de cincuenta libras esterlinas adicionales, esto es como una gota en un vaso de agua si estamos hablando de una máquina con un precio de 1.000 libras, pero que supone un handicap considerable en una máquina de 200, ya que constituye una quinta parte del precio final (20%) mientras que en el primer caso no llega al 5%. Por su parte, Morbello ha afirmado que "pese a Microsoft", Acer va a apostar abiertamente por Linux en el futuro próximo, aumentando el número de máquinas que distribuye con el sistema operativo libre. Entre las ventajas que ve en GNU/Linux están la optimización para la máquina (recompilando el kernel del sistema podemos hacer que arranque más rápidamente que otros sistemas operativos e incluso extender la duración de la batería) y el coste (naturalmente). No se han concretado fechas, pero sí se ha dejado entender que podríamos empezar a ver máquinas de Acer con Linux precargado este mismo año, aunque probablemente muy restringidas al mercado asiático en el que el sistema del pingüino tiene más penetración a nivel de telefonía móvil y de computadoras personales. [1] http://www.vnunet.com/vnunet/news/ 2218172/acer-pushes-linux-hard

Firefox quiere obtener el récord Guinness de descargas La campaña que bajo el nombre de “Download Day” ha puesto en marcha la comunidad Spread Firefox pretende lograr el máximo número de descargas para esta-

Acer podría apostar más por Linux en un futuro próximo Directivos del fabricante taiwanés afirman que el sistema operativo del pingüino podría equipar en breve a muchos de sus www.revistasprofesionales.com

9

SOLO PROGRAMADORES nº 162


noticias:NOTICIAS

16/6/08

10:31

Página 10

NOTICIAS

blecer un nuevo récord en el popular libro Guinness: el del software más descargado en un sólo día. La tercera versión del popular navegador web de código libre Firefox será publicada en algún momento de este mes de Junio aún sin especificar. Para canalizar la expectación generada por esta nueva versión, la comunidad Spread Firefox -a través de la cual Mozilla hace buena parte de su márqueting- ha hecho un llamamiento a lo que ha bautizado como Download Day 2008, y mediante el cual se quiere conseguir establecer un nuevo récord dentro del popular libro Guinness de los récords: el del software más descargado en un sólo día. La marca es segura: el récord que se busca no existe actualmente, con lo que Firefox 3 será sin lugar a dudas el primero en conseguirlo. La intención de la organización es hacer de esta una marca duradera en el tiempo por difícil de superar. Para ello se ha hecho a través del sitio Spread Firefox un llamamiento[1] para que el mayor número de internautas descargue el programa.

Bill Gates y Steve Ballmer hablan sobre Windows 7 Interfaz multitáctil y un Dock al estilo Mac OS X las novedades que los dos directivos de Microsoft muestran, mas unas capturas de pantalla que podrían corresponder a la próxima versión del sistema, un punto este último que no ha podido ser contrastado. Pese a que hasta ahora pocas eran las indicaciones oficiales de como sería el

SOLO PROGRAMADORES nº 162

10

futuro Windows 7 (la versión que saldrá al mercado después de Vista), en un acto celebrado recientemente en California (Estados Unidos) Bill Gates y Steve Ballmer (presidente y CEO de Microsoft respectivamente) dieron algunas pistas sobre alguna de las novedades que va a ofrecer. Como se sospechaba[1], el próximo Windows dispondrá de interfaz multitáctil[2], una tecnología de la que Microsoft ya dispone y ha lanzado comercialmente con Surface, una prueba de concepto para un nuevo dispositivo de alta interactividad. Con esta tecnología, cuya precursora fue Apple con el iPhone y el iPod

Touch, la compañía de Redmond busca acercar un poco más la forma de trabajar del sistema con la forma de pensar del ser humano. Pese a que muchas veces se ha tildado a la tecnología incluida por Microsoft en sus productos como de un plagio de otros sistemas y programas (especialmente de los de Apple), la capacidad multitáctil de Surface no ha levantado críticas, probablemente debido a dos factores: a) es un dispositivo con un cierto halo elitista y por lo tanto no accesible a todo el mundo con lo que "jugar" con él no es muy fácil, y b) la tecnología está bien conseguida. Otra novedad sería la aparición de un Dock al estilo del Mac OS X, una tendencia que a diferencia de otras marcadas por Apple no ha acabado de cuajar entre los sistemas operativos rivales ya que hasta ahora solamente había sido adoptado por algunos entornos de escritorio para Unix, aunque no los principales, KDE y Gnome. Por otra parte, e independientemente de lo que hayan afirmado Bill Gates y Steve Ballmer, una serie de capturas de pantalla[3] que muestran el aspecto que podría tener el futuro Windows 7 han sido filtradas a Internet. Pese a que han sido dadas por buenas por varios medios de comunicación especializados y a que se incluye en este artículo el enlace para acceder a ellas, no es posible verificar su autenticidad al no haber reconocido Microsoft que efectivamente correspondan a lo que dicen ser. Cabe recordar que Windows 7 se encuentra aún en una fase temprana de desarrollo, y por lo tanto las funcionalidades presentadas ahora pueden variar hasta el lanzawww.revistasprofesionales.com


noticias:NOTICIAS

16/6/08

10:31

Página 11

NOTICIAS

miento definitivo del producto, algo que según Gates y Ballmer podría producirse en Enero de 2010.

¿Porqué ahora? Una de las preguntas que podemos hacernos sobre el sucesor de Vista es el porqué precisamente ahora se empiezan a revelar detalles de lo que va a ofrecer. El éxito de Vista es relativamente bueno: se ha vendido bien con ordenadores nuevos para usuarios finales, pero no está cuajando en el sector empresarial, el cual es muy lento a la hora de adoptar los cambios. Además, un número significativo de compradores de máquinas nuevas solicita un "downgrade" a Windows XP, algo que Steve Ballmer reconoció. Las críticas al sistema se centran en la compatibilidad con determinadas aplicaciones (un aspecto que se ha buscado mejorar con el Service Pack 1) y los recursos de hardware que demanda, aunque esto último queda mucho más restringido a las máquinas que se actualizan desde XP. Técnicamente se ha criticado poco, aunque los principales blancos han sido el control de acceso de los usuarios (el sistema de permisos) y la interfaz gráfica, que al fin y al cabo parece no ser tan espectacular como se esperaba. Es difícil calibrar correctamente que es lo que está intentando Microsoft al soltar detalles de la próxima versión. Algunos analistas (pocos) han dicho que de seguir así, Vista podría convertirse en un segundo Windows Millenium, un sistema denostado por usuarios y técnicos por su rendimiento y estabilidad. Aunque no de la misma manera (estos son dos aspectos que apenas se le han criticado a la nueva versión), ciertamente por los motivos antes explicados, Windows Vista podría ver su entrada en el sector empresarial vetada, pero no una próxima versión, especialmente si incorpora tecnologías novedosas. Las capacidades multitactiles junto a otros nuevos añadidos podrían marcar una mayor aceptación del futuro Windows 7. Y puede que Microsoft lo sepa y, consciente de ello, quiera abrir boca a los futuros compradores. La verdad seguramente solo la sabrán Bill Gates, Steve Ballmer, y unas pocas personas de su equipo directivo. Y es que en informática es muy peligroso mostrar las bondades de la futura versión de un producto cuando aún se está vendiendo la versión más reciente. Puede provocar el efecto de que los clientes potenciales dejen de comprar esperando al lanzamiento de la siguiente versión que se les ha mostrado. De hecho, en el acto californiano en el que hablaron de Windows 7, tanto Gates como www.revistasprofesionales.com

Ballmer salieron en defensa de Windows Vista, negando que el lanzamiento del sistema haya sido un error de cálculo de la compañía que presiden y dirigen respectivamente. Ya saben lo que se acostumbra a decir: cuando el río suena, agua lleva...



La Unión Europea da el visto bueno a la adquisición de Trolltech por parte de Nokia, con lo que la operación podrá consumarse. Más información: http://www.nokia.com/ A4136001?newsid=1225376

Más información: Entrevista a Bill Gates y Steve Ballmer - primera parte (en inglés) http://d6.allthingsd.com/20080527/gatesballmer-video-part-1/ Entrevista a Bill Gates y Steve Ballmer segunda parte (en inglés) http://d6.allthingsd.com/20080527/videobill-gates-and-steve-ballmer-highlightreel-part-two/ [1] http://www.imatica.org/bloges/2008/ 04/12048412008.html [2] http://windowsvistablog.com/blogs/ windowsvista/archive/2008/05/27/microsoftdemonstrates-multi-touch.aspx [3] http://wepokers.blogspot.com/2008/05/ microsoft-confirms-windows-7-for-2010.html

Noticias Breves



HP y Acer, dos de los principales fabricantes de PC's del mundo por volumen de ventas, se enfrentan en los tribunales por presuntas violaciones de patentes de las que se acusan mutuamente. Más información: http://www.reuters.com/article/tech nologyNews/idUSN0839609920080609  La saga de juegos de estrategia y simulación histórica Civilization, creada por el aclamado Sid Meyer, llega a un nuevo episodio titulado Revolution, que además de la tradicional plataforma PC también estará disponible para diversos modelos de videoconsolas. Más información: http://www. civilizationrevolution.com/

 Según informa la publicación online eWeek, Microsoft podría hacer pública la segunda beta de Internet Explorer 8 este próximo agosto. Más información: http://www.microsoftwatch.com/content/web_services_browser /coming_soon_ie_8_public_beta.html





Programador crea una shell (una interfaz de comandos) para las funcionalidades que proporciona Google. Esta shell puede ejecutarse desde cualquier navegador web, y es similar a la línea de comandos de Unix/Linux. Más información: http://www.goosh.org/  Informe realizado en los Estados Unidos augura que Google y Amazon serán dos de las compañías que dominarán el mercado de Internet en un futuro próximo, mientras que jugadores como Yahoo! verán su posición comprometida. Más información: http://www.reuters.com/article/technology News/idUSN0232735820080603  Apple anuncia que el iPhone SDK ha sobrepasado las 250.000 descargas desde su lanzamiento el pasado 6 de Marzo.

Anunciada Voltalinux 2.1, distribución basada en Slackware pero que utiliza el sistema de paquetes pkgsrc de NetBSD, lo que le proporciona casi 6.000 paquetes de software procedentes de dicho sistema operativo. Esta nueva revisión se basa en Slackware 12.1. Más información: http:// voltalinux.sicurezzarete.com/?p=39  Según informaciones no confirmadas oficialmente, Nokia pondrá a la venta nuevos ejemplares de teléfonos de la serie E, concretamente los modelos E66 y E71. Más información: http://www.reuters.com/article/ technologyNews/idUSHEL00649420080609  Nvidia pone a disposición de los usuarios el software Gelato Pro 2.2 de renderización que a partir de ahora se ofrece de forma gratuita. Más información y descarga: http://www.nvidia.com/page/gz_home.html Autor: Guillem Alsina - guillem@imatica.org 11

SOLO PROGRAMADORES nº 162


Javahispano:Javahispano

16/6/08

10:07

Página 12

JAVAHISPANO

Actualidad Java de la mano de javaHispano Publicada la especificación de los Servlet 3.0, el JSR 315 Desde su concepción, el API de los Servlet ha sido la más usada en el mundo de Java EE. Desde su primera versión, apenas ha sufrido cambios relevantes. Sin embargo la versión 3.0 de la especificación traerá cambios significativos, comparables con aquellos que sufrió EJB en su versión 3, orientados a facilitar la tarea del desarrollador. Uno de los más notables será la sustitución del monolítico web.xml por los denominados fragmentos web. Hasta la versión 2.0, para definir nuevos servlets y componentes web (listeners, filters, etc) había que editar el fichero web.xml de la aplicación. Esto también suponía que para emplear la mayoría de los frameworks web era necesario declarar el Servlet FrontController de los mismos, o incluso listeners y filters. En Servlets 3.0 la especificación permitirá usar varios web.xml en una misma aplicación, de forma que al instalar un framework web, el web.xml con los elementos necesarios para dicho framework podrá estar dentro del .jar que lo contiene y al iniciar el contenedor, éste será el encargado de juntar dichos web.xml para formar uno sólo. Otra novedad es el uso anotaciones para construir los Servlets, de forma que un servlet será un POJO anotado con "@Servlet". La especificación también proporciona soporte para Servlets asíncronos, que permitirán procesar peticiones HTTP de modo asíncrono, proporcionando soporte a la construcción de aplicaciones Comet (o reverse Ajax) usando directamente el API de Servlets. Otras mejoras al API son el añadir a la clase HTTPServletRequest los métodos login y logout y a la de HttpServletSession logout; con el fin de permitir la autenticación de forma programática.

Sun anuncia Java Card 3.0 Platform Specification Recientemente Sun Microsystems ha anunciado la versión 3.0 de la especificación Java Card. La principal novedad es que en este caso la especificación cuenta con dos "ediciones" (quizá deberían haber elegido la palabra "perfiles" por ser la que ya se emplea para Java ME y la que se va a emplear para Java EE 6). La edición Clásica es una evolución de la versión 2.2.2 de Java Card. Sus novedades son correcciones de bugs, mejores algoritmos de seguridad y una definición más clara de ciertos puntos oscuros de la anterior especificación. La otra edición, que más que una simple evolución podría considerarse una pequeña revolución, se llama "Edición Conectada" (Connected Edition) y cuenta con una nueva máquina virtual y mejoras sustanciales en el entorno de ejecución. Está orientada a dispositivos más potentes que la anterior y contiene nuevas funcionalidades orientadas a interaccionar con el dispositivo a través de la red, como soporte para aplicaciones web (incluidos los Servlets) y soporte para Applets más potentes que la edición clásica. Desde su creación, en 1997, hasta la fecha se han distribuido más de 3.500 millones de JavaCards. En la actualidad estos dispositivos se usan para multitud de aplicaciones, desde DNI electrónicos o tarjetas prepago hasta como SIMs de terminales móviles.

SOLO PROGRAMADORES nº 162

12

www.revistasprofesionales.com


Javahispano:Javahispano

16/6/08

10:07

Página 13

JAVAHISPANO

Actualidad Java de la mano de javaHispano

TagsMe GUI: un entorno de desarrollo para Java ME

OPINIÓN

¿Resurgirán de las cenizas? No estoy hablando de ningún ave mitológica, ni mucho menos, hablo de los legendarios Applets. Muchos los conocen, y hay gente que cree que Java son los Applets. El problema que se vio cuando empezaron es que eran lentos, pesados y consumían muchos recursos. Eso hizo que se rezagara su uso a simples ejemplos de algunas animaciones físicas o matemáticas y algunos efectos visuales. ¿Han cambiado desde entonces? A simple vista no, pero lo que muchos desconocen es que los Applets han evolucionado mucho en los últimos años. Sun les ha prestado atención de nuevo y ahora tenemos

TagsMe (http://www.tagsme.net) es un motor de aplicaciones móviles cuyo propósito es permitir crear aplicaciones compatibles con los principales modelos de terminales móviles, eliminando así la necesidad de creación de diferentes versiones de la aplicación para diferentes fabricantes/modelos/resoluciones de pantalla. La plataforma TagsMe proporciona un lenguaje XML para la definición de pantallas, un simple lenguaje de script similar a Java, un motor que interpreta los ficheros TagsMe en tiempo de ejecución y un entorno de desarrollo basado en NetBeans. Con TagsMe es posible empaquetar toda la aplicación dentro de un único jar o descargarse e interpretar en tiempo de ejecución los ficheros XML desde un servidor web. Esta solución también proporciona una extensa librería de componentes personalizables.

Borland vende CodeGear, su división de IDEs Después de más de 2 años buscando comprador, Borland ha vendido su división CodeGear a la empresa Embarcadero por 23 millones de dólares. CodeGear es la división encargada del desarrollo de lo que antaño eran los productos insignia de Borland: los IDEs, incluyendo al mítico JBuilder. El bajo (bajísimo) precio de venta, hubiera parecido increíble al principio de esta década por incluir el que en aquel entonces era el entorno de desarrollo Java más empleado, JBuilder. Sin embargo, la imposibilidad de competir con alternativas gratuitas como Eclipse y Netbeans en el campo Java, la desventaja con la que juegan los productos de Borland contra los de Microsoft en .NET, y el abandono de la plataforma Delphi en favor de las anteriores han diezmado lo que en su día eran las joyas de la corona de Borland. Embarcadero se dedica al desarrollo de herramientas para la gestión y diseño de bases de datos. Aún no se han desvelado los planes que esta empresa tiene para los productos de CodeGear, aunque probablemente sus intenciones sean impulsar su negocio de bases de datos apoyándose en las antiguas herramientas de Borland y tomando ventaja de sus clientes.

una JVM veloz, mucho más segura y ligera, que actualmente está en Beta: la Consumer JRE, que arreglara de una vez por todas aquellos problemas que quedan. Por ejemplo, descarga del JRE bajo demanda, aceleración 3D de hardware para renderizar las interfaces y mejor integración con el sistema operativo, entre otros. Y no solo eso, frameworks como PulpCore que se ejecutan sobre Applets permiten tener un rendimiento hasta cuatro veces mayor que Flash, Processing y JavaFX son otros ejemplos y benchmarks como BubbleMark demuestran que Java en los navegadores tiene mucho potencial. En realidad los Applets están renaciendo y, una vez lleguemos a ese punto, veremos Java en los navegadores tanto como en los servidores. Mario Serrano, java.mario@gmail.com

Sobre el autor Abraham Otero (abraham.otero@javahispano.org) es responsable de calidad y miembro de la junta de javaHispano. www.revistasprofesionales.com

13

SOLO PROGRAMADORES nº 162


16-21 MIDDLEWARE(Scrum):MIDDLEWARE(Scrum)

16/6/08

11:56

Página 14

MIDDLEWARE

Scrum (II), Desarrollando ágilmente: Los eventos JAVIER HOLGUERA BLANCO - javier.holguera@gmail.com Titulado en Ingeniería en Informática, Analista/Programador en GMV-SGI.

Este es el segundo y último artículo dedicado a Scrum, un framework de desarrollo ágil. El artículo se centra en sus eventos y en cómo roles y artefactos participan en ellos. En el anterior artículo sobre Scrum, se realizó una panorámica sobre sus características, los roles que pueden ejercer sus participantes y los artefactos que van a utilizar para llevar a cabo dichas responsabilidades. Se dio también una pequeña pincelada sobre los eventos de Scrum, pero es en este segundo artículo donde cada uno de ellos se describe pormenorizadamente. En la descripción de cada evento se va a ver cómo las piezas del puzle, los roles y la documentación de que hacen uso, deben encajar para lograr que el evento se celebre con éxito.

Introducción Como ya se comentó en el anterior artículo, resulta difícil dividir una explicación sobre Scrum en dos partes, sin caer en el error de que alguna de las dos quede falta de contenido. Por esta razón, en el primer artículo se optó por describir de forma general Scrum, profundizando en la forma de gestionar el trabajo que hace este framework, los roles que pueden ejercer sus participantes y los documentos que van a manejar para ejercer correctamente sus responsabilidades. En este segundo artículo se ve de qué forma esta gestión del tiempo, los roles y los documentos, tienen reflejo en cada evento. Se describen cada uno de ellos, indicando qué objetivo tienen, de qué forma deben celebrarse para hacerlo con éxito, y qué roles y documentos van a ser necesarios durante su realización. La primera parte del documento, tras esta sección, trata sobre la forma en que se gestiona el tiempo en los eventos de Scrum y hasta qué punto debe ser riguroso con este aspecto el Scrum Master a la

SOLO PROGRAMADORES nº 162

14

hora de dirigir cada uno de ellos. La segunda sección presenta una panorámica general de todos los eventos de Scrum, indicando algunas de sus características comunes. A continuación se suceden cinco secciones dedicadas a cada uno de los eventos habituales de Scrum. Por último, el artículo se cierra con las habituales conclusiones, extendiéndolas no sólo al contenido de este artículo sino a la saga entera.

Time-Boxing Una de las frases más repetidas en el desarrollo de software es: “Tiempo, presupuesto o calidad, escoja qué dos desea cumplir”. Viene a reflejar la práctica imposibilidad de entregar un proyecto a tiempo, sin salirse del presupuesto y cumpliendo todos los baremos de calidad propuestos. Para ofrecer una solución a este problema, han surgido distintas aproximaciones. El time-boxing es una de ellas y propone fijar una de estas variables, el tiempo, para ver qué lejos se puede llegar en las otras dos. Es decir, partiendo de la idea de que la fecha de entrega es absolutamente inamovible, hacer un desarrollo de la mejor calidad posible sin salirse del coste inicialmente presupuestado. El time-boxing es un concepto que se repite no sólo en cualquier descripción de Scrum, sino que se extiende a la mayoría de metodologías y procesos de desarrollo ágil hoy en día. Sin embargo, es aplicable más allá de las fronteras del desarrollo de software. En el día a día, cualquiera puede recurrir a esta técnica para emprender sus tareas. Basta con plantearse una limitación determinada de tiempo para hacer algo, e intentar llegar lo más lejos posible en su realización. En Scrum el time-boxing se aplica tanto en la gestión del proyecto en sí, como en la forma en que se realizan sus eventos. En cuanto a la gestión, se puede ver claramente en la forma en que se divide el desarrollo en una sucesión de iteraciones con una duración fija e inamovible, los sprints. En lo que respecta a los eventos, la rigidez a la hora de cumplir los horarios propuestos es similar a la existente con las fechas de los sprints. Es preferible que un evento no se complete del todo, a alargarlo más allá de lo necesario en el tiempo. De esta forma, www.revistasprofesionales.com


16-21 MIDDLEWARE(Scrum):MIDDLEWARE(Scrum)

16/6/08

11:56

Página 15

MIDDLEWARE

Scrum (II), Desarrollando ágilmente: Los eventos

siendo inflexibles, en el próximo evento o bien se estimará de forma correcta el tiempo necesario para realizarlo, o bien se aprovechará mejor el tiempo planeado. En cualquier caso, aunque al iniciar una adopción de Scrum se corra el riesgo de intentar ser más laxo con estas restricciones, es sólo gracias a cumplir con severidad sus reglas que se consigue que el framework termine gestionando el tiempo de los participantes de una forma transparente, sin que su utilización resulte una carga para los desarrolladores.

Eventos en Scrum Como ya se ha comentado en la introducción, este segundo artículo está totalmente centrado en los eventos de Scrum, toda vez que tanto los roles como los documentos de que hacen uso, fueron convenientemente descritos en el anterior artículo. Para aquellos que se perdieran el primer artículo de la saga, va este pequeño repaso sobre los tres roles y los dos artefactos más habituales. El rol de Product Owner es ejercido por aquella persona que mejor conozca el producto a desarrollar y, por tanto, el responsable de añadir o eliminar características, siendo también quien debe gozar de la mejor comunicación con el cliente. Ejerce su labor apoyado en el Product Backlog, un artefacto que contiene los requisitos del proyecto. El rol de Scrum Master se asemeja al gestor de proyecto de otros procesos y se encarga de asegurarse de que el equipo, el tercero de los roles, alcance su máxima productividad, eliminando cualquier tipo de impedimento. También gestiona el proceso y realiza un seguimiento de cada iteración o sprint, controlando los progresos que el equipo hace durante el mismo. Su labor la realiza apoyado en el Sprint Backlog, un documento similar al Product Backlog pero centrado en las características que se van a desarrollar durante el sprint. Por último, el equipo engloba a los demás desarrolladores y entre sus responsabilidades se encuentra la auto-organización y la toma de decisiones importantes sobre el desarrollo del proyecto. Su grado de implicación con el resultado del proyecto debe ser el mayor de todos los participantes. En Scrum los eventos rigen el flujo de trabajo que realizan los desarrolladores del proyecto durante el tiempo que dure el mismo. Son los eventos los que articulan las actividades que www.revistasprofesionales.com

Gráfico de artefactos y eventos en Scrum.

realizan los distintos roles, siendo los artefactos o bien el punto de partida de los eventos o bien los que registran los resultados que arrojan sus respectivas realizaciones. Dentro de Scrum se puede observar un esquema que relaciona los eventos y que se repite en cada aplicación del framework. Cada proyecto se compone de una serie de iteraciones, y estas iteraciones empiezan siempre con un evento en el que se planifica el sprint y acaban con otro evento en el que se analizan y muestran los resultados alcanzados. En cada uno de los días de que se compone el sprint se realiza una reunión de seguimiento diaria del estado del sprint, para permitir al gestor controlar de cerca la evolución del trabajo. Este esquema se puede ver reflejado gráficamente en la Figura 1. Estos eventos descritos en el anterior esquema tienen todos ellos nombres concretos, dentro de la terminología de Scrum. La reunión que da comienzo a cada nuevo sprint se conoce como Sprint Planning. En cuanto a la reunión que pone fin a cada sprint, se conoce como Sprint Review, existiendo una segunda parte consistente en la demostración o Demo. Por último, la reunión diaria también recibe una denominación concreta: Daily Scrum. Todos estos eventos comparten los principios del time-boxing, como ya se ha indicado anteriormente. El Scrum Master será el encargado de guiar a los participantes y asegurarse de que se cumplan las reglas propuestas

para cada evento, durante su celebración. En aquellas ocasiones en que el tiempo se agote sin haberse completado del todo el evento, es responsabilidad del Scrum Master la selección de las partes que resten por hacerse, que considere de mayor prioridad. En cualquier caso, esto no deja de ser una situación anómala que se debe evitar en la medida de lo posible. En las siguientes secciones se verá una descripción pormenorizada de cada evento, incluyendo los roles que deben participar, las funciones que cumplirán dichos roles en cada evento y el uso que se hará de los artefactos descritos anteriormente.

Sprint Planning La reunión de planificación o Sprint Planning es el primer evento que se realiza en cada sprint en Scrum. Tiene como fin organizar el siguiente ciclo y definir la cantidad de trabajo que se va a acometer durante el mismo. Prueba de la importancia de este evento es que siempre que no resulta exitosa su celebración, el ciclo suele sufrir gran cantidad de problemas. La Sprint Planning se divide en dos partes. En la primera, el Product Owner y el Scrum Master se reúnen para decidir qué características del producto se desarrollarán en el sprint. En la segunda, el equipo se une a la reunión y se estima el tiempo que llevará la realización de las características selecciona15

SOLO PROGRAMADORES nº 162


16-21 MIDDLEWARE(Scrum):MIDDLEWARE(Scrum)

16/6/08

11:56

Página 16

MIDDLEWARE

das en la primera parte del evento, con el fin de alcanzar un compromiso sobre la cantidad de trabajo a acometer. En la primera parte de la reunión el Product Owner y el Scrum Master se reúnen alrededor del Product Backlog, puesto que de este artefacto es de dónde se saca la información sobre las características que hay que construir en el siguiente sprint. Para todos aquellos ítems cuya prioridad les convierta en candidatos a desarrollarse durante la siguiente iteración, es imprescindible que todos sus campos de información estén completados. En la Figura 2 se puede ver cómo interactúan los distintos roles y artefactos que participan en el evento. Juntos, el Scrum Master y el Product Owner, deciden las características a elaborar en el siguiente ciclo, estimando qué cantidad de tiempo puede llevar cada una para saber cuántas pueden incluir en el sprint. Sin embargo, estas estimaciones deben ser ratificadas por el equipo, puesto que es quien tiene la última palabra a este respecto siempre. Como ya se explicó en el primer artículo, en Scrum las decisiones al respecto de cómo construir el producto y en qué plazos realizarlo, deben ser tomadas por el equipo puesto que nadie mejor que los desarrolladores para saberlo. Son estas personas, las que día a día trabajan para alcanzar los objetivos del proyecto y los que, por tanto, más comprometidos están con la consecución de las metas marcadas, los más indicados para tomar estas decisiones. El resto de participantes en el proyecto, el Product Owner, el Scrum Master y otras personas interesadas o implicadas, deben respetar lo que decida el equipo, dentro de los límites propios de la jerarquía de la organización. Durante la segunda reunión, el subconjunto de funcionalidad elegido del Product Backlog se transforma en el Sprint Backlog que utilizará el Scrum Master durante el siguiente ciclo de desarrollo. Para permitir ajustar al máximo las estimaciones de tiempo de cada ítem realizadas por el equipo, se sigue un proceso de descomposición de los ítems en actividades. Como ya se mencionó en el primer artículo, los ítems representan las características del producto y están expresados en el lenguaje de negocio del dominio de la aplicación. Por ejemplo, un ítem cualquiera de muchos proyectos podría ser “Identificación de usuarios de aplicación”. En esta denominación no encontramos términos técnicos que puedan

SOLO PROGRAMADORES nº 162

16

Participantes en la reunión de planificación (extraído de navegapolis.net)

requerido de un informático para comprender qué va a hacer esa característica. Un ítem así, durante la Sprint Planning previa al ciclo en el que fuera a ser elaborado, sería analizado por los desarrolladores y descompuesto en una serie de actividades, como por ejemplo: “Formulario web recogida de datos”, “Validación campos usuario”, “Recuperación información usuario en BD”, “Pruebas unitarias”, “Documentación requisito”, etc. Como se puede ver, los nombres de las actividades sí se expresan en un lenguaje técnico, puesto que quienes van a gestionarlas son los miembros del equipo (junto al Scrum Master). Todas juntas conformarán el trabajo necesario para tener el ítem terminado. A cada una de estas actividades se le asigna una duración en mandays, la unidad utilizada para medir el esfuerzo en Scrum. En el anterior artículo ya se apuntó que un manday se corresponde con el trabajo realizado por una persona durante un día, por lo que un ítem que requiere de dos personas trabajando cinco días, correspondería con diez mandays. La suma de los mandays de todas las actividades corresponde con la cantidad de trabajo asignado al ítem y tiene su reflejo en el Sprint Backlog que manejará el Scrum Master durante el ciclo. Existen otras informaciones que tienen que concretarse durante la reunión de planificación. Una de las más importantes es el Sprint Goal u objetivo del sprint. Este objetivo debe reflejar la razón de ser del sprint, es decir, el porqué el equipo está realizando el trabajo. Durante un sprint que esté dedicado fundamentalmente a la mejora de la robustez y calidad de la aplicación, un posible objetivo sería “Fortificar la aplicación”. Debe servir al equipo para mantenerse focalizado durante su trabajo y no perderse en nuevas tareas u

actividades complementarias que, aunque relacionadas con el trabajo que están realizando, no entran dentro del objetivo del sprint y, por tanto, deben ser pospuestas. Toda la información que se concrete durante la reunión debe ser publicada por el Scrum Master en una localización que permita su consulta por cualquier persona de la organización interesada en el proyecto. Scrum anima a hacer el desarrollo lo más transparente posible a los demás estamentos de la organización, puesto que dicha transparencia mejorará la comunicación.

Daily Scrum La Daily Scrum o reunión diaria es un evento celebrado cada día durante los sprints, en la que participan el Scrum Master y los miembros del equipo. La asistencia a otros participantes del proyecto está abierta, aunque con una restricción: no pueden tomar la palabra, sólo asistir como oyentes. La sucesión de distintas reuniones diarias, junto con el trabajo realizado cada día, es lo que compone un sprint. En la Figura 3 se puede ver reflejada dicha composición, resultando del proceso el correspondiente incremento de funcionalidad. La silueta roja representa a los “interesados” en el proyecto, aquellas personas que no participan directamente en el proceso de desarrollo pero tienen necesidad de conocer su estado. Durante esta reunión el Scrum Master recibe información sobre la situación del proyecto, en boca de los miembros del equipo. A cada uno de ellos se le plantean tres preguntas que deben responder: qué hizo el día anterior, qué hará a lo largo del día actual y qué dificultades se está encontrando. Con estas sencillas preguntas, planteadas a cada desarrollador, el www.revistasprofesionales.com


16-21 MIDDLEWARE(Scrum):MIDDLEWARE(Scrum)

16/6/08

11:56

Página 17

MIDDLEWARE

Scrum (II), Desarrollando ágilmente: Los eventos

Scrum Master se facilita la consecución de dos de sus obligaciones, como son conocer el estado del desarrollo y trabajar para eliminar los impedimentos que pueda tener el equipo y que le impidan alcanzar su máxima productividad. Durante la reunión, mientras un miembro responde a las preguntas, el resto debe permanecer en silencio, atentos a sus respuestas. En caso de que, al hablar del trabajo que va a acometer en el día, se nombre un tema en el que estén interesados otros miembros del equipo, se puede plantear la necesidad de realizar, tras la Daily Scrum, una Follow-Up Meeting, un tipo de evento del que se hablará más adelante. Es importante que durante la Daily Scrum no se trate ningún tema distinto a los tres puntos antes comentados, para hacerla lo más concisa posible y evitar que los participantes pierdan la concentración o el interés. Durante esta reunión (o al finalizarla), el Scrum Master debe actualizar el Sprint Backlog. Los miembros del equipo indicarán sus progresos con respecto a las características que estén desarrollando. Siempre que se finalice una actividad de uno de los ítems elaborados, se le informará al Scrum Master para que reste, en el Sprint Backlog, la cantidad de tiempo que tenía asignada la actividad, al total de trabajo que queda por hacer del ítem. En caso de completarse la última de las actividades de que se componga un ítem, se dará el mismo por finalizado. Esta actualización puede ser realizada por los miembros del equipo, en caso de utilizarse una aproximación “física” a la gestión del Sprint Backlog. Como ya se indicó en el ante-

rior artículo, en muchas implantaciones de Scrum se está combinando el clásico fichero de hoja de cálculo para almacenar la información del Sprint Backlog, con una versión real o manual del mismo. Esta versión se suele componer de un panel y una serie de tarjetas que representan los ítems que se van a elaborar durante el sprint. En estas tarjetas se apunta toda la información del ítem, incluidas las estimaciones de tiempo, y se acompañan de pegatinas o papeles adhesivos que representan las actividades que componen el ítem. Los papeles llevan escritas sus estimaciones de tiempo y el nombre de la actividad correspondiente. Al finalizar una de ellas, el desarrollador responsable de su elaboración es el encargado de darla por completada, actualizando la cantidad de tiempo que, finalmente, le llevó su elaboración. Con esto se mejora la interacción del equipo con el Sprint Backlog y se le mantiene más atento durante las reuniones diarias. La Figura 4 muestra un ejemplo del Sprint Backlog en su versión física. Una vez que la reunión ha concluido, el Scrum Master debe proceder a actualizar el Sprint Backlog Graph. Este gráfico representa la evolución de la cantidad de trabajo que resta por hacer en cada sprint, siendo por tanto un gráfico descendente. Gracias a él, de un solo vistazo, es posible para cualquier participante medir la salud del sprint y conocer hasta qué punto las expectativas se están cumpliendo o, por el contrario, la cantidad de trabajo estimada es superior a la que se está pudiendo completar. También existe la posibilidad de que, por el contrario, la cantidad de trabajo disminuya más rápidamente de lo

Participantes de la reunión diaria (extraído de navegapolis.net).

www.revistasprofesionales.com

esperado. En tal caso se abre la puerta a introducir nuevos ítems en el sprint, con el objeto de no tener al equipo parado hasta terminarse el ciclo.

Sprint Review La reunión de revisión o Sprint Review es un evento celebrado al final de cada sprint. Como su propio nombre indica, sirve para realizar una revisión o análisis a posteriori del sprint y de sus resultados. Durante este evento participan el Scrum Master, el Product Owner y el equipo. Juntos realizan una retrospectiva del sprint, planteándose cómo ha ido evolucionando, los problemas que se han ido sucediendo y los resultados que, finalmente, se han podido alcanzar. Todo ello, comparándolo con las previsiones y compromisos que se plantearon durante la reunión de planificación que dio origen a dicho sprint. El artefacto básico que se utiliza en esta reunión es el Sprint Backlog (junto con el gráfico que le acompaña). El carácter a modo de “bitácora del sprint” que tiene este artefacto, lo hace perfecto para ayudar al equipo a la hora de revisar y recordar los distintos sucesos acontecidos durante el ciclo de desarrollo, muchos de los cuales habrán tenido un reflejo en el Sprint Backlog. Todo aquello que haya perturbado de algún modo al equipo, se habrá visto reflejado en su productividad y, por tanto, apuntado convenientemente en el Sprint Backlog y en su gráfico. La Figura 5 muestra a los participantes de este evento y la demo, del que se hablará en la siguiente sección. Los temas a tratar durante esta reunión son libres, aunque algunos puntos comunes suelen aparecer en todas las implementaciones que se hacen de Scrum. Uno de estos puntos compartidos por la mayoría de reuniones de revisión es el pulsar la opinión de los miembros al respecto de qué ha ido bien y qué ha ido mal a lo largo del sprint. La primera parte sirve para recopilar aquellas acciones que se han considerado beneficiosas para el sprint y para el trabajo diario, con el claro objetivo de seguir repitiéndolas en sucesivos ciclos. La recopilación de las cosas que han ido mal o, al menos, no como se esperaba, debe servir para corregir dichas conductas en futuros sprints y convertir los problemas en aspectos positivos. No siempre es necesario tomar una acción concreta para resolver un problema que aconteció durante un sprint, puesto que en muchas ocasiones el simple hecho de 17

SOLO PROGRAMADORES nº 162


16-21 MIDDLEWARE(Scrum):MIDDLEWARE(Scrum)

16/6/08

11:56

Página 18

MIDDLEWARE

sus participantes de cualquier distracción o injerencia, al tiempo que la lejanía con el lugar del trabajo les permite opinar con más libertad de aquello que realmente no les gusto o que sintieron que les perjudicaba en su labor diaria.

Demostración

Foto de un Sprint Backlog real.

hablar de ello durante esta reunión, sirve para que los participantes tomen buena nota para sucesivos sprints y eviten incurrir de nuevo en los mismos errores. Esta reunión es también una oportunidad de recoger ideas sobre cómo se podría mejorar el proceso. El Scrum Master tiene la posibilidad de conocer, de boca de los demás participantes en el proyecto, cómo mejorarían ellos el proceso y qué cambios introducirían para lograr mejores resultados en futuros sprints. El Scrum Master debe tener muy en consideración las sugerencias que se le hagan, puesto que sólo mediante una clara atención a las propuestas y un ánimo de llevarlas a cabo más adelante, se conseguirá dar sentido a la participación y la opinión de los miembros del equipo durante sucesivas reuniones de revisión. El equipo debe sentirse importante y decisivo en la organización y ejecución del trabajo. Aunque Scrum no indica como obligatorio el registrar los resultados de la reunión en ningún tipo de documento, sí que es muy conveniente hacerlo, especialmente a la hora de poder analizar varios sprints y ver cómo ha sido la evolución de sus resultados. Por tanto, es muy recomendable que el Scrum Master o cualquier miembro del equipo que se ofrezca a realizar el papel de secretario, apunte en un documento todo lo tratado en la reunión. En este documento, posteriormente, el Scrum Master también debe dedicar un apartado a los resultados de velocidad del equipo durante el sprint. Al comienzo de cada ciclo, duran-

SOLO PROGRAMADORES nº 162

18

te la reunión de revisión, se hace una estimación de la velocidad que va a alcanzar el equipo, es decir, de la cantidad de ítems que cree que puede terminar en el espacio de tiempo del sprint. Evidentemente, al finalizar el sprint y revisarlo, la velocidad finalmente lograda es uno de los aspectos a considerar. Por tanto, se ha de hacer un contraste entre lo estimado y lo conseguido. Del análisis del factor de correlación entre ambas cifras, se saca para futuros ciclos un multiplicador que permita reducir la velocidad teórica del equipo. Con este factor lo que se busca es realizar estimaciones de velocidad lo más realistas posibles, que pueda cumplir el equipo. Uno de los aspectos más curiosos pero, a la vez, importantes, de la reunión de revisión es la localización en que debe realizarse esta reunión. A diferencia del resto de eventos, que se celebran en el lugar de trabajo de los miembros del proyecto, la Sprint Review debe realizarse fuera de las oficinas de trabajo, preferiblemente en un ambiente relajado y distendido. La razón de este cambio de localización es la necesidad de mantener al equipo ajeno a cualquier tipo de distracción durante el evento. Para lograr celebrar con éxito esta reunión, es muy importante que los participantes puedan recordar con la mayor nitidez posible los sucesos que han acontecido durante el sprint. Puesto que la base del evento es la introspección y el recuerdo de los días que han compuesto el ciclo de desarrollo, no es posible celebrar con éxito la reunión si no se aísla a

Aunque la demostración y la revisión del sprint suelen ser inmediatas en el tiempo y, por tanto, podría considerarse a ambas como un único evento, las diferencias son tantas que es preferible tratarlas como dos distintos. Además, es posible que por las peculiaridades propias de un proyecto u organización determinada, no sean consecutivas en el tiempo, debiéndose aplazar la demostración hasta que todos los implicados puedan estar presentes. En la demostración el equipo, con el Scrum Master a la cabeza, muestra al cliente y al resto de la organización, los avances que se han realizado durante el último ciclo de desarrollo. La principal razón para realizar este evento es la valía del feedback que obtiene el equipo procedente del cliente, una vez ha visto lo último que se ha desarrollado. Gracias a este feedback, el equipo puede tener la seguridad de que lo construido es lo que realmente deseaba el cliente o, por el contrario, que son necesarias una serie de correcciones para satisfacer sus demandas. Por otra parte, el cliente tiene una buena oportunidad de proponer nuevas características para el producto, una vez que ya ha visto el estado en el que se encuentra actualmente, así como reorganizar sus prioridades con respecto a los ítems que ya ha había propuesto con anterioridad. Otro de los beneficios de este evento es que obliga al equipo a terminar totalmente las características. De lo contrario, se corre el riesgo de tener grandes cantidades de ítems que están “prácticamente terminados” pero que, de hecho, nunca alcanza el estado de completado. En Scrum, a la hora de medir la velocidad que ha alcanzado el equipo, sólo se toman en consideración aquellos ítems que se terminaron totalmente, por lo que es preferible que el equipo termine totalmente un número menor de características, a que desarrolle un número mayor en un estado cercano al final pero sin alcanzarlo. Los miembros del equipo no van a querer presentar una característica que no estén seguros de que funcione y esté lo suficientemente probada, www.revistasprofesionales.com


16-21 MIDDLEWARE(Scrum):MIDDLEWARE(Scrum)

16/6/08

11:56

Página 19

MIDDLEWARE

Scrum (II), Desarrollando ágilmente: Los eventos

dada la audiencia que van a tener durante el evento. Ese será motivo más que suficiente para que se esfuercen en alcanzar una alta madurez para la funcionalidad demostrada, suficiente como para pasarla a producción, una vez alcanzado el visto bueno del cliente. Existen otros efectos positivos que extraer de este evento, como sería la visibilidad que da al proyecto, puesto que quién esté interesado en él podrá asistir, periódicamente, a las demostraciones y comprobar cómo va evolucionando. También es una oportunidad para que, en caso de existir más equipos en la empresa, compartan experiencias, comentarios e información. A la hora de realizar el evento, el Scrum Master debe tener en cuenta algunos puntos importantes. El primero de ellos es que toda la presentación debe realizarse a nivel del lenguaje de negocio y, por tanto, debe estar enfocada a qué se ha hecho y no a cómo se ha hecho. Los asistentes quieren oír hablar sobre las novedades del producto, no sobre cómo los desarrolladores han conseguido crear dichas novedades. En caso de que alguno de los asistentes no conozca el producto, es conveniente realizar una breve introducción sobre el mismo, ofreciendo una descripción de qué se está construyendo en el proyecto y con qué objetivos. Por último, es muy aconsejable que ni el Scrum Master ni los desarrolladores inviertan mucho tiempo en preparar el evento. Es decir, deben evitarse coloridas presentaciones o complejos gráficos. Simplemente centrarse en transmitir lo que se ha hecho y, sobretodo, en enseñarlo en funcionamiento. En caso de haber la posibilidad, resulta muy interesante que los asistentes puedan probar por si mismos las novedades, puesto que así el valor del feedback se incrementa aún más. Para terminar esta descripción sobre el evento de demostración, es muy importante que los desarrolladores tengan claro que este evento es “inexcusable”. No importa si hay pocas características que mostrar o si no se sienten cómodos del todo con el trabajo desarrollado durante el último sprint. Pase lo que pase, la demostración se debe realizar y el equipo debe saber que así será. Si tras un sprint el equipo realiza una demostración en la que se siente incómodo por tener pocas características que presentar, esto servirá de incentivo para, en el siguiente, mejorar la imagen ofrecida con más funcionalidad.

Follow-Up Meetings

www.revistasprofesionales.com

Participantes de la reunión de revisión (extraído de navegapolis.net)

Con este término Scrum denomina a las reuniones informales que se realizan entre varios desarrolladores para tratar un tema concreto del proyecto que les afecta. Como se comentó en la explicación sobre la reunión diaria, suele ser durante este evento cuando se acuerda su realización. Si mientras uno de los desarrolladores comenta en lo que va a trabajar hoy, otros se muestran interesados o afectados por ese trabajo, pueden ponerse de acuerdo, de la forma más breve posible para no entorpecer la reunión diaria, para más tarde reunirse y tratar el tema entre todos juntos. Gracias a este tipo de evento, la reunión diaria puede mantener sus tiempos bajo los mínimos prescritos por Scrum. Sin embargo, la ausencia de reglas concretas en Scrum sobre cómo realizar las Follow-Up Meetings, junto con las pocas líneas que los autores más relevantes les han dedicado, no deja de señalar a este evento como un “ciudadano de segunda clase” dentro de los eventos de Scrum.

ellas precisamente trazadas para controlar el desarrollo de un proyecto software sin interferir con el recurso más preciado que cuenta todo gestor, su equipo de desarrolladores. Scrum cumple con su naturaleza ágil y centra el foco de atención en el equipo, en las personas que trabajan día a día para sacar adelante el proyecto. Son ellos los importantes y no la documentación o el propio proceso. Pero Scrum también es una oportunidad para una organización que haya decidido adoptarlo. Si la organización se impregna de la filosofía que emana de Scrum, podrá responder con mayor velocidad a los desafíos diarios que el mercado y el negocio le plantee. Porque si hubiera que describir Scrum con una única palabra, probablemente sería “adaptación”.

Referencias 

Conclusiones Si tras el primer artículo sobre Scrum el lector pudo tener una panorámica clara de cuáles eran las piezas del framework, entiendo piezas por los roles y documentos que se manejan, no habrá sido hasta este segundo artículo cuando ha podido constatar cómo estas piezas encajan con precisión para formar este puzle que, cada día más, se impone como un estándar entre los procesos ágiles en todo el mundo. Scrum es la agilidad llevada a sus cotas más altas, con muy pocas reglas si se compara con los procesos clásicos, pero todas

 





Corral, R. (s.f.). La Masa, El Ladrillo, La Bota, El Bocadillo... Obtenido de La Masa, El Ladrillo, La Bota, El Bocadillo...: http://geeks.ms/ blogs/rcorral/ Kniberg, H. (2007). Scrum And XP From Trenches. InfoQ. Palacios, J. (s.f.). Navegapolis.net. Obtenido de Navegapolis.net: http://www.navegapolis.net/ Schwaber, K. (2004). Agile Project Management With Scrum. Microsoft Press. Schwaber, K., & Beedle, M. (2001). Agile Software Development With Scrum. Prentice Hall.

19

SOLO PROGRAMADORES nº 162


REDES-RSS Java 1:REDES-RSS Java 1

16/6/08

11:59

Página 20

REDES

RSS con Java III Los documentos RSS pueden servirse de forma optimizada sacando provecho de todos los recursos que ofrece el propio protocolo HTTP, empezando por la compresión de datos que transfieren al cliente. Además empleando la caché en el servidor, la caché en el cliente y las cabeceras HTTP, se crea una arquitectura que reduce la carga de trabajo. Con ello la aplicación está lista para servir más documentos RSS, en menor tiempo.

ADOLFO ALADRO GARCÍA

HTTP Compression

Material adicional El material complementario puede ser descargado desde nuestra web www.revistasprofesionales.com

SOLO PROGRAMADORES nº 162

20

Cualquier aplicación Web puede utilizar HTTP Compression de forma que el contenido que devuelve el servidor en cada llamada está comprimido con el algoritmo gzip. Muchos portales y servicios emplean la compresión. Las páginas llegan comprimidas al navegador y éste las descomprime automáticamente antes de mostrarlas. Todo ocurre de forma transparente al usuario. Este mecanismo ofrece dos ventajas principales. La primera es que se consume menor ancho de banda ya que el número de bytes a transmitir entre el servidor y el navegador es menor. La segunda es que también se reduce el tiempo que tardan en cargarse las páginas. No todos los datos que se comprimen con gzip se reducen notablemente pero cuando se trata de texto, como es el caso de las páginas HTML o de los propios documentos RSS, la reducción es muy alta. Por lo tanto resulta muy conveniente el empleo de HTTP Compression. El servlet SRssServer6 es una versión avanzada del servlet SRssServer5 que utiliza compresión. El tratamiento del documento y la caché son idénticos. La diferencia principal llega cuando realmente van a escribirse los datos por el canal de escritura típico de los servlets. El primer paso consiste en consultar si el cliente que solicita el documento RSS admite la compresión. Para ello

se obtiene la cabecera HTTP denominada AcceptEncoding: String sAcceptEncoding = req.getHeader(“Accept-Encoding”);

El método getHeader, de la interfaz HttpServletRequest del API estándar, recibe como parámetro el nombre de la cabecera HTTP y devuelve una cadena de texto con el valor de dicha cabecera, o null en caso de que no exista. Por consiguiente si el valor devuelto es distinto de null y contiene la cadena gzip, el cliente admite compresión: boolean bHttpCompression = sAcceptEncoding!=null && (sAcceptEncoding.toLowerCase().indexOf (“gzip”) != -1);

El esqueleto del código responsable de generar los datos a enviar es una estructura try…catch…finally en la que se garantiza que se liberan los recursos con independencia de lo que suceda durante la ejecución: ByteArrayOutputStream baos = null; GZIPOutputStream gzipos = null; OutputStreamWriter osw = null; try { ··· } catch (Exception e) { e.printStackTrace(); } finally { try {if (osw!=null) osw.close(); osw=null;} catch (Exception e) {} try {if (gzipos!=null) gzipos.close(); gzipos=null;} catch (Exception e) {} try {if (baos!=null) baos.close(); baos=null;} catch (Exception e) {} }

El canal de escritura de tipo ByteArray OutputStream se encarga de almacenar en un buffer interno todo lo que recibe de forma que posteriormente los datos pueden obtenerse en forma de array de bytes. El canal de tipo GZIPOutputStream se utiliza para comprimir automáticamente. Finalmente el canal OutputStreamWriter permite hacer la interconexión necesaria entre la escritura orientada de cadenas de texto y la escritura de bytes. La iniwww.revistasprofesionales.com


REDES-RSS Java 1:REDES-RSS Java 1

16/6/08

11:59

Página 21

REDES

RSS con Java (III)

cialización de estos canales, dentro de la cláusula try debe tener en cuenta el valor de bHttpCompression obtenido anteriormente: baos = new ByteArrayOutputStream(); if (bHttpCompression) { gzipos = new GZIPOutputStream(baos); osw = new OutputStreamWriter(gzipos, Charset.forName(“UTF-8”)); } else { osw = new OutputStreamWriter(baos, Charset.forName(“UTF-8”)); }

La variable baos se inicializa empleando el constructor simple de la clase ByteArray OutputStream. Si el cliente admite compresión entonces se crea el canal de escritura de tipo GZIPOutputStream de forma que el constructor toma como parámetro el canal anterior. Asimismo se inicializa la variable osw, el canal de escritura orientado a caracteres, empleando el canal de escritura orientado a bytes y con compresión, e indicando el juego de caracteres que se emplea. Si bHttpCompression es false entonces el canal de escritura orientado a caracteres se crea simplemente a partir del canal ByteArrayOutputStream. El proceso de escritura del documento RSS es idéntico al que se ha venido empleando en los ejemplos anteriores. El método toString de la interfaz RssDocument Cacheable devuelve una cadena de caracteres conteniendo el código XML correspondiente al documento RSS. El método write del canal de escritura orientado a caracteres escribe dicha cadena. Finalmente el método flush garantiza que los buffer internos se vacían y todos los datos son realmente escritos en la salida: osw.write(rssDocCacheable.toString());

Página de la Wikipedia dedicada a la compresión HTTP (HTTP Compression): en.wikipedia.org/wiki/HTTP_compression. if (bHttpCompression) { gzipos.flush(); gzipos.finish(); }

El último paso dentro de la cláusula try consiste en obtener el array de bytes. baos.flush();

bos = new BufferedOutputStream

data = baos.toByteArray();

(res.getOutputStream());

Obsérvese que si el cliente admite HTTP Compression ese array de bytes contiene el código XML correspondiente documento RSS comprimido con gzip. En caso contrario contiene el código XML tal cual, pero en forma de array de bytes, y no de cadena de caracteres. Antes de pasar a escribir la salida del servlet resta ajustar la cabecera HTTP si se está empleando compresión. La primera cabecera que se establece es Content-Length y su valor es el número de bytes que van a escribirse. La segunda es Content-Encoding y su valor es gzip. Esta cabecera indica al cliente que los datos están comprimidos empleando gzip de forma que debe descomprimirlos antes de hacer nada con ellos:

www.revistasprofesionales.com

bos.write(data); bos.flush();

Evidentemente al emplear HTTP Compression también se añade una carga adicional en el servidor, en el sentido de que tiene que comprimir los datos antes de enviarlos al cliente. Sin embargo el coste de esta tarea adicional merece la pena en comparación con el ahorro de ancho de banda y tiempo de transmisión. Además, los algoritmos modernos de compresión de datos están bastante optimizados por lo que la carga real que se añade no es tampoco muy alta.

Compresión en la Caché

if (bHttpCompression) {

osw.flush();

La diferencia principal con respecto a los ejemplos anteriores es que en este caso sabemos que los datos no se están mandando al cliente todavía sino que se están almacenando internamente en forma de bytes mediante el canal ByteArray OutputStream. Si el cliente admite compresión, además de las sentencias anteriores es necesario ejecutar los métodos flush y finish del canal GZIPOutput Stream para que los datos comprimidos tengan el formato correcto:

servlet orientado a bytes. Éste se emplea para inicializar un canal de escritura con buffer interno como es el canal de tipo BufferedOutputStream. Se escribe el array de bytes y se llama al método flush para garantizar que los buffer internos se liberan y todos los datos se escriben en la salida:

res.addHeader(“Content-Length”, Integer.toString(data.length)); res.addHeader(“Content-Encoding”, “gzip”); }

La cabecera que indica el tipo de los datos no cambia en ningún caso, y sigue estableciéndose: res.setContentType(“text/xml; charset=UTF-8”);

Por último, con el método getOutput Stream se obtiene el canal de escritura del

En el apartado anterior se ha visto cómo comprimir los datos dinámicamente cuándo van a servirse. Teniendo en cuenta que los documentos RSS se sirven empleando una caché representada por la clase RssDocumentCache puede ser interesante contemplar la posibilidad de que en la propia caché se guarde el array de bytes correspondiente al código XML comprimido en vez de la cadena de texto sin comprimir. La ventaja de hacerlo de esta manera es evidente. La caché es en última instancia un conjunto de datos que se guardan en la memoria del servidor. Si estos datos están 21

SOLO PROGRAMADORES nº 162


REDES-RSS Java 1:REDES-RSS Java 1

16/6/08

11:59

Página 22

REDES

la cabecera Content-Encoding y es el propio servidor de aplicaciones el que establece dinámicamente la cabecera ContentLength, que guarda el número de bytes necesarios para almacenar la cadena de texto correspondiente al código XML del documento RSS: Server: Resin/3.0.13 Expires: Wed, 31 Dec 1969 23:59:59 GMT Cache-Control: no-cache Pragma: no-cache Content-Type: text/xml; charset=UTF-8

Cabeceras HTTP devueltas por el documento rss5.xml (No utiliza HTTP Compression).

Content-Length: 2125 Date: Sun, 04 May 2008 04:32:55 GMT 200 OK

En el segundo caso la cabecera ContentEncoding tiene el valor gzip. Así por ejemplo, un navegador que reciba esta respuesta sabe que antes de hacer nada con los datos debe descomprimirlos. El valor de Content-Length aquí sí ha sido establecido explícitamente desde la programación del servlet: Server: Resin/3.0.13 Expires: Wed, 31 Dec 1969 23:59:59 GMT

Cabeceras HTTP devueltas por el documento rss6.xml (Sí utiliza HTTP Compression).

Cache-Control: no-cache

comprimidos la memoria necesaria para mantener la caché es menor o si se prefiere, la caché puede ser mucho más grande. Para guardar los datos comprimidos en la caché puede modificarse la interfaz RssDocumentCacheable o bien crear una nueva interfaz que extienda a esta. Ésta última opción es laque representa la interfaz RssDocumentCacheable2, que cuenta con un nuevo método toBytesGZIP, el cual devuelve el array de bytes correspondiente al código XML comprimido del documento RSS. En la implementación de la interfaz se sigue el mismo esquema que cuando se guarda en caché la cadena de texto. Es decir, la implementación cuenta con un atributo, arrRssDocAsBytesGZIP, que se inicializa sólo la primera vez que se llama al método.

Pragma: no-cache

if (arrRssDocAsBytesGZIP == null) { ··· }

El código principal de la sentencia condicional anterior consta de la misma estructura try…catch…finally expuesta en el apartado anterior, con las variables baos de tipo ByteArrayOutputStream, gzipos de

SOLO PROGRAMADORES nº 162

22

tipo GZIPOutputStream y osw de tipo OutputStreamWriter:

Content-Encoding: gzip

baos = new ByteArrayOutputStream();

Content-Type: text/xml; charset=UTF-8

gzipos = new GZIPOutputStream(baos);

Content-Length: 960

osw = new OutputStreamWriter(gzipos,

Date: Sun, 04 May 2008 04:33:23 GMT

Charset.forName(“UTF-8”)); rssDoc.write(osw); osw.flush(); gzipos.flush(); gzipos.finish(); baos.flush(); arrRssDocAsBytesGZIP = baos.toByteArray();

A diferencia de lo que sucede cuando se escribe directamente la salida del servlet, aquí la escritura del documento RSS se hace empleando el método write de la clase RssDocument. El parámetro que recibe es lógicamente el canal de escritura orientado a caracteres representado por la variable osw. Las diferencia entre usar o no HTTP Compression se aprecian observando las cabeceras HTTP devueltas por las llamadas a los documentos RSS rss5.xml (el servlet SRssServer5) y rss6.xml (el servlet SRssServer6). En el primer caso no aparece

200 OK

Si se comparan los valores de ContentLength se aprecia que la versión comprimida es aproximadamente un 44% de la versión normal. No hay que olvidar que en estos ejemplos se está utilizando un documento RSS con fines didácticos. En un entorno real el documento RSS sería mucho más grande, con lo que la reducción sería todavía mayor. Además en un entorno real también es posible que se sirvieran varios documentos RSS, como por ejemplo podría ocurrir en un servicio de blogs. Teniendo en cuenta todos los factores anteriores resulta evidente que aplicar compresión es muy aconsejable: reduce el número de bytes a transmitir, con ello el tiempo de transmisión, y todo ello sin cargar en exceso al servidor, ni por supuesto al cliente. De hecho, si se comparan los tiempos consumidos por los servlet SRssServer5 y SRssServer6, la diferencia en general no es apreciable. www.revistasprofesionales.com


REDES-RSS Java 1:REDES-RSS Java 1

16/6/08

12:05

Página 23

REDES

RSS con Java (III)

Control de la Caché mediante Cabeceras HTTP El sistema de caché propuesto hasta el momento simplemente guarda en memoria los documentos RSS (en forma de cadena de caracteres o de array de bytes comprimido). De esta forma se libra al servidor de la carga asociada a la regeneración completa del código XML en cada llamada. No obstante, el documento realmente se manda en cada llamada, con el coste que ello tiene en ancho de banda. Además aunque el documento no se cree y venga directamente de la caché, para el servidor no es despreciable el esfuerzo de tener que escribir en el canal de escritura típico del servlet, especialmente en un entorno real en el que puede haber cientos o miles de llamadas en un corto espacio de tiempo. Un paso más allá en la optimización es el que se propone ahora, aprovechando que los clientes normalmente también soportan su propia caché. Éste es el caso por ejemplo de los navegadores. Si un navegador guarda el documento RSS en su propia caché, la mejor de las optimizaciones consiste en poder decir al navegador que utilice su caché siempre que el documento no haya cambiado. Así no hay que transmitir nada ni siquiera. Para ello el servidor de RSS puede instar a los clientes (navegadores, aplicaciones de RSS, etc.) a utilizar su propia caché mediante el uso de cabeceras HTTP específicas. El servlet SRSSServer7 establece dos cabeceras HTTP cuando sirve el documento RSS. Con este fin emplea los métodos setDateHeader y setHeader típicos de la interfaz HttpServletResponse del API estándar de Java. res.setDateHeader(“Last-Modified”,···); res.setHeader(“Cache-Control”, ”max-age=10, must-revalidate”);

En el primer caso se establece la cabecera Last-Modified. Ésta indica al navegador la fecha de la última modificación del documento RSS. El primer parámetro es el nombre de la cabecera y el segundo es un valor numérico de tipo long con la fecha. En Java, como en muchos otros lenguajes de programación, las fechas pueden expresarse en forma de número de milisegundos transcurridos desde el 1 de enero de 1970 UTC. En la segunda línea de código el método setHeader se emplea para establecer la cabecera Cache-Control. Como siempre el www.revistasprofesionales.com

Documentación del API estándar del Java de la interfaz HttpServletResponse (java.sun.com/javaee/5/docs/api/).

primer parámetro es el nombre de la cabecera y el segundo el valor. El valor es una cadena de caracteres en la que max-age indica al navegador el número de segundos que debe almacenar el documento RSS en su caché; must-revalidate indica que el navegador debe revalidar con el servidor el contenido guardado en la caché antes de usarlo. En general, la cabecera CacheControl aplicada a las respuestas puede adoptar los siguientes formatos:  p u b l i c : indica que el documento puede guardarse en cualquier caché.  p r i v a t e : indica que el documento no puede guardarse en una caché pública compartida.  n o - c a c h e : indica que el documento puede almacenarse en cualquier caché, pero antes de utilizarlo siempre debe validarse.  n o - s t o r e : indica al navegador que no guarde el documento.  n o - t r a n s f o r m : indica que el cuerpo (body) de la respuesta HTTP no debe ser modificado.  m u s t - r e v a l i d a t e : indica que el contenido de la caché debe ser validado antes de usarse.  p r o x y - r e v a l i d a t e : indica lo mismo que must-revalidate pero exceptuando el caso de las caché privadas.  m a x - a g e = seconds: indica que el documento almacenado en la caché debe considerarse caducado pasado un número determinado de segundos.  s - m a x a g e = s e c o n d s : indica lo mismo que la cabecera anterior pero obviando el caso de las caché públicas. Como se puede observar, el uso de esta cabecera es bastante flexible y puede adaptarse casi a cualquier arquitectura: caché públicas, privadas, proxies, etc. El correcto uso de

Cache-Control es muy importante en general, en el desarrollo de cualquier aplicación Web sometida a un estrés de carga considerable, y en particular a la hora de servir documentos RSS. Los lectores de RSS, ya sean plug-in de los navegadores, los propios navegadores o cualquier otro tipo de aplicación, Web o de escritorio, suelen hacer muchas llamadas a la URL con el fin de determinar si el documento RSS ha sido actualizado. Utilizando las cabeceras HTTP adecuadas puede evitarse que cada llamada se transforme en una carga de trabajo para el servidor reduciéndose el trabajo a una mera comprobación de fechas y terminado con una indicación al lector de RSS para que utilice el documento que almacena en su caché. El esquema de control de la caché con las cabeceras HTTP se completa con el análisis de las cabeceras enviadas por el cliente. El método getDateHeader, de la interfaz HttpServletRequest del API estándar, devuelve un valor numérico que se corresponde con una fecha. El parámetro que recibe es el nombre de la cabecera, en este caso IfModified-Since. long lIfModifiedSince = req.getDateHeader(“If-ModifiedSince”);

El método devuelve -1 cuando no encuentra la cabecera. En otro caso devuelve un valor indicando al servidor la fecha del documento que tiene almacenada en la caché. La cabecera se denomina IfModified-Since porque en realidad es una pregunta, en el sentido de que el cliente está preguntando al servidor si el documento ha sido modificado desde la fecha dada. El servidor con esta información puede gestionar la respuesta como se muestra seguidamente: 23

SOLO PROGRAMADORES nº 162


REDES-RSS Java 1:REDES-RSS Java 1

16/6/08

12:05

Página 24

REDES

Aunque la información se manda en formato comprimido el código fuente del navegador muestra lo mismo: la transformación es transparente.

emplea el método flushBuffer para liberar los recursos relacionados con los canales de lectura y lectura, y directamente se retorna con la sentencia return. Obsérvese que cuando esto ocurre, el servlet en realidad no ha hecho nada: ni se ha generado el documento RSS, ni se ha consumido tiempo en escribir nada en los canales de escritura, ni en consultar la propia caché del servidor, etc. Es decir, la carga para el servidor es mínima, ya que se limita a comparar fechas y decirle al cliente que puede utilizar el documento almacenado en su caché.

almacenado en la caché del cliente, es válido todavía. El esquema general del servlet queda por lo tanto como sigue: if (rssDocCacheable==null) { /* No está en la cache. Hay que crearlo y añadirlo */ } else { /* Está en la cache */ ··· if ((lLastModified - lIfModifiedSince)<=1000) { /* La caché del cliente es válida. Fin */ }

long lIfModifiedSince =

}

req.getDateHeader(“If-Modified-Since”);

···

if (lIfModifiedSince!=-1) {

/* Se devuelve el documento RSS.*/

long lLastModified = /* ··· */; if ((lLastModified lIfModifiedSince)<=1000) { res.setStatus(HttpServletResponse.SC _NOT_MODIFIED); res.flushBuffer();

Cabeceras HTTP de la versión que emplea la caché en el cliente.

return; } }

Si la cabecera If-Modified-Since está definida se compara con la fecha de la última modificación del documento solicitado. Si la diferencia es menor que una determinada cantidad de tiempo, en milisegundos, se considera que el documento almacenado en la caché del cliente es válido y por lo tanto no es necesario que el servlet haga nada más que dar luz verde al cliente para que utilice su caché. El método setStatus establece el estado de la respuesta HTTP, en este caso HttpServletResponse.SC_NOT_MODIFIED, que se corresponde con el código de estado 304 del protocolo HTTP. Seguidamente se

Uso combinado con la Caché del servidor En el esquema propuesto en el apartado anterior falta por determinar de dónde sale la fecha de la última modificación del documento RSS, representada por la variable lLastModified. Existen muchas soluciones al respecto. Una de las más sencillas consiste en evolucionar el sistema de caché que ya se ha implementado en el servidor. La interfaz RssDocumentCacheable3, que extiende a su versión predecesora, implementa un nuevo método denominado lastModified: public final long lastModified() { return l; }

En este ejemplo el método se limita a devolver el valor de l, que es la fecha de creación del documento RSS en forma de número de milisegundos. Con este método se asigna el valor a lLastModified: long lLastModified = ((RssDocumentCacheable3) rssDocCacheable).lastModified();

Ejemplo de creación dinámica de una instancia de un objeto que implementa la interfaz RssDocumentCacheable3.

SOLO PROGRAMADORES nº 162

24

Esto significa que se utiliza la caché del servidor para determinar si el documento RSS,

Si bien lo anterior es cierto, el uso que se hace es muy limitado y en la mayor parte de los casos se limita a una consulta de la fecha de creación del documento RSS. Si la aplicación Web tiene que servir muchos documentos RSS simultáneamente, podría ser interesante construir dos sistemas de caché en el servidor. El primero se utilizaría para almacenar los documentos RSS más utilizados, y tendría un tamaño limitado con el fin de no sobrecargar la memoria. El segundo sistema de caché solamente guardaría las fechas de la actualización de los documentos RSS y podría ser mucho más grande. Éste se emplearía cuando entra en juego la caché del cliente.

Conclusión A lo largo de esta serie de artículos se ha expuesto cómo crear una aplicación Web que genere y sirva de forma optimizada documentos RSS. La tecnología RSS se utiliza cada día más, en servicios y portales de todo tipo. Conocer y ser capaces de crear documentos RSS en todos los formatos es interesante para garantizar la máxima compatibilidad, pero el reto verdaderamente importante de las aplicaciones que generan RSS está en cómo servir los documentos sin morir en el intento, de éxito. Si se contempla por ejemplo el caso de un periódico on-line de gran audiencia que ofrece la posibilidad de agregar noticias mediante RSS, la carga que tiene que soportar el servidor para servir los documentos RSS es enorme. Mecanismos de optimización como los expuestos en esta entrega son indispensables. www.revistasprofesionales.com


49 Suscripcion Digital Solop:Suscripcion Digital Solop

17/6/08

12:25

Página 1

Sólo Programadores en Formato Digital Por mucho menos dinero Llegará antes a su ordenador que a los quioscos Suscríbase en www.revistasprofesionales.com Suscripción a Sólo Programadores (12 números) por sólo 32 euros Suscripción a Sólo Programadores (12 números) + Mundo Linux (6 números) por sólo 36 euros


DISPMOVILES(J2ME Polish):DISPMOVILES(J2ME Polish)

16/6/08

12:07

Página 26

DISPOSITIVOS MÓVILES

Desarrollo de aplicaciones con J2ME Polish En los dos anteriores artículos hemos visto como utilizar la base de datos de dispositivos y como construir nuestras aplicaciones mediante scripts de ANT adaptados a J2ME Polish. Además hemos comprobado como introduciendo directivas de preprocesado en el código podemos adaptar automáticamente la aplicación a dispositivos con diferentes capacidades (diferente soporte de librerías, tamaños de pantalla diferentes…). En este último artículo veremos que librerías ofrece J2ME Polish para desarrollar nuestras aplicaciones.

AITOR ALMEIDA ESCONDRILLAS Y DAVID SAINZ GONZALEZ

LISTADO 1

Ejemplo 1: Uso de ArrayList

public class UltimasLlamadas{ private ArrayList llamadasRecibidas = new ArrayList(); public void añadirLlamada( Llamada nuevaLlamada ) { llamadasRecibidas.add(nuevaLlamada); } public Llamada[] consultarLlamadas( int numTelefono ) { ArrayList llamadasNum = new ArrayList(); for ( int i = 0; i < llamadasRecibidas.size(); i++) { Llamada llamada = (Llamada) llamadasRecibidas.get(i); if (llamada.numero = numTelefono) { llamadasNum.add(l); } } return (Llamada[])llamadasNum.toArray(new Llamada[llamadasNum.size()]); } }

LISTADO 2

Ejemplo 2: Uso de TextUtil

public String[] formatearTexto (String texto, Font fuente, int anchoPrimeraLinea, int ancho linea) { //El método gras formatea el texto para adaptarlo a las medidas adecuadas String[] textoFormateado = TextUtil.wrap(texto, fuente, anchoPrimeraLinea, linea); Return textoFormateado; }

SOLO PROGRAMADORES nº 162

26

de.enough.polish.util.* En este paquete de J2ME Polish se encuentran varias clases que facilitaran el desarrollo de aplicaciones para dispositivos móviles. Estas clases ofrecen funcionalidades que no se encuentran en el perfil MIDP.  ArrayList es una alternativa más rápida al Vecto de java.  BitMapFont permite crear fuentes personalizadas para la aplicación.  TextUtil permite formatear adecuadamente el texto que se quiere mostrar para que se ajuste a las medidas de la pantalla del dispositivo. La clase de.enough.polish.util.ArrayList proporciona un array dinámico en el que almacenar elementos pero a diferencia de Vector no es sincronizado automáticamente. Por esta razón si varios hilos de ejecución acceden a uno de estos ArrayList concurrentemente habrá que implementar un mecanismo de sincronización. Por lo demás de.enough.polish. util.ArrayList ofrece los mismos métodos que java.util.ArrayList. En el ejemplo 1 se puede ver el uso del ArrayList para gestionar un historial de las llamadas recibidas en un teléfono. La clase de.enough.polish.util.TextUtil permite ajustar el texto a la pantalla del dispositivo. Esto evita tener que realizar los cálculos manualmente, automatizando el proceso. En el ejemplo 2 se muestra como hacer uso del método wrap para hacer esto. Además TextUtil también proporciona varios métodos para trabajar con texto. Algunos de estos métodos se encuentran disponibles en los dispositivos con MIDP 2.0 por defecto, pero no es así con los dispositivos que sólo soportan MIDP 1.0:  equalsIgnoreCase: Compara dos strings sin tener en cuenta mayúsculas y minúsculas.  lastIndexOf: Devuelve el índice de la última ocurrencia de un string dentro de otro.  replace: reemplaza todas las ocurrencias de un string por otro.  replaceFirst: Sólo reemplaza la primera ocurrencia.  replaceLast: Sólo reemplaza la última ocurrencia.  split: Divide un string en tokens de acuerdo a un valor.  splitAndTrim: Se aplica el trim a cada token resultante. www.revistasprofesionales.com


DISPMOVILES(J2ME Polish):DISPMOVILES(J2ME Polish)

16/6/08

12:07

Página 27

Desarrollo de aplicaciones con J2ME Polish

LISTADO 3

Ejemplo 3: Formateador de texto con BitMapFont

import de.enough.polish.util.BitMapFont; import de.enough.polish.util.BitMapFontViewer; import javax.microedition.lcdui.Graphics; public class TextFormater { private final BitMapFont bitMapFont; private BitMapFontViewer bitMapFontViewer; public TextFormater( String miFuente ) { this.bitMapFont = BitMapFont.getInstance(miFuente); } public void mostrarTexto(String texto, int anchoPrimLinea, int anchoLinea, int altura, int x, int y, Graphics g ) { bitMapFontViewer = bitMapFont.getViewer(texto); bitMapFontViewer.layout( anchoPrimLinea, linea, altura, Graphics.LEFT ); bitMapFontViewer.paint( x, y, g ); } }

DISPOSITIVOS MÓVILES

Herramientas standalone J2ME Polish incluye varias herramientas en su directorio bin. La primera de ellas es un editor binario (ver Figura 1) que permite editar ficheros. Aunque más interesante es el FontEditor, esta herramienta nos permitirá crear nuestras propias fuentes a partir de fuentes TrueTypr para usarlas junto a la clase BitMapFont. Seleccionando File>Open se puede abrir cualquier fuente TrueType en formato .ttf y visionarla en el editor (ver Figura 2). Como se puede ver en la figura 2 el editor permite cambiar el aspecto de la letra modificando su tamaño, color, espaciado entre caracteres… Además se pueden seleccionar los caracteres que se van a incluir en la BitMapFont, pudiendo desechar aquellos que no se vayan a utilizar por nuestra aplicación. Esto permite ahorrar espacio, dado que muchas veces la capacidad de almacenamiento de los dispositivos móviles se encuentra muy limitada. Por último en el directorio /samples/sysinfo se encuentra el Midlet SysInfo. Este Midlet permite recuperar mucha información de un dispositivo móvil, por ejemplo: altura y anchura de la pantalla, número de colores soportados, perfiles y configuraciones soportadas, librerías soportadas…

J2ME Polish GUI

Figura 1. BinaryEditor de J2ME Polish.

Por último la clase de.enough.polish.util. BitMap Font permite personalizar las fuentes que se quieren utilizar. Por defecto las fuentes disponibles en J2ME son bastante limitadas, existiendo sólo tres tipos de fuentes y tres tamaños para las mismas. Además el aspecto de las fuentes suele depender de la implementación, por lo que pueden variar de un dispositivo a otro haciendo que la aplicación no tenga un aspecto unificado. BitMapFont permite utilizar cualquier fuente TrueType en la aplicación, aumentando el número de posibilidades a la hora de diseñar el interfaz gráfico y asegurando un aspecto uniforme en diferentes plataformas y dispositivos. Para transformar una fuente TrueType es necesario utilizar la herramienta Font Editor que se incluye en J2ME Polish y de la que se hablará más adelante. Una vez transformadas las fuentes el uso de www.revistasprofesionales.com

las mismas es muy sencillo, tal como se muestra en el ejemplo 3. Sólo se debe indicar donde se encuentra nuestra fuente personalizada y después formatear el texto que se va a mostrar en pantalla.

LISTADO 4

La programación del interfaz gráfico en dispositivos móviles tiene una serie de limitaciones. En los dispositivos en los que sólo es soportado MIDP 1.0 el desarrollador se encuentra limitado a la hora de diseñar el interfaz ya que las clases que proporciona el perfil no permiten demasiadas variaciones. En MIDP 2.0 la cosa tampoco mejora demasiado, si se hace uso de las clases gráficas de alto nivel los interfaces resultan todos demasiado genéricos. Ejemplo 4: Activar J2ME Polish GUI

<j2mepolish> <info license=”Apache2” name=”AplicaciónPrueba” vendorName=”SoloP” version=”1.0.0” jarName=”UnEjemplo.jar”/> <deviceRequirements> <requirement name=”Identifier” value=”Generic/midp1” /> </deviceRequirements> <build usePolishGui=”true“> <midlet class=”miPaquete.AplicacionPrueba “ /> <variables> <variable name=”polish.usePolishGui” value=”false“ if=”polish.vendor == Motorola“ /> </variables> </build> <emulator /> </j2mepolish>

27

SOLO PROGRAMADORES nº 162


DISPMOVILES(J2ME Polish):DISPMOVILES(J2ME Polish)

16/6/08

12:07

Página 28

DISPOSITIVOS MÓVILES

LISTADO 5

Ejemplo 5: Activar fullscreen

<j2mepolish> <info license=”Apache2” name=”AplicaciónPrueba” vendorName=”SoloP” version=”1.0.0” jarName=”UnEjemplo.jar”/> <deviceRequirements> <requirement name=”Identifier” value=”Generic/midp1” /> </deviceRequirements> <build usePolishGui=”true“ fullscreen=”menu”> <midlet class=”miPaquete.AplicacionPrueba “ /> </build> <emulator /> </j2mepolish>

LISTADO 6

Ejemplo 6: Configuración de J2ME Polish GUI

<variables> <variable name=”polish.TextField.charactersKey1“ value=”abc“ /> <variable name=”polish.TextField.charactersKey2“ value=”2“ /> <variable name=”polish.TextField.charactersKey3“ value=”def“ /> <variable name=”polish.command.ok” value=”Aceptar“ /> <variable name=”polish.command.cancel“ value=”Cancelar“ /> <variable name=”polish.command.select“ value=”Seleccionar” /> <variable name=”polish.command.delete” value=”Borrar” /> </variables>

LISTADO 7

Ejemplo 7: Uso incorrecto de las clases

public class HolaMundo extends javax.microedition.midlet.MIDlet { private javax.microedition.lcdui.Display display; private javax.microedition.lcdui.Screen texto; public HolaMundo() { display = Display.getDisplay(this); texto = new javax.microedition.lcdui.TextBox( “HolaMundo”, “Hola Mundo”, 50, TextField.ANY); } protected void startApp() { display.setCurrent(texto); } protected void destroyApp(boolean unconditional) { } protected void pauseApp() { } }

LISTADO 8

Ejemplo 8: Selección del directorio de recursos

<j2mepolish> <info license=”Apache” name=”MiAplicacion” vendorName=”SoloP” version=”1.0.0” jarName=”ejemplo.jar”/> <build usePolishGui=”true” fullscreen=”menu”> <midlet class=”ejemplo.MiAplicacion” /> <resources dir=”recursos”/> </build> </j2mepolish>

Por otro lado si se hacen uso de las clases de bajo nivel la dificultad y el tiempo de desarrollo aumentan considerablemente. Además el comportamiento de los interfaces será diferente dependiendo de la implementación de las clases, no visualizándose de la misma manera en diferentes dispositivos. Gracias a J2ME Polish GUI es posible desarrollar interfaces gráficos con un diseño profesio-

SOLO PROGRAMADORES nº 162

28

nal sin necesidad de alargar el desarrollo de la aplicación. Además los interfaces desarrollados se comportarán de la misma manera en diferentes dispositivos. Para crear una interfaz con J2ME Polish GUI no sólo se debe modificar el código fuente, si no que es necesario introducir las directivas adecuadas en el build.xml y crear un fichero css que contenga los estilos que se aplicarán al interfaz.

Lo primero a realizar será introducir las directivas necesarias en el build.xml para poder hacer uso de J2ME Polish GUI. Para hacer esto es necesario utilizar el atributo usePolishGui que puede tomar los valores true, false y always. La diferencia entre true y always es que si el atributo tiene el valor true J2ME Polish GUI sólo será usado en aquellos dispositivos que puedan tener aplicaciones con mas de 100KB y que posean un color depth de al menos 8. Con always J2ME Polish se utilizará para todos los dispositivos, aunque estos no cumplan los requisitos mínimos. En el ejemplo 4 se puede ver un uso más específico. En este caso se activa la GUI para todos los dispositivos excepto para aquellos fabricados por Motorola. Una vez se ha activado el paso siguiente será configurar el GUI. Hay varias opciones a configurar:  Uso de pantalla completa.  Comportamiento de los controles.  Modo de entrada del TextField.  Fichero CSS utilizado. J2ME Polish GUI puede ser utilizado en modo pantalla completa en aquellos dispositivos que lo soporten. Para configurar este modo se hará uso del elemento fullscreen que puede tomar los valores true, false y menu. Es necesario utilizar la opción menu en aquellas aplicaciones que hagan uso de comandos para que J2ME Polish GUI renderice adecuadamente los menús. Hay que tener en cuenta que puede haber dispositivos que no soporten la opción menu. En el ejemplo 5 se puede ver como se activa la opción de pantalla completa. Otra de las posibilidades que ofrece J2ME Polish GUI es configurar el comportamiento de los diferentes elementos gráficos. Se puede cambiar el comportamiento de casi todos los elementos, por ejemplo:  polish.animationInterval: Define el intervalo para las animaciones.  polish.ChoiceGroup.suppressMark Commands: Elimina los comandos Mark y Unmark de los ChoiceGroup.  polish.ChoiceGroup.suppressSelect Command: Elimina el comando Select de los ChoiceGroup.  polish.TextField.suppressClearCommand: Elimina el comando Clear de los TextField.  polish.TextField.showInputInfo: Controla si se muestra el modo de input en los TextField.  polish.TextField.InputTimeout: Permite cambiar el timeout a la hora de escribir caracteres en los TextField. www.revistasprofesionales.com


DISPMOVILES(J2ME Polish):DISPMOVILES(J2ME Polish)

16/6/08

12:07

Página 29

DISPOSITIVOS MÓVILES

Desarrollo de aplicaciones con J2ME Polish

LISTADO 9

Ejemplo 9: Uso de la directiva #style

public class HolaMundo extends MIDlet { private display; private Form form; private List lista; public HolaMundo() { //#style formMail form = new Form(); //#style listaMail lista = new List(); //#style opcionMail lista.append( unMail, null ); display = Display.getDisplay(this); } protected void startApp() { display.setCurrent(texto); } protected void destroyApp(boolean unconditional) { } protected void pauseApp() { } } //En el css estarán configurados los estilos utilizados //fichero css .formMail{ background-image: url( fondo.png ); } .listaMail{ border-color: blue; background-color: black; } .opcionMail{ font-color: red; font-style: bold; font-size: medium; font-face: proportional; }

LISTADO 10

Ejemplo 10: Uso de tabbedForm

public class HolaMundo extends MIDlet { public HolaMundo() { //Se crea los nombres de las pestañas String[] pestanas = new String[]{“Mandar Mail”, “Recibir Mail”}; //se crea el formulario pasandole las pestañas //el parámetro null podría contener una array de Images para cada //pestaña //#style formMail TabbedForm formulario = new TabbedForm(“Mi form”, pestanas, null); //Se añade un elemento a la primera pestaña (indice 0) //#style labelEmail StringItem email = new StringItem(null, “Mail”); formulario.append( 0, email); //Se añade un elemento a la segunda pestaña (indice 1) //#style labelDest StringItem dest = new StringItem(null, “Destinatario”); formulario.append( 1, dest); //Se borra el elemento de la primera pestaña formulario.delete (0, email); //Se consigue el índice de la pestaña seleccionada int indice = formulario.getSelectedTab(); } protected void startApp() { display.setCurrent(formulario); } protected void destroyApp(boolean unconditional) { } protected void pauseApp() { } } 

polish.TextField.charactersKeyX (donde X es un número del 0 al 9, Star o KeyPound): Permite configurar que caracteres están disponibles en cada tecla.

www.revistasprofesionales.com

 

polish.command.ok: Permite cambiar la etiqueta del comando de OK. polish.command.cancel: Permite cambiar la etiqueta del comando de Cancel.



polish.command.select: Permite cambiar la etiqueta del comando de Select.  polish.command.mark: Permite cambiar la etiqueta del comando de Mark.  polish.command.unmark: Permite cambiar la etiqueta del comando de Unmark.  polish.command.delete: Permite cambiar la etiqueta del comando de Delete.  polish.command.clear: Permite cambiar la etiqueta del comando de Clear. Se puede consultar una lista completa de las opciones disponibles en la documentación de J2ME Polish. En el ejemplo 6 se puede ver como se han cambiado los valores para las tecla 1 (valores a, b y c), tecla 2 (valor 2) y tecla 3 (valores d, e y f). Además se modifican las etiquetas de los comandos Ok, Cancel, Select y Delete para ponerlas es castellano. Una vez se ha activado y configurado J2ME Polish GUI ya podremos utilizarlo en nuestro programa. Es importante a la hora de utilizarlo hacer los imports de las clases del interfaz gráfico en vez de utilizar el nombre de clase completo (ver ejemplo 7). Si no se hace así J2ME Polish GUI tendrá problemas a la hora de sustituir las clases originales por sus clases y el interfaz no se renderizará de la manera deseada. Una vez hechos los imports de la manera correcta se hará uso de la directiva de preprocesamiento #style para indicar que estilo aplicar a un control. Estos estilos estarán definidos en un fichero css dentro del directorio de recursos configurado en el build.xml (ver ejemplo 8). En el ejemplo 9 se puede ver como se utiliza la directiva de preprocesado #style para asignar los estilos a los diferentes elementos. En este caso se le asigna el estilo formMail a un formulario, listaMail a una lista y opcionMail a un elemento de la lista. Estos tres estilos se encontrarán definidos en un fichero css dentro del directorio de recursos configurado anteriormente. La directiva #style puede ser introducida en diferentes posiciones dentro del código:  Delante de los constructores de los elementos.  Antes de llamar al método append.  Antes de llamar al método set.  Antes de llamar al método insert. Antes de llamar al método set Appearance Mode.

Elementos específicos de J2ME Polish GUI J2ME Polish provee a los desarrolladores de una serie de controles específicos: 29

SOLO PROGRAMADORES nº 162


DISPMOVILES(J2ME Polish):DISPMOVILES(J2ME Polish)

16/6/08

12:07

Página 30

DISPOSITIVOS MÓVILES

Conclusión

Figura 2. FontEditor de J2ME Polish.

LISTADO 11

Ejemplo 11: Uso de FramedForm

public class HolaMundo extends MIDlet { public HolaMundo() { //se crea el formulario //#style formMail FramedForm formulario = new FramedForm( “Mail” ); //Se añade un elemento al área bottom //#style labelEmail StringItem email = new StringItem(null, “Mail”); form.append(Graphics.BOTTOM, email); //Se añade un elemento al área top //#style labelDest StringItem dest = new StringItem(null, “Destinatario”); formulario.append(Graphics.TOP, dest); } protected void startApp() { display.setCurrent(formulario); } protected void destroyApp(boolean unconditional) { } protected void pauseApp() { } }

TabbedForm, FramedForm y SpriteItem. TabbedForm permite la creación de un formulario que tendrá varias pestañas en su parte superior. Dado que hereda de form se pueden utilizar los métodos de esa clase, pero además incorpora nuevos métodos para controlar las pestañas. Esto puede observarse en el ejemplo 10. En este ejemplo se añaden elementos al tabbedForm mediante el método append, se borran elementos con el método delete y se recupera que pestaña está seleccionada mediante el método getSelectedTab. FramedForm permite la creación de un formulario dividido en cinco partes: un área principal en el centro, top, bottom, left y right. El área principal tiene un scroll pero las otras 4 áreas se mantienen siempre en la misma posición. En el ejemplo 11 se puede ver como usar este formulario. Por último SpriteItem permite incluir animaciones en los formularios de menú cuando el elemento es seleccionado (por ejemplo un mail enviándose). En el ejemplo 12 se puede ver como se haría esto.

SOLO PROGRAMADORES nº 162

30

En este último artículo de la serie sobre J2ME Polish hemos visto como crear interfaces más ricos que se comporten homogéneamente en diferentes dispositivos. J2ME Polish nos permite crear interfaces con un aspecto acabado y profesional de una manera sencilla mediante el uso de J2ME Polish GUI. Además también podemos utilizar nuestras propias fuentes gracias a la herramienta BitMapFont. A lo largo de la serie hemos podido comprobar que J2ME Polish es un Framework versátil que puede facilitar enormemente el desarrollo de aplicaciones para dispositivos móviles, sobre todo agilizando la personalización de las aplicaciones para diferentes dispositivos y disminuyendo de esta manera el time-to-market.

Figura 3. Algunos interfaces creados con J2ME Polish GUI.

LISTADO 12

Ejemplo 12: Uso de SpriteItem

public class HolaMundo extends MIDlet implements ItemCommandListener { private Command enviarMail = null; public HolaMundo() { super(); enviarMail = new Command( “Enviar Mail“, Command.ITEM, 1 ); Form formMail = new Form( “Menu de Mails” ); // se crea el sprite con la animacion Image imagen = Image.createImage( “/envio.png”); Sprite sprite = new Sprite(imagen, 40, 40 ); sprite.setFrameSequence( new int[]{ 1, 2, 3, 4, 5} ); //#style menu SpriteItem spriteMail = new SpriteItem( null, sprite, 50, 0, false ); //Se configure el comando al que está ligado spriteItem.setDefaultCommand(enviarMail); //Se configura quien recibirá sus eventos spriteItem.setItemCommandListener( listenerMenu ); //Se añade al formulario formMail.append(spriteMail); } protected void startApp() { display.setCurrent(formulario); } protected void destroyApp(boolean unconditional) { } protected void pauseApp() { } public void commandAction( Command cmd, Item item ) { if ( cmd == enviarMail ) { //enviar un mail } } }

www.revistasprofesionales.com


Suscripcion papel

16/4/08

12:22

Página 1

Suscripción a Sólo Programadores SUSCRIPCIÓN PARA ESPAÑA Opción A: Suscripción anual con 25% descuento: 54 euros* (3 revistas gratis, 18 euros de ahorro) Opción B: Suscripción anual con 15% descuento: 61,20 euros* (tapas de regalo, 10,80 euros de ahorro) *10 euros de gastos de envío para la opción contrareembolso

SUSCRIPCIÓN PARA EXTRANJERO Opción C: Suscripción anual con 25% descuento Europa: 78 euros (gastos de envío incluidos) Opción D: Suscripción anual con 25% descuento Resto de paises: 102 euros (gastos de envío incluidos)

FORMAS DE PAGO PARA ESPAÑA  Contrareembolso (10 euros gastos de envío)  Giro Postal a Revistas Profesionales, S.L.  Transferencia al Banco Popular: c.c:0075/1040/43/0600047439  Talón Bancario a nombre de Revistas Profesionales  Domiciliación Bancaria  Tarjeta de Crédito FORMA DE PAGO EXTRANJERO:  Tarjeta de crédito

Suscríbase en www.revistasprofesionales.com Más información en el teléfono 91 304 87 64, en el fax 91 327 13 07 y en rpsuscripciones@revistasprofesionales.com


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 32

MIDDLEWARE

Programación con Múltiples Hilos (Threads) en Visual Basic; C# y Java (II) MG. LIC. GASTÓN C. HILLAR e-mail: gaston_hillar@hasa.com.ar

En la entrega anterior ofrecimos una detallada introducción a las necesidades del uso de múltiples hilos (threads) en Visual Basic; C# y Java; así como a los conceptos fundamentales y los principales enemigos y problemas con los cuales nos encontraremos en este largo pero apasionante camino. En esta ocasión, vamos a comenzar a generar código y ejemplos concretos para estos tres lenguajes de programación para evitar los obstáculos explicados y conseguir tener el control de múltiples hilos de ejecución acorde a la cantidad de núcleos de procesamiento disponibles. Divide y vencerás Nada mejor que el viejo y conocido refrán “divide y vencerás” para explicar las ventajas del paralelismo con los sistemas de multiprocesamiento moderno. Sin embargo, antes de lanzarnos al código y profundizar en los ejemplos, nos queda un gran enemigo a combatir. En la entrega anterior explicamos en detalle la problemática del recolector de basura (garbage collector) y cómo se podía transformar en un importantísimo cuello de botella. El segundo gran cuello de botella con el cual nos podemos encontrar a la hora de conseguir un paralelismo extremo es la competencia por el acceso al subsistema de E/S del ordenador, en el peor de los casos, la pelea de múltiples hilos de ejecución por acceder simultáneamente a uno de los dispositivos eternamente más lentos de los ordenadores, los discos duros (discos rígidos, HDD).

SOLO PROGRAMADORES nº 162

32

En cualquier configuración, siempre son muchísimo más lentos que la memoria del ordenador, por lo cual, hacer que múltiples hilos soliciten servicios al subsistema de discos o bien, generalizando, al subsistema de E/S puede eliminar muy rápidamente toda la ganancia en rendimiento que conseguimos al realizar los esfuerzos para paralelizar. Ni siquiera en un servidor de alto rango, el subsistema de discos equipara en rendimiento a la memoria del ordenador. Como regla general o bien como patrón de diseño, la recomendación, a la hora de paralelizar un proceso crítico, es evitar que cada hilo de ejecución tenga en lo posible la mayor cantidad de datos necesarios para realizar sus tareas dentro de la memoria caché de segundo (L2) o tercer nivel (L3) del microprocesador y, en el peor de los casos, que tenga que salir a la memoria principal, pero no más allá de ésta. Esto lo podríamos comparar con una catarata de rendimiento, en donde cada escalón que se baja desde la cima, se pierde un poco de rendimiento. Si cada hilo tiene lo que necesita en la memoria caché de segundo o tercer nivel, estamos en el mejor de los casos. Ahora bien, si tiene que salir al controlador de memoria, cada hilo empezará a competir por un turno para pasar por el bus frontal que comunica al microprocesador con el mundo exterior y con la memoria. Entonces, tendremos más tiempo esperando y menos trabajando, más ciclos de procesamiento ociosos para cada uno de los hilos. Ahora bien, cómo conseguimos estos objetivos centrados en las micro-arquitecturas de los microprocesadores con lenguajes de alto nivel como Visual Basic; C# y Java, en los cuales no tenemos un gran control de ésto. La respuesta es simple, pero se comprende mucho mejor utilizando un ejemplo de la vida real. Imaginemos la siguiente situación, tengo una empleada que sabe mecanografía (el hilo de ejecución) y escribe a una velocidad mayor de 100 palabras por minuto, pero cada 2 minutos se queda sin hojas y manda a un botones a comprar 1 sola (salida a leer al disco rígido). El botones tarda media hora en traer la hoja, porque va caminando despawww.revistasprofesionales.com


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 33

MIDDLEWARE

Programación con Múltiples Hilos (Threads) en Visual Basic; C# y Java (II) cio, se queda mirando escaparates por el camino, se toma algo y después llega con la hoja. En este caso, he desperdiciado la velocidad de la empleada (el hilo de ejecución) porque el muchacho que se encarga de traer las hojas malgasta el tiempo y trae poca cantidad cada vez que viene (el disco rígido). El mismo concepto anteriormente explicado se aplica a los sistemas con múltiples hilos de ejecución. Podemos tener un ordenador equipado con el procesador con más cantidad de núcleos existente en el mercado, pero si lo utilizamos mal porque el sistema que lo comunica con el mundo exterior es lento, no sirve de nada, porque los núcleos de procesamiento se pasarán la mayoría del tiempo esperando que los buses lleven y traigan los datos. Si el bus es rápido pero trae pocos datos al mismo tiempo, tampoco es bueno, como sucedería si yo reemplazara al botones por uno que me traiga 1 hoja por vez, pero corriendo. En cambio, si preparo el sistema para que traiga 500 hojas por vez, solamente lo tendré que enviar a comprar hojas un par de veces al día. Ese mismo objetivo se debe cumplir al planear el algoritmo para el paralelismo. En un esquema de ejecución lineal, se puede suponer que hay un único hilo de ejecución corriendo y por ende se dan por descartadas ciertas situaciones, que no se pueden trasladar sin correcciones a un modelo con múltiples hilos de ejecución que busca conseguir la mayor eficiencia posible para el proceso en cuestión. Esto mismo se aplica al acceso a recursos en la red o en bases de datos, en los cuales estamos generando una sobrecarga de E/S importante. Muchas veces es preferible organizar todos los datos en un arreglo, matriz o colección y recorrerlos, antes que ir haciendo numerosos accesos a bases de datos o a recursos en la red.

Un ejemplo sencillo para comenzar en .Net 2.0; 3.0 y 3.5 Vamos a comenzar con un ejemplo muy simple, para luego complicar las cosas y ver lo aprendido con un caso concreto. Por un momento dejaremos de lado Java y nos centraremos en los lenguajes de programación .Net. Un hilo de ejecución no es un temporizador (timer). Es importante aclararlo debido a que los desarrolladores que todavía no han experimentado con los hilos de ejecución pueden confundirlos con una nueva especie de temwww.revistasprofesionales.com

porizador. Salvo algún caso especial en el cual creemos un temporizador compatible con programación concurrente con múltiples hilos de ejecución dentro de un hilo, generalmente los temporizadores corren todos en el mismo hilo de ejecución principal de la aplicación. Por lo tanto, utilizando simplemente temporizadores no conseguiremos ningún aprovechamiento de los múltiples núcleos de ejecución disponibles en un equipo. La forma más sencilla para empezar a experimentar con múltiples hilos de ejecución en .Net y aprender los principios básicos es utilizar el componente Backgroundworker (Trabajador en segundo plano), System. ComponentModel. BackgroundWorker. Este componente nos permite definir ciertas propiedades en tiempo de diseño y programar el gestor (handler) del evento DoWork. Constituye una forma sencilla y rápida de generar un hilo de ejecución independiente al que se está utilizando para ejecutar la aplicación sin todavía entrar en métodos un poco más versátiles pero también más complejos (como pasa siempre). Por lo tanto, vale la pena conocerlo. Al componente BackgroundWorker lo vamos a encontrar en la caja de herramientas (Toolbox) del entorno de desarrollo .Net (debemos tener en cuenta que está disponible a partir de .Net 2.0, es decir, en Visual Studio 2005 y 2008, pero no en versiones anteriores). El componente está pensado inicialmente para ejecutar operaciones que tardan en dar una respuesta al usuario en la interfaz gráfica y que se puedan cancelar, para lo cual la ejecuta en un hilo de ejecución independiente, sin embargo, resulta ser una buena alternativa para generar múltiples hilos de ejecución sin tener que entrar en temas más avanzados que pueden asustar a los desarrolladores menos expertos, al ser bastante intensos en código. Sus dos propiedades más importantes son:  WorkerReportsProgress. Del tipo boolean, indica si el proceso que ejecuta el hilo de ejecución indicará alguna clase de progreso, para lo cual, se dispara el gestor del evento ProgressChanged. Este evento facilita la actualización de la interfaz con el usuario, es decir, de valores de los controles, sin complicarnos con los problemas que se generan cuando queremos hacerlo desde un hilo de ejecución diferente al principal de la aplicación.  WorkerSupportsCancellation. Del tipo boolean, indica si el proceso que ejecuta

el hilo de ejecución se puede cancelar llamando a su método Cancel Async(), el cual se encarga de dejar en true (verdadero) el valor de la propiedad CancellationPending (hay una cancelación pendiente) que deberá revisar el código en ejecución que dispara el gestor del evento DoWork. Parece complicado, pero con un ejemplo empleando este componente en Visual Basic y en C#, resultará mucho más sencillo de comprender. Vamos a retomar el código de ejemplo que habíamos utilizado en la entrega anterior para demostrar la ineficiencia del código lineal ante las arquitecturas de multiprocesamiento (repasar el Listado 1 de la entrega anterior). Dividiremos ese bloque de código de un ciclo que se ejecutaba 36 millones de veces en 4 componentes Background Worker que contendrán el mismo código, pero, cada uno ejecutando un ciclo de 9 millones de veces (9 x 4 = 36). Y lo ejecutaremos en un ordenador con cuatro núcleos de ejecución (luego veremos cómo podemos conseguir optimizar en forma dinámica este comportamiento, pero debemos ir por partes, porque el tema requiere de la máxima atención). Vamos a generar un Windows Form como el que se muestra en la Figura 1, con los siguientes controles y componentes:  4 BackgroundWorker, para generar 4 hilos de ejecución independientes al principal. Hay que asignar el valor True (verdadero) a sus propiedades WorkerReportsProgress en tiempo de diseño. De esta manera, programaremos el código del gestor de un evento para que muestre el progreso en los 4 ProgressBar (Barras de progreso).  4 Button (Botones), encargados de iniciar la ejecución de cada Background Worker.  4 Label (Etiquetas) acompañando a 4 ProgressBar (Barras de progreso), que serán las encargadas de mostrar cómo avanza el procesamiento de cada hilo independiente.  1 Timer (Temporizador) que irá consultando el valor de 4 variables para presentar el progreso de los 4 hilos de ejecución en los 4 ProgressBar (Barras de progreso). En el Listado 1 presentamos el código completo del ejemplo para Visual Basic y C# (tengamos en cuenta que se aplica a .Net 2.0; 3.0 y 3.5), el cual explicaremos en detalle a continuación. Los gestores de eventos Background Worker1_DoWork; BackgroundWorker2_ 33

SOLO PROGRAMADORES nº 162


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 34

MIDDLEWARE

Figura 1. Un Windows Form para empezar a experimentar con varios hilos de ejecución simultáneos en .Net 2.0 y superiores.

Figura 2. Resultado de comenzar la ejecución del primer hilo.

DoWork; BackgroundWorker3_DoWork y BackgroundWorker4_DoWork contienen el código que ejecutará cada uno de los hilos de ejecución independientes generados por el componente BackgroundWorker correspondiente. Como podemos ver, se trata del ciclo que analizamos en la entrega anterior, pero dividido en 4 partes igual de 9 millones de veces, en vez de las 36 millones de veces lineales. Además, se encarga de registrar el progreso del proceso almacenando el valor de la variable i en la variable de instancia del Windows Form pitProgreson, donde n será de

SOLO PROGRAMADORES nº 162

34

1 a 4 dependiendo del número de BackgroundWorker del cual está programado el evento. De este modo, se logra desacoplar al hilo de ejecución de la problemática de tener que competir por la modificación de la interfaz con el usuario, es decir, por el cambio de alguna propiedad de un control visual. De esto se encarga el temporizador Timer1, el cual hace lo siguiente, verifica si se está ejecutando código correspondiente al hilo de ejecución de cada BackgroundWorker consultando el valor booleano de la propiedad IsBusy (está ocupado). Si el resultado es True

(verdadero), quiere decir que hay código ejecutándose en ese hilo de ejecución, entonces, llama al método ReportProgress de ese BackgroundWorker, pasándole como parámetro el valor porcentual de progreso dividiendo al valor de la variable pitProgreso por 9000000 y multiplicándola por cien. Esto disparará el gestor del evento ProgressChanged del BackgroundWorker correspondiente, el cual se encargará de actualizar el ProgressBar correspondiente con el nuevo porcentaje, tomándolo del parámetro e, del tipo System. ComponentModel. Progress ChangedEvent Args, más específicamente de su propiedad ProgressPercentage, la cual se completa con el valor que especificamos como parámetro al llamar al método ReportProgress. Cada Button (Botón) se encarga de generar un nuevo hilo de ejecución y poner a trabajar el código programado en el gestor del evento DoWork del BackgroundWorker correspondiente a través del llamado al método RunWorkerAsync(). Una de las grandes diferencias que notaremos con respecto a la ejecución no basada en múltiples hilos de ejecución es que una vez que se llama a este método, obtenemos el control del flujo de ejecución inmediatamente, pues, se disparó un hilo de ejecución asincrónico con respecto al hilo de ejecución principal. Además de que a nivel programación se siguen ejecutando instrucciones después de ésta, el usuario retiene el control de la interfaz con el usuario y puede seguir presionando botones, inclusive cerrar la ventana. Como el código no es perfecto, deberíamos tener en cuenta que si se vuelve a presionar el botón se detenga la ejecución del BackgroundWorker, pero, la idea es presentar un primer ejemplo sencillo. La primera experiencia para ejecutar la aplicación consiste en tener la ventana y un monitor de actividades del microprocesador, ambos visibles e ir presionando de uno en uno los botones para ir viendo cómo al dispararse cada hilo, en vez de reducirse la carga total del procesador, se va distribuyendo cada nuevo hilo en un núcleo de procesamiento e inclusive, no se disminuye el rendimiento de los otros hilos que ya se están ejecutando. Para ello está preparado el ejemplo con las ProgressBar (Barras de progreso), que nos permiten visualmente detectar una caída en el rendimiento. Como ejercicio para comparar las diferencias, vale la pena preparar esta misma solución pero utilizando Timers (Temporizadores) en vez de Background Workers y visualizar la diferencia, pues como www.revistasprofesionales.com


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 35

MIDDLEWARE

Programación con Múltiples Hilos (Threads) en Visual Basic; C# y Java (II)

Códigos de ejemplo de un lazo ahora presentado en 4 hilos de ejecución independientes a través del componente BackgroundWorker.

LISTADO 1 Lenguaje de Programación Visual Basic: Imports System.Threading Imports System.Environment Public Class Form1 Private pitProgreso1 Private pitProgreso2 Private pitProgreso3 Private pitProgreso4

As As As As

Long Long Long Long

Private Sub Timer1_Tick(ByVal sender As System.Object, If BackgroundWorker1.IsBusy Then BackgroundWorker1.ReportProgress((pitProgreso1 End If If BackgroundWorker2.IsBusy Then BackgroundWorker2.ReportProgress((pitProgreso2 End If If BackgroundWorker3.IsBusy Then BackgroundWorker3.ReportProgress((pitProgreso3 End If If BackgroundWorker4.IsBusy Then BackgroundWorker4.ReportProgress((pitProgreso4 End If End Sub

ByVal e As System.EventArgs) Handles Timer1.Tick / 90000000) * 100) / 90000000) * 100) / 90000000) * 100) / 90000000) * 100)

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork Dim s As String Dim i As Long s = “” For i = 1 To 90000000 s = Chr(i Mod 255) pitProgreso1 = i Next End Sub Private Sub BackgroundWorker2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork Dim s As String Dim i As Long s = “” For i = 1 To 90000000 s = Chr(i Mod 255) pitProgreso2 = i Next End Sub Private Sub BackgroundWorker3_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker3.DoWork Dim s As String Dim i As Long s = “” For i = 1 To 90000000 s = Chr(i Mod 255) pitProgreso3 = i Next End Sub Private Sub BackgroundWorker4_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker4.DoWork Dim s As String Dim i As Long s = “” For i = 1 To 90000000 s = Chr(i Mod 255) pitProgreso4 = i Next End Sub Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged ProgressBar1.Value = e.ProgressPercentage End Sub Private Sub BackgroundWorker2_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker2.ProgressChanged ProgressBar2.Value = e.ProgressPercentage End Sub Private Sub BackgroundWorker3_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker3.ProgressChanged ProgressBar3.Value = e.ProgressPercentage End Sub

www.revistasprofesionales.com

35

SOLO PROGRAMADORES nº 162


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 36

MIDDLEWARE

Códigos de ejemplo de un lazo ahora presentado en 4 hilos de ejecución independientes a través del componente BackgroundWorker.

LISTADO 1

Private Sub BackgroundWorker4_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker4.ProgressChanged ProgressBar4.Value = e.ProgressPercentage End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click BackgroundWorker1.RunWorkerAsync() End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click BackgroundWorker2.RunWorkerAsync() End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click BackgroundWorker3.RunWorkerAsync() End Sub Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click BackgroundWorker4.RunWorkerAsync() End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Timer1.Enabled = True End Sub End Class Lenguaje de Programación C#: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; namespace ThreadingCSharpEjemplo1 { public partial class Form1 : Form { long pitProgreso1; long pitProgreso2; long pitProgreso3; long pitProgreso4; public Form1() { InitializeComponent(); } private void timer1_Tick(object sender, EventArgs e) { if (backgroundWorker1.IsBusy) { backgroundWorker1.ReportProgress((int) (((double) } if (backgroundWorker2.IsBusy) { backgroundWorker2.ReportProgress((int) (((double) } if (backgroundWorker3.IsBusy) { backgroundWorker3.ReportProgress((int) (((double) } if (backgroundWorker4.IsBusy) { backgroundWorker4.ReportProgress((int) (((double) } }

pitProgreso1 / 90000000) * 100)); pitProgreso2 / 90000000) * 100)); pitProgreso3 / 90000000) * 100)); pitProgreso4 / 90000000) * 100));

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { long i; String s; char miChar; for (i = 1; i<= 90000000; i++) { miChar = (char) (i % 255); s = miChar.ToString(); pitProgreso1 = i; } } private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) { long i; String s; char miChar;

SOLO PROGRAMADORES nº 162

36

www.revistasprofesionales.com


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 37

MIDDLEWARE

Programación con Múltiples Hilos (Threads) en Visual Basic; C# y Java (II) LISTADO 1

Códigos de ejemplo de un lazo ahora presentado en 4 hilos de ejecución independientes a través del componente BackgroundWorker.

for (i = 1; i <= 90000000; i++) { miChar = (char)(i % 255); s = miChar.ToString(); pitProgreso2 = i; } } private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e) { long i; String s; char miChar; for (i = 1; i <= 90000000; i++) { miChar = (char)(i % 255); s = miChar.ToString(); pitProgreso3 = i; } } private void backgroundWorker4_DoWork(object sender, DoWorkEventArgs e) { long i; String s; char miChar; for (i = 1; i <= 90000000; i++) { miChar = (char)(i % 255); s = miChar.ToString(); pitProgreso4 = i; } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; } private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar2.Value = e.ProgressPercentage; } private void backgroundWorker3_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar3.Value = e.ProgressPercentage; } private void backgroundWorker4_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar4.Value = e.ProgressPercentage; } private void button1_Click(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } private void button2_Click(object sender, EventArgs e) { backgroundWorker2.RunWorkerAsync(); } private void button3_Click(object sender, EventArgs e) { backgroundWorker3.RunWorkerAsync(); } private void button4_Click(object sender, EventArgs e) { backgroundWorker4.RunWorkerAsync(); } private void Form1_Load(object sender, EventArgs e) { timer1.Enabled = true; } } }

www.revistasprofesionales.com

37

SOLO PROGRAMADORES nº 162


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 38

MIDDLEWARE

Figura 3. Resultado de la ejecución de dos hilos simultáneos.

los temporizadores se ejecutan en el mismo hilo de ejecución veremos cómo cae el rendimiento visualmente observando la velocidad de incremento de las ProgressBar (Barras de progreso). Es conveniente ejecutar la aplicación varias veces e ir presionando los botones para comprender claramente el funcionamiento de los diferentes hilos de ejecución y sus diferencias con el ejemplo que habíamos presentado en la entrega anterior. En las Figuras 2, 3, 4 y 5 se presentan los monitoreos de la actividad de un microprocesador con cuatro núcleos ante la iniciación de cada nuevo hilo de ejecución. Como podemos ver en la Figura 5, en un ordenador equipado con cuatro núcleos de ejecución, podemos conseguir un aprovechamiento del procesador cercano al 90% en Windows XP y entre el 95% y el 98% en Windows Vista. Mucho mejor comparado con el 25% que obteníamos en nuestro ejemplo de la entrega anterior. Sin lugar a dudas, vale la pena el esfuerzo. Es fundamental tener en cuenta que, a pesar de todas las críticas recibidas por su rendimiento, en equipos con múltiples núcleos de ejecución y aplicaciones preparadas con múltiples hilos, el planificador de Windows Vista tiene una eficiencia muy superior a la de Windows XP. Por lo tanto, no todo son puntos negativos para el tan vapuleado Windows Vista. También, debemos considerar que el entorno de desarrollo tanto de Visual Studio 2005 como 2008 es un tanto pesado, por ende, los resultados definitivos se deben medir ejecutando la aplicación sin el entorno de fondo.

Un parche muy importante

Figura 4. Resultado de la ejecución de tres hilos simultáneos

SOLO PROGRAMADORES nº 162

38

Si vamos a ejecutar aplicaciones optimizadas para el uso de múltiples hilos de ejecución que busquen optimizar su rendimiento en ordenadores con varios núcleos de ejecución y utilizando el sistema operativo Windows XP con el Service Pack 2 o Windows Server 2003, es importante tener en cuenta que existe un parche que se debe descargar en forma manual para solucionar un inconveniente que puede afectar el rendimiento de esta clase de aplicaciones. Los equipos equipados con varios núcleos de ejecución o varios procesadores que admiten características de administración de energía del procesador pueden experimentar una reducción del rendimiento si no tiene aplicado este parche, el cual no se descarga mediante el utilitario de actualización de Windows. www.revistasprofesionales.com


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 39

MIDDLEWARE

Programación con Múltiples Hilos (Threads) en Visual Basic; C# y Java (II)

Figura 5. Resultado de la ejecución de cuatro hilos simultáneos.

Figura 6. Visualizando los múltiples hilos de ejecución que está ejecutando la aplicación.

Lo podemos conseguir en http://support. microsoft.com/kb/896256.

Depurando múltiples hilos de ejecución Las técnicas tradicionales para depurar aplicaciones que utilizan un único hilo de ejecución no se aplican a aquéllas que tienen varios, pues, podemos volvernos locos sin entender por dónde se está ejecutando código. Después de presionar los cuatro Button (Botones) para que arranquen los Backgroun Workers y sus respectivos hilos de ejecución, www.revistasprofesionales.com

si presionamos el botón Break all (Frenar todo), es decir, el botón con el símbolo de pausa del entorno de desarrollo, y seleccionamos Debug, Windows, Threads (Depurar, Ventanas, Hilos de ejecución ), aparecerá una ventana que nos muestra todos los hilos de ejecución (threads), la cual es fundamental para poder saber en dónde estamos parados (ver la Figura 6). Entre varios otros hilos de ejecución veremos uno con categoría (category) main thread (hilo de ejecución principal), el cual es el que controla el flujo principal de la aplicación y ejecuta el gestor del evento del temporizador. Y, por otro lado, hay cuatro hilos

de ejecución con la categoría (category) Worker thread y nombre (name) Worker thread, que en la columna ubicación (location) presentan el nombre del gestor del evento DoWork al cual pertenece cada uno de ellos:  WindowsApplication1.Form1. BackgroundWorker1_DoWork  WindowsApplication1.Form1. BackgroundWorker2_DoWork  WindowsApplication1.Form1. BackgroundWorker3_DoWork  WindowsApplication1.Form1. BackgroundWorker4_DoWork Haciendo doble click en el nombre de cada hilo, nos mostrará la parte de código que se está ejecutando actualmente (ver la Figura 7) y podremos inspeccionar valores de las variables. De esta manera, es posible verificar el estado de la aplicación en un momento determinado, algo que con la depuración tradicional no se podría conseguir, debido a que posiblemente el hilo de ejecución principal (main thread) no esté ejecutando ninguna instrucción. La información de esta ventana también nos muestra la prioridad que tiene asignada el hilo de ejecución y si se encuentra en espera o durmiendo. Tengamos en cuenta que es posible establecer puntos de interrupción y observaciones (watches) en el código de los hilos y de esta manera, se detiene la ejecución y con esta ventana, es posible verificar el punto del código en el cual se encuentra cada uno de los hilos. En muchos casos, será necesario recurrir a las viejas pero tan útiles técnicas de depuración a ciegas, en las cuales enviamos información a un archivo o a la salida de consola (Debug.Print) con información de qué tareas se han llevado a cabo. La depuración con múltiples hilos requiere un cambio de paradigma importante para comprender que pueden estar pasando muchas cosas en paralelo en un mismo instante de tiempo y en un paralelismo real y no ficticio generado por el sistema operativo como era antes.

Múltiples hilos dinámicos en .Net Ahora bien, en la entrega anterior habíamos definido un objetivo bien claro, que consistía en poder dividir los procesos críticos dinámicamente según la cantidad de núcleos de procesamiento disponibles y en base a ello generar tantos hilos de ejecución como sean necesarios. Podemos conseguirlo con 39

SOLO PROGRAMADORES nº 162


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 40

MIDDLEWARE

LISTADO 2

Código de ejemplo de la clase Circulo.

Lenguaje de Programación Visual Basic: Public Class Circulo Private priRadio As Double Private priDiametro As Double Public ReadOnly Property piDiametro() As Double Get piDiametro = priDiametro End Get End Property Public Property piRadio() As Double Get piRadio = priRadio End Get Set(ByVal value As Double) priRadio = value End Set End Property Public Sub CalcularDiametro() priDiametro = Math.PI * (priRadio ^ 2) End Sub End Class Lenguaje de Programación C#: using System; using System.Collections.Generic; using System.Text; namespace ThreadingCSharpEjemplo2 { class Circulo { private double _radio; private double _diametro; public double Diametro { get { return _diametro; } } public double Radio { get { return _radio; } set { _radio = value; } } public void calcularDiametro() { _diametro = Math.PI * Math.Pow(_radio, 2); } } }

BackgrounWorkers, pero, es conveniente presentar el ejemplo empleando la clase Thread a la que, a la larga, vamos a necesitar cuando busquemos mayor flexibilidad. En este caso, el objetivo es crear 24.000.000 (24 millones) de instancias de la clase Circulo, asignarle un valor a su radio y calcular el diámetro, guardarlos en múltiples colecciones del tipo ArrayList (tantas como

SOLO PROGRAMADORES nº 162

40

núcleos de procesamiento disponibles existan) y luego, finalmente, juntarlas en una colección que contenga a las 24 millones de instancias de la clase Circulo, lo que servirá para, entre otras cosas, mostrarla en una tabla. Este tipo de procesos es muy común en las aplicaciones que trabajan con bases de datos y es una muestra muy representativa de las

tareas que suelen llevar bastante tiempo e impacientan al usuario de un sistema informático. Por lo tanto, se trata de algo importante para ser optimizado con el uso de múltiples hilos de ejecución. En el Listado 2 presentamos el código de la clase Circulo, en el Listado 3 el de la aplicación que hace uso de la clase Thread en vez de emplear el presentado Background Worker, preparada para 4 hilos de ejecución fijos y en el Listado 4 esa misma aplicación, pero que automáticamente determina la cantidad de núcleos disponibles y divide la tarea en tantos como existan para conseguir el mejor rendimiento posible. En todos los casos, presentamos el código en Visual Basic y en C# (más adelante volveremos con Java). La clase Thread es lo suficientemente compleja como para que podamos quedarnos sin dormir muchos días seguidos intentando entender con suficiente nivel de detalle todas sus variantes de uso, por lo cual, la idea es simplificar su comprensión para su aplicación en el 80% de los casos más requeridos en la mayoría de los sistemas informáticos modernos. Dejaremos de lado ese 20% de los casos más específicos y complejos que requieren de otro enfoque. Además, estamos centrados en aprovechar el multiprocesamiento y no en otros usos que se pueden conseguir con los múltiples hilos de ejecución. Lo primero que hace el código del Listado 3 es declarar 4 variables del tipo Thread: t1, t2, t3 y t4, así como 5 variables del tipo ArrayList: colCirculos1, colCirculos2, colCirculos3 y colCirculos4 por un lado y colFinal, la cual contendrá la colección de círculos que será la sumatoria del contenido de los 4 ArrayList generados por hilos de ejecución independientes. De esto trata el proceso unificador de los resultados de múltiples hilos que hablábamos en la entrega anterior. Utilizamos Shared en Visual Basic y static en C#. Por otro lado se define el código que ejecutará cada uno de los 4 hilos de ejecución, en procedimientos independientes Proceso Thread1 a ProcesoThread4. Reciben como parámetro stateinfo (información de estado), del tipo Object y también utilizamos Shared en Visual Basic y static en C#. En el procedimiento Main, creamos las 4 instancias de la clase Thread pasándole como parámetro el método que deben ejecutar cuando arranquen, es decir, la tarea que llevarán a cabo. www.revistasprofesionales.com


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:10

Página 41

MIDDLEWARE

Programación con Múltiples Hilos (Threads) en Visual Basic; C# y Java (II)

Código de ejemplo de uso de 4 instancias de la clase Thread en forma estática para resolver un proceso.

LISTADO 3 Lenguaje de Programación Visual Basic: Imports System.Threading Imports System.Runtime.InteropServices Imports System.Text Imports System.Diagnostics Public Class ThreadingVBEjemplo2 Private Private Private Private

Shared Shared Shared Shared

t1 t2 t3 t4

As As As As

Thread Thread Thread Thread

Private Shared colCirculos1 As Collections.ArrayList() Private Shared colCirculos2 As Collections.ArrayList() Private Shared colCirculos3 As Collections.ArrayList() Private Shared colCirculos4 As Collections.ArrayList() Private Shared colFinal As New

New

= = = =

New New New New

Thread(AddressOf Thread(AddressOf Thread(AddressOf Thread(AddressOf

New New Collections.ArrayList()

ProcesoThread1) ProcesoThread2) ProcesoThread3) ProcesoThread4)

t1.Start() Thread.Sleep(0) t2.Start() Thread.Sleep(0) t3.Start() Thread.Sleep(0) t4.Start() Thread.Sleep(0) t1.Join() t2.Join() t3.Join() t4.Join() colFinal.AddRange(colCirculos1) colFinal.AddRange(colCirculos2) colFinal.AddRange(colCirculos3) colFinal.AddRange(colCirculos4) End Sub Public Shared Sub ProcesoThread1(ByVal stateinfo As Object) Dim i As Long Dim loCirculo As Circulo For i = 1 To 6000000 loCirculo = New Circulo loCirculo.piRadio = (i * 2) Mod 255 loCirculo.CalcularDiametro() colCirculos1.Add(loCirculo) Next End Sub Public Shared Sub ProcesoThread2(ByVal stateinfo As Object) Dim i As Long Dim loCirculo As Circulo For i = 1 To 6000000 loCirculo = New Circulo loCirculo.piRadio = (i * 3) Mod 255 loCirculo.CalcularDiametro() colCirculos2.Add(loCirculo) Next End Sub Public Shared Sub ProcesoThread3(ByVal stateinfo As Object)

www.revistasprofesionales.com

For i = 1 To 6000000 loCirculo = New Circulo loCirculo.piRadio = (i * 4) Mod 255 loCirculo.CalcularDiametro() colCirculos3.Add(loCirculo) Next End Sub Public Shared Sub ProcesoThread4(ByVal stateinfo As Object) Dim i As Long Dim loCirculo As Circulo

New

Public Shared Sub Main() t1 t2 t3 t4

Dim i As Long Dim loCirculo As Circulo

For i = 1 To 6000000 loCirculo = New Circulo loCirculo.piRadio = (i * 5) Mod 255 loCirculo.CalcularDiametro() colCirculos4.Add(loCirculo) Next End Sub End Class Lenguaje de Programación C#: using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Collections; namespace ThreadingCSharpEjemplo2 { class EjemploThreadsCSharp2 { private static Thread t1; private static Thread t2; private static Thread t3; private static Thread t4; private ArrayList(); private ArrayList(); private ArrayList(); private ArrayList(); private ArrayList();

static ArrayList colCirculos1 = new static ArrayList colCirculos2 = new static ArrayList colCirculos3 = new static ArrayList colCirculos4 = new static ArrayList colFinal = new

public static void Main() { t1 = new Thread(new ThreadStart(procesoThread1)); t2 = new Thread(new ThreadStart(procesoThread2)); t3 = new Thread(new ThreadStart(procesoThread3)); t4 = new Thread(new ThreadStart(procesoThread4)); t1.Start(); Thread.Sleep(0); t2.Start(); Thread.Sleep(0); t3.Start(); Thread.Sleep(0); t4.Start(); Thread.Sleep(0); t1.Join(); t2.Join(); t3.Join(); t4.Join(); colFinal.AddRange(colCirculos1);

41

SOLO PROGRAMADORES nº 162


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:11

Página 42

MIDDLEWARE

Códigos de ejemplo de un lazo ahora presentado en 4 hilos de ejecución independientes a través del componente BackgroundWorker.

LISTADO 3 colFinal.AddRange(colCirculos2); colFinal.AddRange(colCirculos3); colFinal.AddRange(colCirculos4);

public static void procesoThread3() { long i; Circulo loCirculo;

} public static void procesoThread1() { long i; Circulo loCirculo;

for (i = 1; i <= 6000000; i++) { loCirculo = new Circulo(); loCirculo.Radio = ((i * 4) % 255); loCirculo.calcularDiametro(); colCirculos3.Add(loCirculo); }

for (i = 1; i <= 6000000; i++ ) { loCirculo = new Circulo(); loCirculo.Radio = ((i * 2) % 255); loCirculo.calcularDiametro(); colCirculos1.Add(loCirculo); }

} public static void procesoThread4() { long i; Circulo loCirculo;

} public static void procesoThread2() { long i; Circulo loCirculo; for (i = 1; i <= 6000000; i++) { loCirculo = new Circulo(); loCirculo.Radio = ((i * 3) % 255); loCirculo.calcularDiametro(); colCirculos2.Add(loCirculo); }

for (i = 1; i <= 6000000; i++) { loCirculo = new Circulo(); loCirculo.Radio = ((i * 5) % 255); loCirculo.calcularDiametro(); colCirculos4.Add(loCirculo); } } } }

}

Figura 7. Visualizando la instrucción actual del hilo de ejecución correspondiente al BackgroundWorker1 en el entorno de desarrollo de Visual Studio 2008.

En Visual Basic, utilizamos AddressOf: t1 = New Thread(AddressOf ProcesoThread1) Y en C# una nueva instancia de ThreadStart con el nombre del método como parámetro: t1 = new Thread(new ThreadStart (proceso Thread1))

SOLO PROGRAMADORES nº 162

42

Ahora que ya tenemos creadas las instancias de la clase Thread, tenemos que indicarle que inicien su ejecución a cada una de ellas, llamando al método Start() y una pausa de 0 milisegundos en el hilo de ejecución principal con Thread.Sleep(0).

Luego, le indicamos a las 4 instancias de la clase Thread que se combinen con el hilo de ejecución principal mediante la llamada el método Join(), de esta manera, una vez que finalicen sus ejecuciones, en ese instante se seguirá con la ejecución de las instrucciones posteriores a estas llamadas, que, en este caso, se trata del agregado de los 4 ArrayList conformados a colFinal a través del método AddRange. De ese modo, una vez que los 4 hilos de ejecución en paralelo e independientes completen cada uno de ellos su ArrayList con los 6.000.000 (seis millones) de círculos, se agregarán uno a uno para conformar una gran colección de 24 millones de círculos. Las llamadas a los métodos Join serían equivalentes a las porciones de código que se muestran en el Listado 5, para poder comprender mejor su objetivo. Mientras alguno de los hilos esté ejecutando código, algo que sabemos llamando al método IsAlive(), el cual nos devuelve un valor booleano. Si es True (Verdadero), quiere decir que el hilo de ejecución todavía está en funcionamiento. Tengamos en cuenta que la llamada al método Sleep (Dormir) suspende la ejecución de un hilo por la cantidad de milisegundos especificada, pero sin consumir ciclos de reloj (no es como el lazo for que consumiría recursos). www.revistasprofesionales.com


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:11

Página 43

MIDDLEWARE

Programación con Múltiples Hilos (Threads) en Visual Basic; C# y Java (II) LISTADO 4

Código de ejemplo de uso de instancias dinámicas de la clase Thread según la cantidad de núcleos de procesamiento disponibles para resolver un proceso.

Lenguaje de Programación Visual Basic: Imports System.Threading Imports System.Runtime.InteropServices Imports System.Text Imports System.Diagnostics Public Class ThreadingVBEjemplo3 Public Class ThreadExample Private Shared miTotalDeCirculos As Integer = 24000000 Private Shared miCantidadDeProcesadores As Integer = Environment.ProcessorCount Private Shared threadsArray() As Thread Private Shared colCirculos() As Collections.ArrayList Private Shared colFinal As New Collections.ArrayList() ‘Public Declare Function SetThreadIdealProcessor Lib “kernel32.dll” _ ‘ Alias “SetThreadIdealProcessor” (ByVal hThread As Long, ByVal dwIdealProcessor As Long) As Long Public Shared Sub Main() ReDim threadsArray(miCantidadDeProcesadores - 1) ReDim colCirculos(miCantidadDeProcesadores - 1) Dim miNumeroThread As Integer For miNumeroThread = 0 To (miCantidadDeProcesadores - 1) threadsArray(miNumeroThread) = New Thread(AddressOf ProcesoThread) threadsArray(miNumeroThread).Name = miNumeroThread.ToString threadsArray(miNumeroThread).Start() Thread.Sleep(0) Next For miNumeroThread = 0 To (miCantidadDeProcesadores - 1) threadsArray(miNumeroThread).Join() Next For miNumeroThread = 0 To (miCantidadDeProcesadores - 1) colFinal.AddRange(colCirculos(miNumeroThread)) Next End Sub Public Shared Sub ProcesoThread(ByVal stateinfo As Object) Dim i As Long Dim miNumeroThread As Integer = CInt(Thread.CurrentThread.Name) Dim miCantidadDeCirculos As Long = CLng(miTotalDeCirculos / miCantidadDeProcesadores) Dim miMultiplicador As Integer = miNumeroThread + 1 Dim loCirculo As Circulo colCirculos(miNumeroThread) = New Collections.ArrayList(CInt(miCantidadDeCirculos)) For i = 1 To miCantidadDeCirculos loCirculo = New Circulo loCirculo.piRadio = ((i * miMultiplicador) Mod 255) loCirculo.CalcularDiametro() colCirculos(miNumeroThread).Add(loCirculo) Next End Sub End Class Lenguaje de Programación C#: using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Collections; namespace ThreadingCSharpEjemplo3 { class EjemploThreadsCSharp2 { private static int miTotalDeCirculos = 24000000; private static int miCantidadDeProcesadores = Environment.ProcessorCount;

www.revistasprofesionales.com

43

SOLO PROGRAMADORES nº 162


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:11

Página 44

MIDDLEWARE

Código de ejemplo de uso de instancias dinámicas de la clase Thread según la cantidad de núcleos de procesamiento disponibles para resolver un proceso.

LISTADO 4

private static Thread[] threadsArray; private static ArrayList[] colCirculos; private static ArrayList colFinal = new ArrayList(); public static void Main() { threadsArray = new Thread[miCantidadDeProcesadores]; colCirculos = new ArrayList[miCantidadDeProcesadores]; int miNumeroThread; for (miNumeroThread = 0; miNumeroThread < miCantidadDeProcesadores; miNumeroThread++) { threadsArray[miNumeroThread] = new Thread(new ThreadStart(procesoThread)); threadsArray[miNumeroThread].Name = miNumeroThread.ToString(); threadsArray[miNumeroThread].Start(); Thread.Sleep(0); } for (miNumeroThread = 0; miNumeroThread < miCantidadDeProcesadores; miNumeroThread++) { threadsArray[miNumeroThread].Join(); } for (miNumeroThread = 0; miNumeroThread < miCantidadDeProcesadores; miNumeroThread++) { colFinal.AddRange(colCirculos[miNumeroThread]); } } public static void procesoThread() { long i; int miNumeroThread = Convert.ToInt32(Thread.CurrentThread.Name); long miCantidadDeCirculos = miTotalDeCirculos / miCantidadDeProcesadores; int miMultiplicador = miNumeroThread + 1; Circulo loCirculo; colCirculos[miNumeroThread] = new ArrayList((int) miCantidadDeCirculos); for (i = 1; i <= miCantidadDeCirculos; i++) { loCirculo = new Circulo(); loCirculo.Radio = ((i * miMultiplicador) % 255); loCirculo.calcularDiametro(); colCirculos[miNumeroThread].Add(loCirculo); } } } }

El aprovechamiento del microprocesador de este ejemplo será de aproximadamente un 50% en los ordenadores equipados con múltiples núcleos de ejecución con Windows XP y rondando el 75% si utilizamos Windows Vista, en vez de menos del 25% que obtendríamos si no estuviese optimizado el código. Como vemos, no es tan complejo lanzar varios hilos de ejecución y tener el control de éstos. Pero, nuestro objetivo es hacerlo en forma dinámica, por lo cual, ahora que hemos visto cómo se utilizan las instancias de la clase Thread, lo haremos para que, tomando el ejemplo como base, el código resuelva en forma dinámica en cuántos

SOLO PROGRAMADORES nº 162

44

hilos debe dividir el trabajo. Y, con un mismo ejecutable, sin modificar nada del código, lo podamos ejecutar consiguiendo la mejor eficiencia posible en equipos con 1, 2, 3, 4, 6, 8, 16 o más núcleos de ejecución. El Listado 4 es un ejemplo de generalización tras una experiencia concreta y de pragmatismo, pues utilizamos la propiedad Name de cada instancia de Thread para fácilmente conseguir pasar un valor a un hilo de ejecución, algo que de otro modo podría requerir 3 entregas sólo para explicar otras metodologías. Recordemos que queremos programar con múltiples hilos de ejecución sin morir en el intento, entonces, vamos a ser pragmáticos.

Definimos variables de clase Shared en Visual Basic y static en C# para determinar la cantidad total de círculos que deseamos crear (miTotalDeCirculos), la cantidad de núcleos de procesamiento disponibles (miCantidad DeProcesadores) que aprendimos a obtener en la entrega anterior (y que podemos modificar con otros valores para visualizar las diferencias de resultados), una cadena (array) de instancias de Thread, una cadena de ArrayList colCirculos para que cada hilo de ejecución almacene en uno de las instancias de esa cadena la colección de círculos que genera y la cadena que unirá a todos los generados, colFinal. Como vemos, todo es dinámico, sin valores pre-estableciwww.revistasprofesionales.com


Middleware (Programacion multiple):MIDDLEWARE(Programacion multiple)

16/6/08

12:11

Página 45

MIDDLEWARE

Programación con Múltiples Hilos (Threads) en Visual Basic; C# y Java (II) dos, de manera tal que podrá ser cualquiera la cantidad de hilos de ejecución. Tomamos como base la cantidad de núcleos disponible en el ordenador, pero fácilmente lo podremos modificar (no hace falta explicarlo, se trata de ejemplos para experimentar al máximo y tomar como base para otras soluciones). El método ProcesoThread se utilizará para todos los hilos que se generen. Entonces, necesitamos que sepa qué número de hilo es para que agregue los círculos en la colección correspondiente de la cadena de instancias de ArrayList colCirculos. Aquí aparece uno de los grandes inconvenientes a la hora de dividir un proceso en múltiples hilos de ejecución. Cómo hablamos con un método que se lanza en forma asincrónica y con el cual no tenemos acceso directo a sus variables. Hay varias alternativas, una más compleja que la otra, como mencionábamos anteriormente. Elegimos la solución pragmática y le indicamos el número de hilo de ejecución en la propiedad Name (Nombre) de la instancia de la clase Thread que creamos, por lo cual, dentro del método lo puede saber obteniendo la el hilo actual, es decir, sabiendo quién es en ese momento, porque el método es común a todos los hilos, por lo tanto, es información que estará disponible en tiempo de ejecución, totalmente dinámica. Esto se consigue llamando a Thread.CurrentThread y más precisamente a Thread. CurrentThread. Name para saber el nombre del hilo que está representando. Convertido a un integer, se consigue el preciado número, que se almacena en la variable local miNumeroThread. Allí se resuelve uno de los enormes problemas de los múltiples hilos de ejecución y de la segmentación totalmente dinámica del procesamiento. En este caso, sirve al propósito ya explicado, pero en otros puede determinar la dirección de comienzo de procesamiento de un vector y la de finalización o de una matriz, según la tarea que lleve a cabo el método que llamará cada hilo, es decir, con este mismo esquema dinámico se pueden encarar múltiples procesos que requieren multiprocesamiento. En base a este número también se determina el multiplicador que antes estaba fijo. Se utiliza la cantidad de núcleos para determinar en forma dinámica la cantidad de círculos que debe generar cada hilo, se crea el ArrayList prefijando esa capacidad y se procede al ciclo que no requiere mayores explicaciones. www.revistasprofesionales.com

LISTADO 5

Código de ejemplo equivalente (o similar) a las llamadas a los métodos Join de las instancias de la clase Thread.

Lenguaje de Programación Visual Basic: Do While (t1.IsAlive() Or t2.IsAlive() Or t3.IsAlive() Or t4.IsAlive()) ‘ Mientras esté en ejecución alguno de los 4 hilos, hago una pausa en el hilo principal ‘ de 500 milisegundos Thread.Sleep(500) Loop Lenguaje de Programación C#: while (t1.IsAlive() || t2.IsAlive() || t3.IsAlive() || t4.IsAlive()) { // Mientras esté en ejecución alguno de los 4 hilos, hago una pausa en el hilo principal // de 500 milisegundos Thread.Sleep(500); }

En el procedimiento Main, dimensionamos los arreglos threadsArray y colCirculos según la cantidad de procesadores. Luego, creamos cada una de las instancias de la clase Thread, asignándole el método ProcesoThread y el nombre para cumplir con los objetivos explicados. Se llama al método Start() y se hace una pausa de 0 milisegundos en el hilo de ejecución principal con Thread.Sleep(0). Luego, en otro lazo diferente, pues ya deben estar creadas todas las instancias de la clase Thread antes de llamar a los Join(), le indicamos a todas las instancias de la clase Thread que se combinen con el hilo de ejecución principal mediante la llamada el método Join(), de esta manera, una vez que finalicen sus ejecuciones, se seguirá con la ejecución de las instrucciones posteriores a estas llamadas. En este caso, se trata del agregado de todos los ArrayList conformados a colFinal a través de un lazo que hace n llamadas al método AddRange. De ese modo, una vez que los n hilos de ejecución en paralelo e independientes completen cada uno de ellos su ArrayList correspondiente con los x círculos, se agregarán uno a uno para conformar una gran colección de 24 millones de círculos, o del valor que hayamos especificado para la variable miTotalDeCirculos. Pues, ahora el sistema es totalmente dinámico y nos permite experimentar.

Conclusión Bill Dally, jefe del departamento de ciencias de la computación de Stanford (chairman of the computer science department at Stanford) se refirió recientemente a la programación paralela como “quizás el problema más grande en las ciencias de la computación actuales y el mayor obstáculo para seguir escalando el rendimiento de cómputo que ha alimentado a la industria

de los ordenadores, y a varias industrias relacionadas, por los últimos 40 años”. El miedo a que la falta de conocimiento de los desarrolladores del aprovechamiento del paralelismo frene fuertemente el crecimiento de la capacidad de procesamiento de los sistemas informáticos está instalado en todo el mundo. Esto a unido a que, por ejemplo, gigantes de la industria tecnológica hayan conformado un equipo junto con la Universidad de Stanford (Stanford University) para desarrollar una plataforma dedicada a la computación paralela y que a partir del laboratorio se logren avances importantes en el aprovechamiento del multiprocesamiento hacia el año 2012. Tomamos como ejemplo esta novedad, de la cual participan científicos e ingenieros con el soporte de AMD, HP, IBM, Intel, NVidia y Sun Microsystems. Por lo tanto, todo lo que aprendamos y experimentemos con los múltiples hilos de ejecución y con el aprovechamiento del multiprocesamiento rendirá muchos frutos por varios años, sino décadas. En esta entrega, hemos profundizado en cómo conseguir múltiples hilos de ejecución inclusive en forma totalmente dinámica. En la siguiente entrega analizaremos cómo llevarlo a cabo en el lenguaje de programación Java y luego desarrollaremos un caso más complejo para ver otro patrón de trabajo muy común, el de distribuir el procesamiento de estadísticas a partir de la obtención de datos desde una fuente de datos (motores de bases de datos, matrices, otros ficheros, XML, etc.). Profundizaremos en la resolución de mínimos y máximos en cada hilo y luego en general y en algunos problemas que se presentan en estos casos y cómo resolverlos para conseguir el mayor rendimiento posible. 45

SOLO PROGRAMADORES nº 162


DISPMOVILES-Virus en moviles:DISPMOVILES-Virus en moviles

16/6/08

12:26

Página 46

DISPOSITIVOS MÓVILES

Los virus llegan a la telefonía móvil Los teléfonos móviles son dispositivos cada vez más complejos y potentes que han mutado hacia diminutos ordenadores cuya vulnerabilidad aumenta paradójicamente conforme lo hace su tecnología. Y es que un teléfono móvil más avanzado implica también una mayor probabilidad de sucumbir ante diversas amenazas víricas.

NICOLÁS VELÁSQUEZ ESPINEL

Nos encontramos inmersos en la era de la telefonía móvil, una época que ha visto como en la última década el crecimiento de uso de dispositivos móviles ha alcanzado unas cotas difícilmente predecibles aún por el gurú más visionario. Lo que se presentaba como una moda pasajera y relegada a un sector de la población más elitista, se ha vuelto un artículo indispensable para todos los segmentos de la población que ya lo han adoptado en mayor o menor medida, haciéndolo partícipe de su vida cotidiana. Esta popularización también lo ha convertido en el centro y objetivo de algunos malintencionados que han visto en él el medio perfecto a través del cual perpetuar lo que desafortunadamente ya es una constante en el mundo del PC: los virus. Con el crecimiento de las aplicaciones para teléfonos móviles, smartphones, PDAs, Blackberrys y otros dispositivos móviles, se ha abierto un nuevo camino para la aparición de los códigos maliciosos más avanzados, y con ellos la posibilidad de perder datos confidenciales, el envío de mensajes no deseados, o hasta el acceso a la cuenta del banco de los usuarios. Los primeros casos de virus en teléfonos móviles nacían como pruebas de concepto, experimentos inocuos en cuanto a sus resultados reales pero que pretendían demostrar cuán vulnerables podían llegar a ser si alguien los ponía en práctica, tal como ya ocurriera en su momento con sus homó-

SOLO PROGRAMADORES nº 162

46

logos del mundo de los ordenadores, lo que hacía presagiar que la historia volvería a repetirse y que sólo era cuestión de tiempo. Lo cierto es que la virología móvil ya tiene su propia página en la historia tecnología más reciente y la prueba es que los desarrolladores de antivirus han hecho saltar ya todas las alarmas sobre este tipo de amenaza. Y es que los ciberdelincuentes no cejan en su empeño de encontrar nuevas, y cada vez más ingeniosas, formas con las que perjudicar a los usuarios, cuando no lucrarse a costa de ellos de forma ilegal. De ahí que hayan aparecido amenazas con apelativos tan llamativos como Battery Draining, SMS Interception o Vishing o SMiShing. Por ejemplo el Battery Draining o Agotamiento de batería, aunque en un principio no resulte potencialmente peligroso, si que resulta muy molesto. Se inicia cuando el atacante envía mensajes con datos basura consiguiendo que el teléfono salga del modo de espera (stand by) para tratar de determinar si el mensaje recibido es válido. En la mayoría de los casos el usuario no se dará ni cuenta de lo que está sucediendo, si no está atento a su terminal. La consecuencia es que con el cambio constante de estado entre encendido y en espera del teléfono, la batería se agotará a un ritmo 20 veces más rápido de lo normal. Por otro lado, el SMS Interception o Interceptación SMS, es otra amenaza aunque realmente conlleva poco peligro. Según indican sus descubridores, los mensajes SMS que recibe un móvil pueden ser interceptados sin nuestro conocimiento. No obstante para ello el atacante debe tener acceso físico al móvil de la víctima para reprogramarlo de manera que los mensajes SMS recibidos sean desviados al terminal del atacante, además de ser mostrados con total normalidad en el móvil de la víctima. Este tipo de ataques es mucho menos factible, aparte de que parece ser que sólo es posible si tanto el atacante como la víctima disponen de terminales CDMA (estándar usado en EE.UU., pero no en Europa donde se impone GSM). Pese a que no se hayan producido aún casos tan críticos como el del virus I Love You o el Melissa que pusieron en jaque a miles de empresas provocando pérdidas millonarias, el consumidor móvil ya es consciente del peligro que acecha a su terminal. De hecho, recientemente se ha hecho público www.revistasprofesionales.com


DISPMOVILES-Virus en moviles:DISPMOVILES-Virus en moviles

16/6/08

12:26

Página 47

Los virus llegan a la telefonía móvil

que 3 de cada 4 usuarios están ya en alerta ante posibles amenazas, normalmente más asociadas a cobros fraudulentos en las cuentas, y a la pérdida o robo de información. McAfee publicaba recientemente un informe sobre seguridad móvil en el que barajaba una cifra del 72% de usuarios preocupados por este hecho. Eso sin contar con un porcentaje bastante razonable (el 34%) que cuestiona la seguridad de los dispositivos y servicios móviles y otro tanto preocupado por posibles amenazas provenientes de las descargas multimedia. La realidad es que un 79 por ciento de los consumidores usa equipos no protegidos, con un 15 por ciento adicional que no tiene la certeza de los niveles de seguridad. Asimismo, más de la mitad de los suscriptores (el 59%) espera que los operadores móviles asuman la responsabilidad principal de las tareas de protección. El perfil del usuario medio dispone ya de una cultura tecnológica que le permite ser consciente de los riesgos que pueden aguardar a la vuelta de la esquina y el auge de servicios móviles emergentes ha aumentado el índice de preocupación. No hay que olvidar que 1 de cada 10 usuarios móviles en el mundo estuvieron expuestos a incidentes con virus móviles, ya sea directamente o conocen alguien que estuvo contagiado. Por si fuera poco, otro frente ante el que tenemos que batirnos proviene de la mensajería móvil no deseada, el spam tradicional, que ya alcanza a un 38,6% de usuarios que recibe mensajes molestos al menos una vez al mes.

El primer virus para móviles apareció hace menos de 4 años España, país creador del mito picaresco no podía ser ajeno a esta nueva tendencia y así lo dejó patente con el famoso caso de Timofónica en el año 2000 que, aunque no llegaba a ser realmente un virus propio de móviles, lograba que estos padecieran directamente sus consecuencias. El responsable era el virus informático VBS/Timofónica que se coló en miles de ordenadores de clientes de teléfonos móviles con acceso a Internet de la compañía Telefónica. El equipo infectado reenviaba correos electrónicos aprovechando una pasarela del sistema que a su vez permitía el envío de mensajes a móviles al azar desde el correo, en este caso con insultos a los clientes de esta empresa. www.revistasprofesionales.com

Los ciberdelincuentes han encontrado en la telefonía móvil un nuevo filón.

Ese mismo año corrió el rumor de que determinados modelos de teléfonos móviles de la marca Nokia podían quedarse colgados temporalmente si se les enviaba ciertos mensajes de texto, codificados de una forma especial. El problema se solucionaba, en teoría, quitando la batería del aparato y volviendo a conectarla. Asimismo, el sistema de telefonía multimedia utilizado en Japón llamado i-mode tuvo que enfrentarse en 2003 con ataques en sus redes cuando los móviles del país nipón empezaron a recibir un mensaje con un enlace a un sitio con código Java. Si se accedía al mismo se ejecutaba automáticamente una llamada a un número de emergencia (911). Aunque se propagó rápidamente entre los usuarios japoneses, la infección se detuvo en seguida ya que no funcionaba sobre terminales Nokia (que usaban el Symbian) o el Motorola, basados en Windows Mobile. En lo que a nosotros respecta, fue el 15 de junio de 2004 cuando apareció en escena el primer virus para móviles, la primera aplicación que hacía que el teléfono se comportara de forma anómala, haciendo saltar todas las alarmas y confirmando que los terminales de telefonía móvil se habían convertido en el próximo objetivo de hackers y programadores maliciosos. El nombre del susodicho primer virus conocido para móviles era Cabir (aunque tenía otros alias como Epoc.Cabir, EPOC/Cabir.A, Worm.Symbian.Cabir.a, Symbian/Cabir.b, Epoc/Cabir.A.worm o Symb/Cabir-A). Pertenecía al grupo de los llamados gusanos, aplicaciones que tienen por objetivo realizar copias de sí mismo en otros terminales y que pueden llegar a causar daños en la transmisión por saturación de la red, aunque esta no tiene por qué ser su función principal. Ese día varias empresas de antivirus, entre las que se encuentran Kaspersky Labs y Symantec, recibieron una copia del código

DISPOSITIVOS MÓVILES

creado por un grupo clandestino de programadores denominado 29A (en concreto uno que se hace llamar Vallez), más interesado en el desafío intelectual que supone crear códigos que ataquen nuevas tecnologías y conocidos por haber sido los primeros en crear virus para plataformas .NET, NTFS o Win64. El gusano creado infectaba sólo a los teléfonos móviles que utilizaban el sistema operativo Symbian incluido en terminales Nokia, Siemmens, Sony Ericsson o Samsung que, además, incorporaran la tecnología inalámbrica Bluetooth, que permite la conexión sin cables de dispositivos electrónicos como teclados o PDAs. Mediante este tipo de comunicación, el virus intentaba pasar de un móvil a otro, reenviándose camuflado como un archivo de seguridad del sistema. Al usuario le llegaba un fichero llamado “caribe.sis”, que es una aplicación propia de Symbian (la extensión “sis” equivale a la EXE en un sistema operativo Windows) de 15092 bytes de longitud. Si aceptaba la transmisión, el virus instalaba los archivos caribe.app, flo.mdl y caribe.rsc en el directorio “\system\apps\” del móvil, mostrando un mensaje en pantalla del teléfono móvil infectado con el texto: “Caribe” cada vez que este se encendía ya que hacía creer al dispositivo que se trataba de la utilidad Caribe Security Manager. En ese momento el móvil iniciaba el rastreo mediante Bluetooth (en un radio de unos 30 metros que es el que permite esta tecnología) de la zona con la intención de enviar el virus a otro teléfono compatible, acortando considerablemente la duración de la batería. Cada vez que el móvil se encendía, el gusano se activaba y empezaba el rastreo. Si encontraba un equipo disponible, el gusano enviaba una petición de transferencia que, de ser aceptada por usuario destinatario, se copiaba y así sucesivamente. Para desinfectar un terminal infectado era necesario conectarlo al ordenador mediante

Un virus puede hacer que el terminal busque continuamente una red agotando la batería.

47

SOLO PROGRAMADORES nº 162


DISPMOVILES-Virus en moviles:DISPMOVILES-Virus en moviles

16/6/08

12:26

Página 48

DISPOSITIVOS MÓVILES

El ataque SMS Interception demuestra que los datos que contiene tu teléfono pueden ser importantes para otros.

un programa de gestión de archivos que permitiera ver los directorios internos del móvil para eliminar los archivos correspondientes. Algunas fuentes indicaron que también se reenviaba a todos los contactos de la agenda antes de borrarla, aunque esto último no se llegó a demostrar. Aunque los autores de este virus lo diseñaron para poder propagarse masivamente, se trataba de una prueba de concepto que dejaba patente que tenía la capacidad de crear código malicioso para infectar terminales. Por este motivo Cabir fue clasificado como una amenaza de bajo nivel, visto que sólo podía propagarse a unos teléfonos en concreto, en un radio limitado. Además, una vez hecho, no destruía archivos o ejecutaba otro tipo de operaciones perjudiciales para el usuario y para tener éxito era necesario que el usuario aceptara expresamente la instalación de una aplicación desconocida.

habilitada, y cambia los iconos de las aplicaciones por la imagen de una calavera con dos tibias cruzadas. InfoJack es un troyano que ataca a los dispositivos con Windows Mobile que filtran la información desde el dispositivo a un servidor cuando éste se conecta a Internet. Como parte de su actividad, InfoJack altera los ajustes de seguridad del terminal lo que provoca que todo el software que se instale no disponga de las alertas pertinentes en caso de tener que tomar precauciones de seguridad. Esto es posible debido a que se trata de un troyano con múltiples partes de malware. La primera de ellas está adjunta a muchos archivos de instalación que contienen software legal como juegos, aplicaciones de mapas, entre otros. De hecho, InfoJack simula ser un programa que se puede añadir al dispositivo y, una vez que lo ha infectado, espera a que el usuario establezca una conexión a Internet que, cuando se produce, se conecta a un servidor y descarga partes adicionales para su entrada en funcionamiento. Mientras esto se realiza, se va filtrando información desde este dispositivo al servidor. Una vez realizado, InfoJack cambia los ajustes de seguridad del terminal para permitir que se completen todas las instalaciones de software que realiza el usuario sin que se instalen las alertas de seguridad correspondientes. Por el momento, se desconocen los dispositivos que han podido ser infectados con este nuevo troyano específico para móviles.

Y el 2008 empieza fuerte con InfoJack Cuatro años corresponde a toda una eternidad en su equivalente tecnológico. Y este es el tiempo que ha pasado desde la aparición del primer virus como prueba de concepto (desde entonces se han contabilizado hasta un total de 395 malware) a lo que desde FSecure se ha calificado como el primer troyano de este tipo descubierto concretamente para dispositivos móviles. Conocido con el nombre de InfoJack, o Trojan Lince/InfoJack, se trata de un nuevo virus en forma de troyano desarrollado específicamente para dispositivos móviles, aunque antes pudimos ver el troyano Skulls que afecta a teléfonos móviles que usan el sistema operativo Symbian (reemplaza todas las aplicaciones del sistema por versiones no operativas de las mismas, de modo que la funcionalidad del teléfono móvil queda des-

SOLO PROGRAMADORES nº 162

48

El SMiShing Diariamente circulan por la redes de los operadores de telefonía millones de mensajes SMS con todo tipo de contenidos, aunque recientemente se ha detectado uno en parti-

Si el terminal se infecta con algún virus la primera reacción será de impotencia.

El virus normalmente entrará como un mensaje SMS aparentemente inocuo.

cular que podría resultar muy peligroso si no se toman las medidas oportunas. Se trata de una variante de SMS que ya ha sido bautizado como SMiShing y que ha resultado ser la mezcla explosiva entre el conocido Phishing y la popular mensajería a través de dispositivos móviles. El Phishing es una técnica de sobra conocida que consiste en un e-mail supuestamente enviado por alguna entidad (generalmente un banco o similar) que insta al usuario a acceder a su cuenta para por ejemplo actualizar los datos desde el enlace provisto en dicho mensaje. El problema es que dicho enlace enmascara una dirección web falsa (que imitará con todo tipo de detalles la web original) donde el servidor del atacante capturará las claves de la incauta víctima en lo que será la antesala de un proceso de estafa en nuestras cuentas bancarias. Esta técnica, que supone hoy por hoy todo un dolor de cabeza para las unidades dedicadas a perseguir delitos informáticos, ha saltado la barrera tecnológica del PC al teléfono móvil, adaptando sus sistemas para obtener los mismos resultados. La mecánica del SMiShing consiste en engañar a los usuarios para que revelen información privada valiosa, o sean persuadidos para dirigirse a sitios web falsos que contienen algún tipo de programa malicioso (spywares, troyanos) que se instalarán sin el consentimiento del usuario. Es una evolución del conocido spam que emplea técnicas de ingeniería social (la práctica de obtener información confidencial a través de la manipulación de usuarios, aprovechándose de su falta de conocimientos). La diferencia con respecto a los ataques víricos típicos es que no arremete directamente contra los terminales móviles si no que se aprovecha de estos a modo de vector para la ingeniería social. Aquí quien elabora este tipo de ataques tiene una motivación econówww.revistasprofesionales.com


DISPMOVILES-Virus en moviles:DISPMOVILES-Virus en moviles

16/6/08

12:26

Página 49

Los virus llegan a la telefonía móvil

mica y no “exhibicionista” (más propia ésta última de piratas informáticos) con el fin de hacerse con información sensible. El término nace de la combinación de palabras resultantes del modo en el que llegan los virus a los teléfonos móviles (un mensaje SMS) y la técnica social sobre la que están basados (Phishing), creando así un nuevo híbrido llamado SMiShing, también conocido como Phishing vía SMS.

Cómo trabaja El ataque se inicia cuando recibimos un mensaje SMS en el que se nos indica, por ejemplo, que debido a que nos hemos suscrito una oferta de trabajo o a un servicio de citas online se nos cargará un importe (de algunos euros por día) a nuestra factura telefónica. También se ofrece un enlace para que desde el propio teléfono podamos entrar al sitio web y dar de baja dicha suscripción ficticia. Si el usuario cae en la trampa y accede al enlace en cuestión, habrá cometido el error que estaban esperando los ciberdelincuentes. En ese preciso momento se descargará un programa troyano (o cualquier otra aplicación de tipo malware) que dejará al usuario expuesto a ataques externos. El peligro radica básicamente en el tipo de programa que se descargue desde el sitio web, aprovechándose de un agujero de seguridad de Windows. Los primeros casos que se conocen ocurrieron fuera de nuestras fronteras. Se empezaron a recibir mensajes que venía a decir algo así como: “Estamos confirmando que se ha dado de alta para un servicio de citas. Se le cobrará 2 dólares al día a menos que cancele su petición: www.XXXXXX.com”. Para evitar dicho pago, los usuarios se conectaban a la citada página con el fin de

El SMiShing tuvo su origen en China y el mensaje recibido tenía esta forma.

www.revistasprofesionales.com

El ataque SMiShing puede enviar un mensaje creíble que ofrece descargarse gratuitamente un antivirus.

obtener más información o darse de baja, aunque para ello fuera necesario divulgar datos personales y bancarios. Gran Bretaña e Islandia sufrieron los primeros brotes de este tipo de ataque. En el momento en el que la víctima cae en la trampa accediendo a la página web y permitiendo inconscientemente instalar un programa troyano en su PC, este equipo se convierte en lo que se conoce como una máquina zombi, un ordenador controlado por terceros que, en el caso que nos ocupa, son delincuentes. En este preciso instante, el equipo pasa a formar parte de una red de cientos o miles de bots (conformando una botnet), que se usa para lanzar ataques de denegación de servicio (DoS), instalar software capturador de teclado (keylogger), robar información de cuentas personales, enviar Spam y demás actividades de corte ilegal. En definitiva, todo un compendio de actividades fuera de la ley que utilizan este tipo de pasarelas para lanzar sus ataques. En otros países como en Chile, es cada vez más frecuente el Spam móvil con mensajes que invitan a revelar datos para ganar supuestos premios e, incluso, para ciertos fraudes de tarjetas telefónicas. En la actualidad incluso ya se ha liberado una nueva variante de la estafa llamada Vishing que hace uso de la telefonía IP y cuyo lugar de aparición y de máxima presencia ha sido hasta ahora Australia y Estados Unidos. Allí, los delincuentes han aprovechado las ventajas que ofrece la telefonía VoIP (Voz sobre IP) para enviar mensajes SMS indicando un número de teléfono al que se conmina a llamar para realizar determinada consulta o corrección de datos. En este

DISPOSITIVOS MÓVILES

número, mediante la grabación virtual de un sistema automatizado, se solicita a la victima su número de tarjeta, contraseña y demás información privada. Se trata de cambiar el método clásico de desviarnos hacia una página maliciosa a instarnos ahora a que llamemos a un número de teléfono, un medio por el los usuarios sienten menos aprensión que por la red de redes o el correo electrónico, unos medios tan saturados ya de ataque ilegales (lo que en un principio augura un buen porcentaje de éxito en sus estafas). Los expertos ya anuncian que este tipo de fraude tenderá a crecer debido en gran parte a que la VoIP es fácil de usar, tiene bajo coste y su funcionamiento se adapta a los objetivos de los ciberdelincuentes. Incluso existen programas para crear centralitas que simulan ser una empresa con voces grabadas de profesionales que pueden estar instaladas en cualquier lugar del mundo, utilizando un número local redireccionado. El primer caso se dio en China, en octubre del 2006. Un ciudadano Pekinés, el señor Wang, recibió un mensaje en su móvil informándole que el banco le había cargado la compra de objetos valorados en más de 2.000 euros. Se adjuntaba un número de teléfono al que llamar para solicitar información al respecto. Wang lo hizo y una voz grabada le pidió los datos de su cuenta. Horas después se la habían dejado en números rojos.

Zombies Made in Spain Como es lógico, enviar un SMS resulta mucho más caro que la difusión por e-mail de una estafa, lo que de momento dificulta su expansión. Por ello es fundamental para los agresores usar pasarelas SMS que pueden resultar económicas, o servicios de correo proporcionados por las operadoras, que facilitan el envío gratuito de un SMS

Un mensaje nos recomendará acceder a una web que descargará un troyano en nuestro PC.

49

SOLO PROGRAMADORES nº 162


DISPMOVILES-Virus en moviles:DISPMOVILES-Virus en moviles

16/6/08

12:26

Página 50

DISPOSITIVOS MÓVILES

como si fuera un correo electrónico (numerotelefono@operadora.com). En este caso el ataque se ejecuta en dos fases claramente definidas. La primera de ellas consiste en crear las botnets o redes de ordenadores zombies que servirán como plataforma de lanzamiento para los envíos masivos de mensajes SMS por medio de las pasarelas apropiadas, un proceso que se sirve de las clásicas técnicas de infección vírica de sistemas y para la que se emplea el típico gusano que se propaga por varios sistemas sirviéndose de agujeros de seguridad y de la ingenuidad de sus usuarios. El gusano Eliles-A ha tenido por ejemplo cierta incidencia en España. Todo comienza con la llegada de un adjunto al correo electrónico que supuestamente contiene el currículum de un aspirante para un puesto de trabajo. Si se ejecuta el fichero bajo Windows, el PC quedará comprometido y podrá ser utilizado para el envío de SMS de forma automática, calculando números de móviles españoles al azar en base a un algoritmo programado a tal fin. En realidad se trata de un gusano estándar VBS (<VBS/Eliles.A>), un troyano que abre la puerta trasera en el sistema de sus víctimas, programado en Visual Basic Script. Llega por e-mail con el asunto “Curriculum Vitae para posible vacante” y cuerpo siguiente: “Adjunto Curriculum Vitae, por estar interesado en algún puesto vacante en su empresa, me encantaría que lo tuviera en cuenta,

La web de contactos de pago era un señuelo para descargar un troyano.

SOLO PROGRAMADORES nº 162

50

Estructura del ataque SMiShing sucedido en España.

ya que estoy buscando trabajo por esa zona. Sin más, reciba un cordial saludo.” Al abrir el archivo se liberará un gusano que se replicará con el nombre C.Vitae.zip reenviándose a todos los destinatarios de correo electrónico que encuentre en el sistema. De la misma forma, podrá llegar a inutilizar algunos programas antivirus que estén instalados en el PC, editando determinadas entradas en el Registro de Windows para asegurarse que se ejecuta en cada arranque del sistema. Una vez completado este primer paso, el ciberdelincuente tendrá la plataforma necesaria desde la que podrá lanzar los ataques a teléfonos móviles. La tarea del gusano pasa ahora por enviar mensajes a los usuarios de ciertas operadoras de telefonía móvil en España. En lugar de calcular la dirección IP al azar con la que enviar mensajes, este gusano genera números de teléfono dentro de los rangos utilizados en la telefonía móvil y envía su mensaje trampa gratuitamente desde la página de SMS-Correo electrónico que posean los operadores de telefonía móvil. Otros casos hablan de mensajes con textos en español, y algunos comentarios en alemán. Esta incongruencia, junto con las variaciones en el estilo de códigos de las diferentes funciones internas, hace pensar que el virus de este gusano está compuesto desde diferentes orígenes, sacado de gran variedad de otros códigos dispares (como si se tratara de un collage), y por lo tanto creado y ensamblado por lo que se conoce como un script kiddie, alguien que presume de ser un hacker o cracker pero que en realidad no posee un grado de conocimientos suficientes y que básicamente “copia y pega” partes de código malicioso. Eliles no usa un error en la facturación como gancho. En cambio puede ofrecer como cebo la posibilidad de descargar gratuitamente un programa antivirus para el teléfono mediante un mensaje corto que asegura

venir de parte del operador de telefonía móvil. Si se descarga e instala el programa desde el enlace provisto (un archivo SIS para móviles Symbian) se infectará con el virus. El mensaje SMS tiene la siguiente estructura: Remitente: La dirección de e-mail del usuario afectado. Destinatario: el teléfono móvil del destinatario seguido del dominio: @[operatorname].es @[operatorname].es Asunto: “Msj Operador: Proteja su móvil” Mensaje: “Descárguese gratis el Antivirus para Nokias Series 60. (6630,6680,7610, 7650,N70,N90), totalmente gratuito. http://f1.grp.ya<blocked>r8GMzmLAO7taS5 yJIVcWx2F_6NWlo_LBonXVhAfgMBbxzzC4L oS8XSwl_-YO7ZMH01Sw/Antivirus.sis McAfee ya ha desactivado enlaces para la supuesta descarga del programa antivirus aunque lo cierto es que de momento no está muy claro qué hace el virus en el móvil una vez instalado. Y es que los ataques no han tenido demasiado éxito.

Un futuro incierto De acuerdo con las predicciones hechas por McAfee, los ataques SMiShing serán más comunes conforme los teléfonos móviles sean más “inteligentes” y estén más conectados. Se espera que en el año 2008 aumenten los ataques a móviles extendiéndose con más virulencia por Europa y Japón donde hay terminales móviles más avanzados, aunque, según la compañía norteamericana, esto no es más que la avanzadilla para propagarse al resto del mundo. El SMiShing sufre de numerosos obstáculos para propagarse y llegar a provocar problemas graves (como por ejemplo el coste más elevado en comparación con el Phishing tradicional). No obstante, debido a lo novedoso del método, también puede tener como resultado un número de víctimas potencial más alto, no acostumbradas a este tipo de ataques. Un sistema que podría ser rentable para las mafias en un futuro. No deja de ser curioso el hecho de que haya empezado atacando directamente a móviles españoles (antes que a otros países tradicionalmente pioneros en estos campos) así como por lo elaborado del sistema de infección que, aunque no llegará muy lejos, quizás si que siente las bases para futuros sistemas “integrados” más avanzados de infección donde se vean implicados métodos de virus tradicionales, phishing y dispositivos www.revistasprofesionales.com


DISPMOVILES-Virus en moviles:DISPMOVILES-Virus en moviles

16/6/08

12:26

Página 51

Los virus llegan a la telefonía móvil

El teléfono móvil se ha vuelto un artículo indispensable en nuestra sociedad.

móviles. Estos últimos, con una capacidad cada vez mayor para conectarse entre sí y a otros sistemas, pueden ser un interesante objetivo para las mafias informáticas en un futuro no muy lejano. Ya hemos asistido a problemas de cierta consideración con el virus para móviles Commwarrior en España, y algunas casas antivirus ya han creado productos específicos. Debido a que crece constantemente el volumen de teléfonos móviles con funciones avanzadas de conexión a Internet, conviene tomar medidas cada vez más serias en lo relacionado a la protección del usuario. El teléfono móvil se está convirtiendo en mucho más que una simple herramienta de comunicación de individuo a individuo, y el papel de los operadores móviles como protectores de la experiencia del cliente es cada vez más complejo. En el caso de que las propias operadoras decidan adoptar el papel de protectores y asumir la responsabilidad que ello conlleva, tendremos parte del camino andado para disminuir el impacto negativo de un ataque de estas características. Es complicado hacer algún tipo de predicción acerca de las amenazas futuras que puedan sufrir las redes empresariales una vez que los hackers aprendan a explotar completamente las técnicas de SMiShing.

ataque de SMiShing. El objetivo principal de la amenaza son los dos mayores operadores de telefonía móvil en España, y el gancho el envío de mensajes de texto para descargas gratuitas por SMS. También hay que destacar que los mensajes atacantes van dirigidos especialmente a usuarios que dispongan de teléfonos, por ejemplo, de la Series 60 de Nokia. Destaca por ser el primer ejemplo de amenaza móvil proveniente del sector de ordenadores hacia el de los teléfonos móviles, y encima teniendo en cuenta que el ataque de SMiShing evoluciona desde un simple gusano de envío de e-mail masivo. Las pasarelas empleadas son servicios públicos que consisten en direcciones de correo electrónico a las que se pueden mandar mensajes SMS para los clientes de las operadoras. Puedes obtener más información sobre cómo acceder a la entrada de SMS de los operadores visitando la página: http://hiptools.net/sms/ De momento Movistar y McAfee coinciden en que la incidencia del gusano ha sido mínima y la operadora inclusive asegura no haber recibido reclamaciones de clientes.

El iPhone en el punto de mira Ya casi nadie es ajeno a la creciente popularidad del teléfono iPhone de Apple, incluso en nuestro país donde todavía no se ha comercializado. Por ello, muchos programadores ya tienen como reto desarrollar el primer virus que afecte a este dispositivo y la consiguiente fama que esto le aporte. Ya puede encontrarse en la red algún que otro testimonio de cómo podría funcionar

Huella digital Cada ataque destaca por tener una huella digital que lo distingue del resto y que, entre otras cosas, sirve para que los desarrolladores de antivirus lo localicen de forma efectiva. El SMiShing no iba a ser una excepción y, pese a llevar poco tiempo entre nosotros, ya ha sido estudiado en profundidad por prestigiosas compañías como McAfee o Panda. Los aspectos claves que podemos distinguir en esta nueva amenaza comienzan por la presencia de un simple gusano de envío masivo de e-mail, antes de convertirse en un www.revistasprofesionales.com

F-Secure ha publicado el aspecto del virus Skulls para móviles.

DISPOSITIVOS MÓVILES

un virus en un iPhone, y cómo podría enviar a un lugar remoto todo tipo de información, sin que el usuario se diera siquiera cuenta de la transferencia de datos. En la página http://www.iphoneros.com/?p=700, podrás encontrar un vídeo muy ilustrativo (en inglés). En éste se explica cómo hace falta tener acceso de administrador (root), lo que permitirá acceder a la agenda, mensajes y a todo el contenido privado almacenado en el iPhone. Aunque sólo se trate de una “prueba de concepto”, demuestra claramente por qué Apple desea tener control absoluto sobre cuándo y cómo se publicarán las aplicaciones de terceros para su dispositivo. Sin un control adecuado, un iPhone libre y sin control del fabricante podría ser el caldo de cultivo perfecto para la proliferación de virus. Por lo pronto, Steve Jobs ha prometido tomar medidas para evitar que en el iPhone puedan colarse virus o contenidos inapropiados. Desde su punto de vista, una tienda online de software legal será una solución ideal contra programas para el iPhone que circulen por Internet sin su autorización expresa. Por otra parte, al llevar un registro exhaustivo de desarrolladores, Apple estará en condiciones de identificar a los infractores y bloquear sus productos. Los desarrolladores de antivirus también se han pronunciado al respecto. F-Secure, por ejemplo, informaba el pasado mes de enero que había detectado el primer virus para el iPhone. Según la empresa, el ataque se presenta como una actualización del programa Erica’s Utilities (bajo el nombre de 113.prep). El virus muestra la palabra Shoes (zapatos) en la pantalla y, aunque en un principio parece un mensaje inofensivo, los daños que provoca pueden ser importantes al intentar desinstalarlo ya que eliminará la carpeta /bin, destrozando varias aplicaciones como Sendfile o Erica’s Utilities. Según informan, el troyano sólo ataca a los iPhones liberados de forma ilegal, mientras que por el momento los originales con firmware de Apple están a salvo. Ahora bien, quizás lo más destacado de esta noticia no sea que se trate del primer virus para iPhone, si no que su creador ha sido un niño de tan solo 11 años. La firma rusa Kaspersky también es muy consciente del peligro al que están expuestos los usuarios de un iPhone. Y es que aprovechando que este dispositivo puede navegar por la red, los informáticos malintencio51

SOLO PROGRAMADORES nº 162


DISPMOVILES-Virus en moviles:DISPMOVILES-Virus en moviles

16/6/08

12:26

Página 52

DISPOSITIVOS MÓVILES

nados podrían seguir reaprovechando el código para causar daños en estos aparatos ya que no suelen llevar sistemas de protección contra virus. Y dicho y hecho, recientemente se descubría un nuevo exploit, distribuido por la red, que aprovecha una vulnerabilidad en la versión del navegador Safari para el iPhone y también el iPod Touch. Los dispositivos en peligro son aquellos que poseen desde el firmware 1.0.2 hasta el 1.1.3, incluidas las flamantes versiones de 16GB. El ataque sigue una pauta similar al SMiShing. Basta con visitar el sitio que incluya dicho código malicioso, lo que provocará un colapso del iPhone o el iPod Touch al sobrecargar en este caso su memoria. Desde Apple por el momento se recomienda desactivar el JavaScript del navegador. Desde un punto de vista más anecdótico, el Iphone también ha estado estrechamente relacionado con un ataque vírico del que informó PandaLabs a mediados de 2007. En aquel entonces, 7500 ordenadores fueron infectados con el virus Aifone.A, un troyano cuyo nombre es claramente alusivo al teléfono de Apple. La infección se agravaba cuando el usuario visitaba el sitio oficial del iPhone, pues allí era redireccionado hacia otro malicioso. Al intentar comprar el mencionado teléfono desde allí, la victima revela sus datos bancarios o de tarjeta de crédito. El virus troyano en sí infecta a PCs con Windows 2003/XP/2000/NT/ME/98/95 pero no con Vista y su forma de transmisión es a través de archivos adjuntos en correos electrónicos, aunque parece ser que no se esparce automáticamente si no que se propaga a

El iPhone está en el punto de mira de cara a ataques víricos.

SOLO PROGRAMADORES nº 162

52

través de CDs, diskettes, adjuntos de mensajes de correo electrónico, descargar ejecutables, redes P2P, canales IRC o FTP. Se instala en el sistema para que cuando el usuario accede al sitio “iphone.com” sea redirigido a otra página maliciosa y empiece el fraude.

Google Android: ¿objetivo futuro? Hace algunos meses se comenzó a especular con que Google podría lanzar al mercado un nuevo teléfono móvil. Tras varios vaivenes, rumores y vaticinios, finalmente el esperado proyecto Google Phone fue presentado en sociedad a principios de noviembre del 2007 con el nombre de Android. Se trataba ya no de un dispositivo móvil como tal, si no de algo seguramente mucho mejor: una plataforma libre basada en el kernel Linux y con una Máquina Virtual Java para conformar el primer sistema operativo Open Source para móviles. Junto con otras 30 firmas de tecnología móviles, se creaba también la Open Handset Alliance, para impulsar Android. Aunque los primeros dispositivos con Android se comercializarán seguramente para la segunda mitad de 2008, al ser una plataforma completamente abierta (con un SDK disponible), los riesgos de que programadores desarrollen virus para este sistema son una realidad más que tangible. De ahí que los investigadores en seguridad ya hayan advertido del riesgo que puede suponer su naturaleza inherente de cara a un ataque de software malicioso y se está sopesando el potencial de un aumento de virus móviles. Todo dependerá de si Android buscará sistemas totalmente abiertos o si adoptará un sistema para firmar aplicaciones aprobadas como hace Symbian. El peligro es evidente en el caso de que programas no firmados o desarrollados por cualquiera tengan acceso a las características del teléfono. Y como prevenir es curar, han comenzado a presentarse en las primeras soluciones para esta plataforma. El paquete de seguridad SMobile Systems con Security Shield incluirá tanto antivirus, como protecciones contra el Spam y un cortafuegos. Según los directivos de SMobile, su desarrollo está focalizado en brindar un entorno seguro a esta nueva plataforma móvil, dado que actualmente no es nada segura. Uno de los argumentos de la gente de SMobile es el hecho de que en el estado embrionario en el que actualmente se

Una protección efectiva empieza por nosotros mismos, no aceptando conexiones desconocidas.

encuentra el desarrollo de Android, un virus puede ejecutar las funciones de cualquier aplicación, incluyendo opciones como hacer llamadas, enviar mensajes, o simplemente realizar conexiones a Internet. De momento, la empresa se ha comprometido a desarrollar más productos de seguridad, dado que confían en que tendrá buena adopción en el mercado.

En busca del antídoto Como era de esperar, las compañías que desarrollan programas antivirus no han bajado la guardia en ningún momento y, además de advertir de los posibles peligros venideros, han ido presentando productos que tienen como objetivo atajar las amenazas que puedan sufrir los teléfonos móviles. Por ejemplo la multinacional norteamericana Symantec ya ha anunciado el lanzamiento de su primer producto de consumo para la seguridad del móvil, un antivirus para dispositivos móviles con capacidades multimedia. Así ha nacido el Norton Smartpone Security que cuenta con avanzadas tecnologías del Norton Antivirus, un cortafuegos y un antispam para evitar SMS no deseados. La empresa es consciente de que, así como los teléfonos móviles amplían la libertad de los usuarios a la hora de comunicarse, las redes o puntos de acceso WiFi no seguras también pueden exponer a estos a posibles riesgos. El argumento gana peso si a esto sumamos que, tras una encuesta realizada en Estados Unidos por Applied Research a usuarios de dispositivos móviles multimedia en EE.UU., un 34% de los encuestados afirmó que accedían desde su móvil a sus cuenwww.revistasprofesionales.com


DISPMOVILES-Virus en moviles:DISPMOVILES-Virus en moviles

16/6/08

12:26

Página 53

Los virus llegan a la telefonía móvil

tas bancarias y un 54% accedía a sitios web que requieren contraseña también a través del móvil. F-Secure es otra firma que se esfuerza en investigar en esta nueva área de riesgo. Esto ha permitido que expertos en seguridad de la compañía hayan descubierto el nuevo troyano Infojack que se ejecuta en dispositivos móviles que utilizan Windows Mobile como sistema operativo. Junto a F-Secure, McAfee ha sido el principal vendedores de programas de seguridad para teléfonos móviles, aunque las otras compañías no se han quedado quietas y han lanzado otros productos en los últimos tiempos. Y es que pese a que el riesgo de que un teléfono móvil se infecte es relativamente pequeño, ya se han visto problemas en miles de terminales móviles. Casi tres de cada cuatro usuarios han tenido algún problema de seguridad a la hora de utilizar los servicios móviles, como ha quedado demostrado tras una encuesta a 2.000 usuarios de teléfonos móviles llevad a cabo por McAfee y presentada durante el último Mobile World Congress de Barcelona. Para ayudar a combatir este tipo de ingeniería social, Kaspersky ha desarrollado un nuevo producto llamado Kaspersky Mobile Security, que brindará protección contra el robo de datos: si el dispositivo fuera extraviado, la suite permite bloquear los mensajes de texto para limitar el uso (hasta que se ingrese la clave elegida por el dueño), realizar limpiezas del chip interno eliminando la información personal, amén de ofrecer antivirus en tiempo real, antispam, cortafuegos y actualizaciones automáticas en línea.

Conclusiones Según un estudio publicado en Inglaterra, los virus y gusanos informáticos pueden expandirse entre los dispositivos móviles Bluetooth de la misma forma que se propaga la gripe entre los humanos. Para demostrarlo se creó un modelo matemático capaz de discernir cómo se comporta un gusano informático en una red inalámbrica y cómo se transmite por los dispositivos móviles. La conclusión no puede ser más preocupante: un gusano inalámbrico podría dispersarse mejor en una red muy congestionada, y también podría saltar geográficamente a través de los aviones. Esta curiosa analogía sin embargo no debe ser óbice para que consideremos la nueva www.revistasprofesionales.com

El sistema operativo Android de Google deberá asegurarse muy bien para evitar amenazas.

amenaza del spam y los virus móviles desde un enfoque distinto, por lo menos a la hora de prevenirlos y controlarlos. De ahí que debamos asignar a los operadores móviles de todo el mundo un papel destacado. Aunque de momento los incidentes en seguridad móvil no alcanzan la escala que protagonizan los PC, se ha evidenciado un aumento en cuanto a su volumen y sofisticación, lo que unido a una creciente integración con Internet, los convierten en un riesgo latente tanto para los fabricantes de teléfonos móviles como para los operadores. Porque ya puede afirmarse que el diseño conceptual de un virus para teléfono móvil ha evolucionado en desarrollos con un fin específico. Los puntos de entrada de una infección son muy variados debido a los múltiples usos que damos a estos pequeños aparatos. Podemos contagiarnos, por ejemplo, a través de los puertos de comunicación inalámbrica ya que aquellos dispositivos móviles que se encuentren dentro del alcance de otros equipos ya afectados podrían atraer códigos maliciosos a través de las conexiones anónimas. De esta manera cualquier usuario podr��a recibir un supuesto ringtone, wallpaper o cualquier otro elemento que podría ser a su vez un malware. Otro riesgo proviene de los mensajes multimedia, aunque para este caso el usuario debería encontrarse dentro de la cobertura de los servicios móviles de su proveedor o recibir el virus a través de alguno de sus contactos que ya esté afectado. Y no debemos olvidar el crítico momento en el que sincronizamos el teléfono móvil con nuestro ordenador por medio de una conexión USB.

DISPOSITIVOS MÓVILES

Sin embargo, debido a la propia naturaleza de los virus para móviles, en la mayoría de los casos bastará con que el usuario no peque de un exceso de confianza y configure las preferencias para no aceptar cualquier conexión, salvo las de aquellas personas previamente autorizadas. Asimismo deberemos cuidarnos de las falsas suscripciones en línea y ofertas de trabajo falsas por SMS. Un descuido por nuestra parte podrá comprometer nuestra seguridad. Y es que una protección efectiva empieza por nosotros mismos. Cuanto más desarrollado esté el mercado de la telefonía móvil, más frecuente será este tipo de ataques por parte de hackers, debido a que el teléfono se ha convertido ya en una especie de pequeño ordenador móvil con potentes características e infinidad de utilidades cuyo uso no hace más que extenderse en lo que parece ser una tendencia global. Y, aunque no lo creas, el año pasado 110.000 teléfonos con el sistema Symbian de Nokia resultaron atacados en España por medio de mensajes MMS. Una cifra que debería alertar al que aún considere que su teléfono móvil está a salvo de peligros externos.

Enlaces de interés  http://www.siliconnews.es/es/news/2008/02/ 17/los_expertos_alertan_de_un_incremento_de _virus_para_m_viles  http://www.lavanguardia.es/lv24h/20080305/ 53442289893.html  http://www.vnunet.es/Actualidad/Noticias/Se guridad/Virus/20080215006  http://www.datafull.com/site/2/2/noticias/14 11/3-de-cada-4-consumidores-ma-viles-preocupados-por-la-seguridad  http://internetblog.emol.com/archives/2008/ 02/infecciones_por.asp  http://www.noticiasdot.com/wp2/2008/02/19 /expertos-en-seguridad-opinan-que-androidtraera-mas-virus-a-los-terminales-moviles/  Blog McAfee: http://www.avertlabs.com/research/ blog/?s=Spain  Pasarelas SMS: http://hiptools.net/sms/  http://www.pcwla.com/pcwla2.nsf/articulos/ C25B7873CEBBACBB8525725C0060BA36  http://iblnews.com/story.php?id=18307  http://www.xatakamovil.com/2006/09/04tres-nuevas-amenazas-en-el-movil-smishingagotamiento-de-bateria-e-interceptacion-sms  http://www.laflecha.net/canales/seguridad/noti cias/smishing-el-nuevo-peligro-de-los-moviles/  http://en.wikipedia.org/wiki/SMiShing  Prueba de concepto virus iPhone: http:// www.iphoneros.com/?p=700  http://www.noticiasdot.com/wp2/2008/03/10 /infojack-un-troyano-que-ataca-a-los-moviles/

53

SOLO PROGRAMADORES nº 162


NET-Arrastrar-soltar:NET-Arrastrar-soltar

16/6/08

10:12

Página 54

COMUNIDAD .NET

Arrastrar y Soltar PEP LLUIS BAÑO (Presidente de SpainNet, miembro del comité de INETA-Latam y Microsoft MVP– Visual Developer)

Una de las prestaciones más espectaculares para los que vivimos la transición entre los entornos de caracteres a gráficos fue la posibilidad de “Arrastrar” y “Soltar”, como es de suponer hoy en día es algo habitual y normal aunque el nivel de utilización en nuestras aplicaciones acostumbra a ser bajo.

Intentando animar su aplicación en nuestros desarrollos, en la sección de este mes veremos lo fácil que resulta añadir esas prestaciones a nuestras aplicaciones que por falta de prioridad a menudo pasan a segundo plano y que donde hacen falta realmente le dan ese acabado digno de cualquier aplicación profesional que se precie. En nuestro ejemplo podremos ver tres ejemplos muy básicos para construir los contenidos en vistas de árbol “treeviews” con suma facilitad arrastrándolas de una a otra, rellenar un caja de imagen “PictureBox” soltando una foto o finalmente el clásico de arrastrar un Texto+Imagen por ejemplo de un .doc para soltarlo en una caja de texto rico “RichTextBox”.

Figura 1.

SOLO PROGRAMADORES nº 162

54

www.revistasprofesionales.com


NET-Arrastrar-soltar:NET-Arrastrar-soltar

16/6/08

10:12

Página 55

COMUNIDAD .NET

Arrastrar y Soltar

Pongamos manos a la obra! Para hacerlo un poquito más interesante, vamos a definir e incorporar todos los elementos necesarios sin utilizar el diseñador de ‘forms’… el código lo puede todo! La primera tarea será definir los controles con sus respectivos contenedores (ver Listado 1).

LISTADO 1 '' '' Definicion de los controles del form '' Dim panel1 As New FlowLayoutPanel() 'Panel 1 Contenedor del Treeview Dim panel2 As New FlowLayoutPanel() 'Panel 2 Contenedores Foto/Texto Private Private Private Private

WithEvents WithEvents WithEvents WithEvents

VistaDeArbol1 As New TreeView VistaDeArbol2 As New TreeView VistaDeFoto As New PictureBox VistaDeTexto As New RichTextBox

'Primer TreeView 'Segundo Treview 'Imagen PictureBox 'Texto RichTextBox

LISTADO 2 '' '' Al cargar el formulario Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' ' Añadir y rellenar treeview con trenodes con efectos de prueba Dim NudoArbol1 As TreeNode NudoArbol1 = VistaDeArbol1.Nodes.Add("Arbol 1 - Principal") NudoArbol1.Nodes.Add("A1 - Opcion 1") NudoArbol1.Nodes.Add("A1 - Opcion 2") NudoArbol1.Nodes.Add("A1 - Opcion 3") NudoArbol1.Nodes.Add("A1 - Opcion 4") NudoArbol1.Expand() NudoArbol1 = VistaDeArbol1.Nodes.Add("Arbol 2 - Secundario") NudoArbol1.Nodes.Add("A1 - Bla..Bla") NudoArbol1.Expand() Dim NudoArbol2 As TreeNode NudoArbol2 = VistaDeArbol2.Nodes.Add("Arbol 2 - Principal") NudoArbol2.Nodes.Add("A2 - Opcion 2") NudoArbol2.Nodes.Add("A2 - Opcion 2") NudoArbol2.Nodes.Add("A2 - Opcion 3") NudoArbol2.Nodes.Add("A2 - Opcion 4") NudoArbol2.Expand() ' 'Seleccionar el estilo del borde Me.VistaDeFoto.BorderStyle = BorderStyle.Fixed3D ' panel1.Dock = DockStyle.Top 'dock arriba panel1.BorderStyle = BorderStyle.FixedSingle 'Estilo panel2.Dock = DockStyle.Bottom panel2.BorderStyle = BorderStyle.FixedSingle

'dock abajo 'Estilo

'Añadir los controles a los panels panel1.Controls.AddRange(New Control() {VistaDeArbol1, VistaDeArbol2}) panel2.Controls.AddRange(New Control() {VistaDeFoto, VistaDeTexto}) 'Anadir los panels al form Me.Controls.AddRange(New Control() {panel1, panel2}) 'Añadir Datagrid a la coleccion de controles Me.Text = "Arrastrando y Soltando!" 'Permitir que los controles acepten el drop Me.VistaDeArbol1.AllowDrop = True Me.VistaDeArbol2.AllowDrop = True Me.VistaDeFoto.AllowDrop = True Me.VistaDeFoto.SizeMode = PictureBoxSizeMode.StretchImage Me.VistaDeTexto.AllowDrop = True 'Posicionar los controles segun el tamaño del form DragAndDrop_Posicionar_Controles() End Sub

LISTADO 3 ' ' Invocar la funcion de posicionamiento, por cambio de tamaño ' Private Sub DragAndDrop_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize DragAndDrop_Posicionar_Controles() End Sub ' ' Distribuir la disposicion de los controles en funcion ' del tamaño disponible en el form ' Private Sub DragAndDrop_Posicionar_Controles() Me.panel1.Height = Me.Height / 2 - 20 Me.panel2.Height = Me.Height / 2 - 20 Me.VistaDeArbol1.Height = panel2.Height - 10 Me.VistaDeArbol1.Width = (panel1.Width / 2) - 8 Me.VistaDeArbol2.Height = panel2.Height - 10 Me.VistaDeArbol2.Width = (panel2.Width / 2) - 8 Me.VistaDeFoto.Width = (panel2.Width / 2) - 8 Me.VistaDeFoto.Height = panel2.Height - 10 Me.VistaDeTexto.Width = (panel2.Width / 2) - 8 Me.VistaDeTexto.Height = panel2.Height - 10 End Sub

www.revistasprofesionales.com

A continuación utilizaremos el evento “Load” del “Form” para preparar el aspecto del frontal visible a nuestro usuario. Aparte de rellenar los “treeviews” con ‘items’ genéricos para realizar nuestras pruebas y posicionar correctamente los controles en el “form”, cabe destacar la importancia de otorgar permisos de “arrastar y soltar” a los controles con esa propiedad, lo identificaremos en “allowdrop” (ver Listado 2). Antes de pasar a la acción, deberemos tener en cuenta dos acciones imprescindibles para dar un aspecto decente a nuestra aplicación. Se trata de posicionar correctamente los contenedores para que se adapten a la perfección en el formula55

SOLO PROGRAMADORES nº 162


NET-Arrastrar-soltar:NET-Arrastrar-soltar

16/6/08

10:12

Página 56

COMUNIDAD .NET

LISTADO 4 #Region "VistaDeArbol - ItemDrag, DragEnter, DragDrop" ' ' efecto move en ItemDrag ' Public Sub VdA_ItemDrag(ByVal sender As Object, ByVal e As ItemDragEventArgs) _ Handles VistaDeArbol1.ItemDrag, VistaDeArbol2.ItemDrag DoDragDrop(e.Item, DragDropEffects.Move) End Sub ' ' efecto move en DragEnter ' Public Sub VdA_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs) _ Handles VistaDeArbol1.DragEnter, VistaDeArbol2.DragEnter e.Effect = DragDropEffects.Move End Sub ' ' Insertar el nodo arrastrado ' Public Sub VdA_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) _ Handles VistaDeArbol1.DragDrop, VistaDeArbol2.DragDrop ' Comprobar que arrastramos un treenode If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", False) Then 'Apuntar al cliente Dim Puntero As Point = CType(sender, TreeView).PointToClient(New Point(e.X, e.Y)) 'Nudos de origen i destino Dim NudoOrigen As TreeNode = CType(e.Data.GetData("System.Windows.Forms.TreeNode"), TreeNode) Dim NudoDestino As TreeNode = CType(sender, TreeView).GetNodeAt(Puntero) 'Clonar el nudo origen en destino If Not NudoDestino.TreeView Is NudoOrigen.TreeView Then NudoDestino.Nodes.Add(NudoOrigen.Clone) NudoDestino.Expand() 'Eliminar el Origen NudoOrigen.Remove() End If End If End Sub #End Region

rio que los contiene. Ello lo conseguiremos trabajando el evento ‘Resize’ (ver Listado 3). Ni cortos, ni perezosos pasemos a la acción, veamos detenidamente el código que nos

permite arrastrar y soltar entre “treeviews” usando los eventos ‘ItemDrag’, ’DragEnter’ e ’ItemDrop’ (ver Listado 4). Pasado lo más difícil nos queda bordar lo fácil con la espectacularidad de visualizar

en nuestro contendor de imágenes la foto que arrastramos desde nuestro álbum (ver Listado 5). Como colofón solo nos resta ver nuestro arrastrar y soltar en formatos de “texto

LISTADO 5 #Region "VistaDeFoto - ItemDrag, DragEnter, DragDrop" ' 'Recibir el nombre de la imagen que rellenara el contenedor de imagen ' Public Sub VdF_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs)_ Handles VistaDeFoto.DragEnter 'Si el arrastramos ficheros en la caja de imagen... If e.Data.GetDataPresent(DataFormats.FileDrop) Then e.Effect = DragDropEffects.All 'tomar todos los efectos End If End Sub ' 'Cargar la imagen arrastrada sobre el contendor ' Public Sub VdF_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) _ Handles VistaDeFoto.DragDrop Try If e.Data.GetDataPresent(DataFormats.FileDrop) Then 'Si soltamos un archivo Dim Nombres() As String Nombres = e.Data.GetData(DataFormats.FileDrop) 'Obtener su nombre 'Cargar la imagen arrastrada al PicBox Me.VistaDeFoto.Image = System.Drawing.Image.FromFile(Nombres(0)) End If Catch ex As Exception '.... End Try End Sub #End Region

SOLO PROGRAMADORES nº 162

56

www.revistasprofesionales.com


NET-Arrastrar-soltar:NET-Arrastrar-soltar

16/6/08

10:12

Página 57

Arrastrar y Soltar

COMUNIDAD .NET

LISTADO 6 #Region "VistaDeTexto - DragEnter, DragDrop" ' 'Recibir el texto o en su defecto un archivo de texto, ' con el contenido para el rtbTexto Private Sub VdTDragEnter(ByVal sender As Object, ByVal e As system.Windows.Forms.DragEventArgs) Handles VistaDeTexto.DragEnter ' Diferenciar si arrastramos contenido o un archivo rtf If e.Data.GetDataPresent(DataFormats.Rtf) Then e.Effect = DragDropEffects.Copy 'Copiar si es contenido Else If e.Data.GetDataPresent(DataFormats.FileDrop) Then e.Effect = DragDropEffects.All 'todos los efectos si se arrastra un archivo End If End If End Sub ' 'Rellenar el contendor de rtbTexto, con el contenido arrastrado en el control Private Sub VdTDragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles VistaDeTexto.DragDrop ' 'El efecto de soltar se realiza tanto en el rtfBox como en el btnBox Try If e.Data.GetDataPresent(DataFormats.FileDrop) Then 'Si arrastramos un archivo Dim Nombres() As String Nombres = e.Data.GetData(DataFormats.FileDrop) 'obtenemos el nombre del archivo If Nombres(0).EndsWith(".rtf") Then 'Procesarlo si extension es rtf Me.VistaDeTexto.LoadFile(Nombres(0)) 'Llenamos rtfBox con el archivo End If Else 'Leer el RTF arrastrado y llenar el contenido rtbTexto Me.VistaDeTexto.Rtf = e.Data.GetData(DataFormats.Rtf) End If Catch ex As Exception '... End Try End Sub #End Region

rico”, la peculiaridad de este es que me permite arrastrar un texto rico seleccionado

directamente de un Word o WordPad, así como cualquier archivo rtf (ver Listado 6).

Solo nos queda ver el resultado (ver Figura 1).


opinion:OPINION

16/6/08

10:26

Página 58

OPINIÓN

El iPhone aterriza en España Los Geeks (y los que no lo son) estamos de enhorabuena porque, si las previsiones se cumplen, en breve tendremos por fin a nuestra disposición el iPhone entre nosotros. Un hecho que probablemente marque un antes y un después. NICOLÁS VELÁSQUEZ ESPINEL

Pero aunque parezca mentira, la buena nueva no se queda ahí. Resulta que, para más Inri, el evento coincidirá con la presentación de la última versión del modelo, que incorpora toda una serie de interesantes novedades. ¡Y aún hay más! Si son ciertos algunos rumores que circulan por ahí, es posible que salga a coste cero. Sí, exactamente como lo oyes. Totalmente gratis. Aunque a esto ya llegaremos… Los acontecimientos se han sucedido a un ritmo vertiginoso durante las últimas semanas. El pistoletazo de salida se dio realmente en el escenario de un centro de convenciones de San Francisco. Steve Jobs, el presidente ejecutivo de Apple, presentaba el esperado iPhone 3G, la evolución natural del iPhone, probablemente uno de los éxitos comerciales más importantes de los últimos años. La segunda generación del revolucionario teléfono móvil es un terminal más fino, con plástico negro en la base y, lo más interesante, viene equipado con una conectividad de tercera generación 3G que supera con creces (casi tres veces más rápida, según Apple) a la conexión EDGE con que se distribuía hasta ahora. Para rematar, también incorpora de serie un sistema de posicionamiento vía saté-

El iPhone 3G es algo más grande pero más delgado.

SOLO PROGRAMADORES nº 162

58

lite GPS, que le permitirá ser empleado como navegador. El 10 de junio Telefónica y Apple anunciaban oficialmente que traerían de la mano iPhone a España. Del mismo modo se comunicaba que la fecha clave del desembarco español sería el 11 de julio. Hasta entonces sólo podremos fiarnos de la opinión que varias webs especializadas han emitido sobre el nuevo terminal que han podido tener en sus manos durante algunas horas. Así, a través de las conclusiones expuestas por las páginas Engadget, Gizmodo y MacWorld, podemos vislumbrar lo que nos espera a la vuelta de la esquina. Por un lado, respecto a la novedad del GPS, todas son buenas noticias ya que al parecer funciona a la perfección, tanto en la ubicación de calles, como en tareas de geoposicionamiento. Por otro lado, en lo que respecta a la velocidad de datos, la incorporación de 3G supone claramente una mejora, consiguiendo en las pruebas realizadas velocidades de más del doble de las obtenidas con el antiguo EDGE. En lo que respecta a su aspecto físico, es un par de milímetros más grande que el modelo anterior, aunque también algo más delgado. Según los que han podido tener en sus manos el nuevo iPhone, éste no se ve más aparatoso y los bordes traseros redondeados ayudan a que sea más maniobrable. Allí precisamente se ha renovado el material, que ahora es de plástico, aunque no por ello sugiere peor calidad que el anterior modelo sino todo lo contrario. De los contenidos se ha hecho especial hincapié en los juegos que parece que tienen una alta calidad gráfica, y con un toque de diversión que para más de uno serán adictivos. Asimismo, la salida de audio para los audífonos es más universal facilitando escuchar música como queramos, y se espera que la calidad del sonido y de las imágenes mejoren considerablemente. No obstante también han surgido algunas críticas como por ejemplo que el dispositivo Bluetooth siga estando limitado sólo para ser empleado con el manos libres de Apple, imposibilitando, por ejemplo, que se use como

Solo unos pocos afortunados han tenido entre sus manos el nuevo iPhone 3G.

módem 3G. Del mismo modo, pese a situarse en la vanguardia tecnológica, su Wi-Fi sigue usando el protocolo 802.11b/g, pese a que podría haberse lanzado con el 802.11n que ya han implementado varios dispositivos. Finalmente, la cámara mantiene los mismos dos megapíxeles, que se antojan algo limitados y el material de la nueva cobertura no ofrece la misma sujeción al dejarse encima de una superficie. El precio del dispositivo se ha rebajado con respecto a las tarifas de lanzamiento en EE UU. El iPhone 3G de 8 gigas se venderá por un máximo de 199 dólares, unos 127 euros (ahora cuesta 399 y salió a la venta en un principio por 599). Habrá también una versión de 16 gigas, en blanco y en negro, que costará 299 dólares (190 euros). Sin embargo también podría salir gratis en España, aunque habrá que esperar al anuncio oficial y leer la letra pequeña de la supuesta oferta, en el caso de que se confirme. Tras toda la expectación creada y el considerable retraso que hemos sufrido hasta ver en nuestro mercado un dispositivo que tantos elogios ha cosechado, es legítimo preguntarse si tanto bombo es justificado o se trata de una campaña de marketing magistralmente orquestada. Por un lado parece indudable que las funcionalidades que incorpora son impresionantes pero, ¿hasta donde podemos asegurar que viene a cubrir una necesidad “real”? ¿Acaso no está justificado plantearse si se trata de una nueva vuelta de tuerca en la que se está creando la ilusión de una necesidad que no demandamos? Probablemente haya un 50% de cada una, aunque lo único que yo sé es que quiero uno. www.revistasprofesionales.com


sorteo:sorteo

17/6/08

12:24

Página 1

SORTEAMOS EL LIBRO “Inglés para usuarios de informática” Como premio a la fidelidad de nuestros lectores, sorteamos un ejemplar del libro “Inglés para usuarios de informática” de Francisco García Jiménez Inglés para usuarios de Informática quiere ser una herramienta de ayuda para todos aquellas personas que utilicen con frecuencia el ordenador y que encuentran problemas con el inglés, que es indudablemente el idioma de Internet y la Informática. Advirtamos que no se trata de un libro de gramática inglesa, aunque hay páginas dedicadas a explicar los principales elementos gramaticales pero siempre buscando su vertiente práctica. Se pone especial énfasis en la traducción de textos escritos, que es la actividad que más hace un usuario de informática y en la que debe de estar más entrenado. Se ofrecen ideas y estrategias con ejemplo reales de textos extraídos de Internet, a fin de que el lector se habitúe en esta importante tarea. En definitiva se trata de un manual que el usuario de informática debe de tener cerca de su equipo informático. Para ello, solo tienes que enviar un correo a la dirección de la revista, solop@revistasprofesionales.com, contestando a las siguientes preguntas que, en cualquier caso, ayudarán a crear una revista cada vez más acorde con los gustos de nuestros lectores. De entre todos los correos recibidos, sortearemos un ejemplar del libro, que enviaremos al lector que haya resultado seleccionado a la dirección que nos indique. -

¿Cuánto tiempo hace que lees Solo Programadores? ¿Compras o estás suscrito a Solo Programadores? En el segundo caso ¿digital o en papel? Puntúa Solo Programadores de 1 a 10 ¿Qué otras publicaciones parecidas compras? Puntúalas de 1 a 10 ¿Qué añadirías en Solo Programadores? ¿Qué eliminarías en Solo Programadores? Valora de 1 a 10 la presentación de Solo Programadores Valora de 1 a 10 el contenido de Solo Programadores Valora de 1 a 10 el CD/DVD entregado con Solo Programadores Comentarios: (añade aquí los comentarios que creas oportuno)


60-63 Dudas:Dudas

16/6/08

09:45

Página 60

DUDAS

Preguntas y respuestas ADOLFO ALADRO GARCÍA

En un programa en C++ tengo que guardar una serie de cadenas de caracteres. Puedo utilizar un array simple pero el problema es que el número de cadenas a guardar es variable y se conoce en la ejecución, con lo que tengo que estar constantemente reservando memoria, copiando y liberando. ¿Existe alguna estructura en el API estándar, tipo conjunto, HashMap o algo así para hacer este tipo de cosas o tengo que construirme la mía propia? La solución consiste en utilizar la clase vector de la librería estándar. Por ejemplo: #include <iostream> #include <vector> #include <string> using namespace std; int main(int argc, char *argv[]) { vector<int> intVec; intVec.push_back(1); intVec.push_back(2);

Los vectores que implementa esta clase de la librería estándar de C++ pueden guardan no sólo valores de tipo simple. En el siguiente ejemplo se utiliza un vector para almacenar cadenas de caracteres: vector<string> strVec; strVec.push_back(“hola”); strVec.push_back(“caracola”); for (vector<string>::iterator p = strVec.begin(); p!= strVec.end(); ++p) { cout << *p << ‘\n’; }

Obsérvese que en este caso se recorre el vector de una forma diferente, utilizando punteros. El método begin devuelve el puntero al primer elemento del vector. El método end devuelve el puntero al último elemento. Cuando se avanza el puntero, simplemente con el operador ++, se avanza por los elementos del vector. En un vector pueden almacenarse incluso punteros, tal y como muestra el siguiente ejemplo simple:

intVec.push_back(3);

int i1 = 22, i2 = 23, i3 = 24;

for (vector<int>::size_type i = 0;

vector<int*> intVec;

i < intVec.size( ); ++i) {

intVec.push_back(&i1);

cout << “intVec[“ << i << “] = “ << intVec[i] << ‘\n’;

intVec.push_back(&i2); intVec.push_back(&i3);

Aunque el acceso a los elementos de un vector puede hacerse con el operador [] resulta más seguro hacerlo con el método at, el cual recibe como parámetro el índice correspondiente al elemento al que quiere accederse. La razón es que este método genera una excepción del tipo out_of_range si el índice pasado como parámetro está fuera de rango, es decir, menor que cero o mayor o igual al tamaño del vector. Por último, es importante comprender que la clase vector no es más que una forma de encapsular las operaciones que tradicionalmente se harían con un array. Es decir, internamente la clase vector utiliza un array y gestiona de forma transparente las tareas relacionadas con la memoria. Pero lo anterior no significa que dichas tareas no se ejecuten. Si la clase vector no se usa de la mejor forma posible, al final la aplicación no rinde de forma óptima. Por todo ello es conveniente definir los vectores con un tamaño de entrada, por ejemplo: vector<string> strVec(128);

También es posible utilizar el método reserve, cuya funcionalidad es la misma: indicar a la clase que se va a necesitar memoria para almacenar hasta un número determinado de elementos: strVec.reserve(128);

} for (vector<int>::size_type i = 0; i system(“PAUSE”);

< intVec.size(); ++i) {

return EXIT_SUCCESS;

cout << “intVec[“ << i << “] = “ << *intVec[i] << ‘\n’;

}

En la primera línea del procedimiento principal main se define la variable intVec que es un vector que almacena valores de tipo int. Seguidamente se insertan elementos en el vector utilizando el método push_back. Los elementos se guardan en el vector en el orden en el que se insertan. Por último, se recorren todos los elementos del vector. Para conocer el tamaño del mismo se emplea el método size. El acceso a un elemento se puede hacer con el operador [], del mismo modo que ocurre con los array tradicionales.

SOLO PROGRAMADORES nº 162

60

}

En el código anterior se crea el vector utilizando el tipo int*, lo que significa que se guardarán punteros a enteros. Cuando se ejecuta el método push_back para insertar elementos se emplea el operador & para acceder a las direcciones de memoria de las variable i1, i2, i3. Al recorrer el vector lo que se obtiene con el operador [] son los punteros almacenados, por lo que para acceder a los valores reales es preciso utiliza las expresión *intVect[i] que devuelve el número al que apunta el puntero.

¿Cómo se pueden crear objetos Javascript en formato JSON? ¿Es un formato que aceptan todos los navegadores? ¿Qué diferencia hay con los objetos creados de forma digamos “tradicional”? El formato JSON aporta simplicidad, flexibilidad y además compatibilidad, ya que la mayor parte de los motores de Javascript lo soportan sin problema. Además supone una alternativa al XML en las aplicaciones AJAX, pudiendo llegar a constituir una solución notablemente más eficiente que la basada en XML ya que el procesamiento de XML sigue siendo una tarea relativamente www.revistasprofesionales.com


60-63 Dudas:Dudas

16/6/08

09:45

Página 61

DUDAS

Preguntas y Respuestas

costosa. El siguiente ejemplo muestra un objeto JSON muy simple: var oBook = { title: “Título del libro”, author: “Autor del libro” }; alert(oBook.title + “\n” + oBook.author);

Los atributos title y author son miembros del objeto. El acceso a los miembros se produce de la misma forma que en cualquier otro objeto tradicional, utilizando el punto. Las cadenas de texto representan otra de las maneras en las que más frecuentemente se encuentran los objetos en formato JSON, especialmente cuando se desarrollan aplicaciones AJAX. En el siguiente ejemplo la variable oBookAsStr es una cadena de texto que contiene el mismo objeto JSON definido en el ejemplo anterior. Con el procedimiento estándar eval se evalúa la cadena de texto y se obtiene el objeto como tal. Obsérvese que para evaluarlo es necesario “rodear” la cadena de texto con paréntesis:

Ejemplo de utilización de la clase vector de la librería estándar de C++.

var oBookAsStr = ‘{title: “Título del libro”, author: “Autor del libro”}’; var oBook = eval(‘(‘ + oBookAsStr + ‘)’); alert(oBook.title + “\n” + oBook.author);

Con JSON no solamente se pueden definer miembros sino que también se pueden definir métodos, tal y como muestra este otro ejemplo. El método toString devuelve una cadena de texto que representa al objeto. Dentro del código del método, cuando se acceden a los miembros del objeto, es necesario utilizar la palabra reservada this.

Página principal del formato JSON (www.json.org). var oBookAsStr = ‘{title: “Título del libro”, author: “Autor del libro”, toString: function() {return this.title + “\\n” + this.author;}}’; var oBook = eval(‘(‘ + oBookAsStr + ‘)’);

var oBook = { title: “Título del libro”, authors: [“Autor 1”, “Autor 2”, “Autor 3”], toString: function() {

alert(oBook.toString());

var s = this.title + “\n”;

var oBook = { title: “Título del libro”, author: “Autor del libro”, toString: function() { return this.title + “\n” + this.author; } }; alert(oBook.toString());

Los métodos también pueden definirse cuando el objeto aparece en forma de cadena de texto: www.revistasprofesionales.com

Lo miembros de un objeto definido en formato JSON no tienen porqué ser únicamente valores de tipo simple (números, cadenas de caracteres, etc.). También pueden ser otros objetos complejos, como en el ejemplo que se muestra a continuación. El miembro authors es un array de cadenas de texto, tantas como autores tiene el libro. El método toString ahora recorre este array cuando tiene que construir la cadena de texto que devuelve, siempre utilizando la palabra reservada this para fijar correctamente el contexto en el acceso:

for (var i=0; i<this.authors.length; i++) { s += this.authors[i] + “ “; } return s; } }; alert(oBook.toString());

Finalmente, los miembros pueden ser otros objetos JSON, tal y como ilustra este ejemplo, en el que el miembro pubDate, la fecha 61

SOLO PROGRAMADORES nº 162


60-63 Dudas:Dudas

16/6/08

09:45

Página 62

DUDAS

de publicación del libro, es un objeto, también definido en formato JSON, que cuenta con tres atributos: date, month y year. var oBook = {

tipo char. SALT es un array de bytes que podría ser por ejemplo: byte[] SALT = { (byte)0xA9, (byte)0x9B, (byte)0xC8,

title: “Título del libro”,

(byte)0x32,

author: “Autor del libro”,

(byte)0x56, (byte)0x35, (byte)0xE3,

pubDate: {date: 21, month: 2, year:

(byte)0x03 };

2008}, toString: function() { return this.title + “\n” + this.author + “\n” + this.pubDate.year + “/” + this.pubDate.month + “/” + this.pubDate.date; } }; alert(oBook.toString());

El método toString, cuando se accede a la fecha de publicación, se utiliza la palabra reservada this en primer lugar, después pubDate, que es el nombre del miembro del objeto, y después year, por ejemplo, que el nombre del miembro del otro objeto JSON.

ITERATION_COUNT es un valor numérico que en principio, y sin entrar en demasiados detalles, puede ser cualquiera. Con estos datos y el constructor de la clase PBEKeySpec se crea un objeto KeySpec. El método getInstance de la clase SecretFactory recibe el nombre del algoritmo que se va a utilizar y devuelve una factoría objetos SecretKey. Finalmente el método generateSecret devuelve el objeto buscado. El parámetro que recibe, PBEWithMD5AndDES, se corresponde con el nombre del algoritmo que se utiliza para la codificación de los datos. Una vez que se ha obtenido el objeto SecretKey resulta muy fácil encriptar y desencriptar cadenas de texto. Por ejemplo, para la primera tarea se puede hacer: Cipher cipher = Cipher.getInstance

En Java, ¿cómo se pueden encriptar y desencriptar datos usando una contraseña? En el paquete javax.crypto existen muchas clases pero no veo claramente un método en alguna clase para hacerlo. El paquete javax.crypto contiene muchas clases. Está pensando para realizar tareas de criptografía en general y por ello quizás las tareas más sencillas están un poco más escondidas. Cuando se quiere codificar información utilizando una contraseña lo primero que hay que hacer es obtener un objeto de tipo SecretKey a partir de la contraseña. Por ejemplo: KeySpec keySpec = new PBEKeySpec(sPasswordPhrase.toCharArray(), SALT, ITERATION_COUNT); SecretKey secretKey = javax.crypto.SecretKeyFactory.getInstance (“PBEWithMD5AndDES”).generateSecret (keySpec);

En el ejemplo anterior la variable sPasswordPhrase contiene la cadena de texto correspondiente a la contraseña. Con el método toCharArray se convierte la cadena de texto en un array de datos de

SOLO PROGRAMADORES nº 162

62

(secretKey.getAlgorithm());

en una cadena de texto normal usando Base64. La decodificación sigue un esquema muy parecido, como puede verse a continuación: Cipher cipher = Cipher.getInstance (secretKey.getAlgorithm()); AlgorithmParameterSpec algorithmParameterSpec = new PBEParameterSpec(SALT, ITERATION_COUNT); cipher.init(Cipher.DECRYPT_MODE, secretKey, algorithmParameterSpec); byte[] dataEncrypted = data; byte[] dataClean = cipher.doFinal(dataEncrypted); return new String(dataClean, “UTF-8”);

En la variable data se almacena el array de bytes correspondiente a la cadena codificada. El valor devuelto por doFinal es también un array de bytes. La cadena original se obtiene con el constructor de la clase String, utilizando el array de bytes y el esquema de codificación de caracteres adecuado. La utilización del método init es similar al caso de la encriptación, con la diferencia de que ahora el primer parámetro es Cipher.DECRYPT_MODE.

AlgorithmParameterSpec algorithmParameterSpec = new PBEParameterSpec(SALT, ITERATION_COUNT); cipher.init(Cipher.ENCRYPT_MODE, secretKey, algorithmParameterSpec); byte[] dataClean = s.getBytes(“UTF-8”); byte[] dataEncrypted = cipher.doFinal(dataClean);

El método getInstance de Cipher requiere que se le pase como parámetro el algoritmo empleado para la encriptación. Teniendo la contraseña en forma de objeto SecretKey, el método getAlgorithm devuelve el algoritmo. En este ejemplo la variable s contiene la cadena de texto a codificar usando la clase secreta almacenada en secretKey y que se ha obtenido tal y como se ha explicado anteriormente. Obsérvese que el mecanismo utiliza array de bytes tanto en la entrada como en la salida. Así con el método getBytes se obtiene a partir de la cadena de texto a codificar su representación en forma de array de bytes. El parámetro que recibe es la codificación de caracteres, en este caso UTF-8. El método doFinal devuelve igualmente un array de bytes. En las aplicaciones reales normalmente estas cadenas de bytes se suelen convertir

Con la etiqueta <canvas> se pueden pintar gráficos en Mozilla. Pero aparte de la propia etiqueta, que se pone en la página como cualquier otra, ¿cómo se empieza realmente a pintar? Comparándolo con SVG echo en falta el resto de etiquetas para pintar. Por lo general la etiqueta <canvas> representa únicamente un área de dibujo. Utilizando Javascript se suele pintar, inmediatamente después de que se cargue la página –el evento onload-. La etiqueta <canvas> se define en la página tal y como se muestra a continuación: <canvas id=”graphics” width=”640” height=”400”></canvas>

El campo id guarda el identificador de ese elemento dentro del DOM correspondiente a la página HTML. Los campos width y height almacenan respectivamente la anchura y la altura del área de dibujo. En la página se puede añadir un estilo para mostrar claramente dónde se encuentra esta área de dibujo: www.revistasprofesionales.com


60-63 Dudas:Dudas

16/6/08

09:45

Página 63

DUDAS

Preguntas y Respuestas <style type=”text/css”> #graphics {border: 1px solid black;} </style>

En realidad las tareas de dibujo propiamente dichas comienzan cuando la página ha terminado de cargarse, momento éste marcado por el evento onload. El primer paso consiste en utilizar el método getElementById para obtener el elemento correspondiente a la etiqueta <canvas>. Seguidamente se comprueba la existencia del método getContext para dicho elemento. Si existe entonces se trata de un navegador que implementa toda la funcionalidad de la etiqueta <canvas>:

En java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html se especifica el soporte que Java proporciona a través de su paquete dedicado a la criptografía.

window.onload = function() { var oCanvas = document.getElementById(“graphics”); if (oCanvas.getContext) { ··· } };

El método getContext recibe como parámetro la cadena 2d y devuelve el contexto, o lo que es lo mismo, el objeto con el que realmente se pinta en el área de dibujo: var oContext = oCanvas.getContext(“2d”);

Ejemplo de utilización del elemento <canvas> en Mozilla Firefox.

La propiedad fillStyle y el método fillRect son uno de los más sencillos. El primero recibe un color. El formato puede ser rgb(255,0,0) o incluso #ff0000. El método fillRect dibuja un rectángulo. Los dos primero parámetros son la posición del rectángulo dentro del área del dibujo (La esquina superior izquierda es el punto (0,0) y a medida que se avanza hacia la derecha y hacia abajo los valores de las coordenadas en el eje X e Y crecen). Los dos siguientes parámetros coinciden respectivamente con la anchura y la altura del rectángulo:

Otro de los recursos clásicos consiste en pintar formas utilizando path o caminos. Con el método beginPath se marca el comienzo del camino. En el ejemplo que sigue el camino es bastante simple ya que sólo se pinta una circunferencia usando arc. Finalmente con el método stroke se dibuja el conjunto de formas que constituyen el camino. Obsérvese que antes de empezar se ha establecido el valor de lineWidth de forma que la anchura de la línea es ahora de 20 píxeles:

El método createLinearGradient recibe cuatro parámetros. Son coordenadas (x,y) que indican desde qué punto hasta qué otro punto se extiende el gradiente. El método addColorStop del gradiente se emplea para marcar puntos en la transición. El primer parámetro es un valor relativo que establece en qué punto de la transición va ese cambio. El segundo parámetro es un color. var oLinearGradient =

oContext.fillStyle = “rgb(255,0,0)”;

oContext.lineWidth = 20;

oContext.createLinearGradient(320, 200, 640, 400);

oContext.fillRect (0, 0, 320, 200);

oContext.beginPath();

oLinearGradient.addColorStop(0.0,

Los colores pueden admitir transparencia. Para ello hay que utilizar cadenas de texto como rgba(0, 0, 255, 0.5) de forma que el último valor indica el grado de transparencia del color, yendo desde 0 hasta 1: oContext.fillStyle = “rgba(0, 0, 255, 0.5)”; oContext.fillRect (100, 100, 320, 200);

www.revistasprofesionales.com

oContext.arc(320, 200, 150, 150, Math.PI*2, true); oContext.stroke();

Existen muchas otras funcionalidades en las áreas de dibujo implementadas por Mozilla. Una de ellas es otro clásico en los API de dibujo: el uso de gradientes. Los gradientes son una forma de pintar un área de forma que hay una transición suave entre varios colores.

“rgb(255,0,0)”); oLinearGradient.addColorStop(0.5, “rgb(0,255,0)”);

Por último el atributo fillStyle puede recibir un gradiente y así cuando se llama a una rutina de pintado, se utiliza dicho gradiente para rellenar los espacios: oContext.fillStyle = oLinearGradient; oContext.fillRect(400,150,230,230);

63

SOLO PROGRAMADORES nº 162


Video:Video

16/6/08

10:09

Página 64

VIDEO-TUTORIAL

Busca las minas En esta ocasión, vamos a diseñar un clon del súper conocido juego del “Busca Minas”, desarrollado en Java con un nivel Básico/Medio.

Jorge Rubira

Las herramientas que utilizaremos en esta ocasión serán SDK 5 y Netbeans 5.5.

El Juego Aunque seguro que de sobra conocido por los lectores, recordemos brevemente la mecánica del mismo. Se trata de localizar minas ocultas a partir de la información proporcionada por las celdas contiguas a las minas. En dichas celdas, aparece un número que indica el nº de minas que hay en las celdas circundantes. El juego termina cuando se ha elegido una celda en la que hay una mina, o cuando se han elegido todas las celdas libres de minas.

Paso a paso Jorge nos enseñará paso a paso cómo cargar, configurar y utilizar las distintas aplicaciones, y el paso a paso de creación y depuración del juego.

¿Cómo obtener el vídeo-tutorial? El material que conforma este vídeo-tutorial consiste en un archivo de vídeo y unos archivos de código que implementan el proyecto. Los lectores de la edición en papel encontrarán el vídeo-tutorial en el CD-ROM, mientras que los lectores de la edición digital lo encontrarán en el

paquete descargado. Recordamos a los lectores de la edición digital que la nueva dirección es http://www.revistasprofesionales.com. El formato del vídeo es WMV y el tamaño de la descarga es de 50 MB aproximadamente.

¿Tienes sugerencias para el próximo vídeo-tutorial? Nos interesa saber cómo podemos mejorar los vídeos y sus contenidos, de modo que si tenéis cualquier sugerencia para futuros vídeos, no dudéis en transmitirla a Jorge Rubira, el autor: encuestavideos@gmail.com.

SOLO PROGRAMADORES nº 162

64

www.revistasprofesionales.com


63 atrasados:atrasados

16/6/08

10:09

Página 1

NÚMEROS ATRASADOS 161 - Junio 2008

160 - Mayo 2008

Los documentos RSS pueden optimizarse sacando provecho de todos los recursos que ofrece el protocolo HTTP. En este último artículo veremos qué librerías ofrece J2ME Polish para desarrollar nuestras aplicaciones. En este artículo (Tecnologías Java a vista de pájaro) se da una visión de las múltiples tecnologías JAVA. “Programación con múltiples hilos”, vamos a comenzar a generar código y ejemplos concretos. “Scrum II”, el artículo se centra en sus eventos y en cómo roles y artefactos participan en ellos. Una de las prestaciones más espectaculares para los que vivimos la transición entre los entornos de caracteres a gráficos fue la posibilidad de “Arrastrar” y “Soltar”. Los teléfonos móviles son cada vez más complejos y potentes cuya vulnerabilidad aumenta conforme lo hace su tecnología.

Veremos cómo acceder a los mecanismos de almacenamiento y haremos un repaso rápido a algunas librerías opcionales de Android. RSS se ha convertido en una tarea común en el desarrollado de aplicaciones Web, estudiaremos cómo hacerlo con Java. En este segundo artículo, seguiremos estudiando las capacidades de J2ME Polish. Exploramos las tecnologías que constituyen lo que se denomina como “web semántica con minúsculas”. JavaCup 2008, segunda edición torneo de fútbol virtual Java. Hibernate y la sencillez de la capa de persistencia en JAVA. Con Java Media Framework (JMF) resulta muy fácil crear aplicaciones de vídeo y audio. 1 CD-ROM incluido. Incluye Solop 158 en PDF.

159 - Abril 2008

158 - Marzo 2008 Desvelamos las principales novedades de Visual Basic 2008. Análisis sobre la versión final del Service Pack 1 de Windows Vista. Análisis de Microsoft Visual Studio 2008, con la edición Express. Profundizaremos algo más en los tipos de aplicaciones que pueden hacerse con Android y las APIs disponibles. Descripción de PyS60 versión de Python ideada para dispositivos móviles con sistema operativo Symbian y de tipo Serie 60. Análisis de LINQ para SQL. Creación y gestión de componentes, así como la publicación de nuestras bases de datos en la web. Ponemos en práctica mediante la framework Jena las tecnologías semánticas revisadas en la primera parte. 1 DVD incluido.

Paseo por The Evolution Show organizado por Microsoft para presentar sus últimos productos. Solución a problemas habituales desarrollando en J2ME pero que pueden mitigarse con J2ME Polish. Cómo generar un entorno de aprendizaje virtual a través del cual alumnos y profesores puedan interaccionar. Nuevas extensiones de Microsoft para ejecución paralela en .NET. Tratamos el Desarrollo de aplicaciones para redes sociales con OpenSocial de Google. Analizamos Java Media Framework (JMF) un software que permite crear aplicaciones Java. 1 CD incluído.

157 - Febrero 2008 Nos sumergimos en el mundo Android, la nueva plataforma móvil de la Open Handset Alliance, para analizar las herramientas incluidas en su SDK y poder crear nuestra primera aplicación Android. Además, continuamos nuestro seguimiento a la tecnología 4D v11 SQL, iniciamos una serie dedicada a LINQ para SQL, continuamos nuestro desarrollo para iPhone, programamos la web semántica con Jena y ofrecemos la segunda entrega de nuestro curso AJAX. 1 CD-ROM incluido.

Si te falta algún número de la temporada, ahora tienes la oportunidad de conseguirlo Precio Oferta descuento Precio por ejemplar: 6€

1 a 10 = 10% dto. / 11 a 20 = 20% dto. 21 a 30 = 30% dto. / 31 a 40 = 40% dto. +40 = 50%

BOLETÍN DE PEDIDO

Rellene o fotocopie el cupón y envielo a REVISTAS PROFESIONALES, S.L. (Revista SÓLO PROGRAMADORES) C/ Valentín Beato, 42 - 3ª Planta - 28037 MADRID Tel.: 91 304 87 64 - Fax: 91 327 13 03 - www.revistasprofesionales.com - rpsuscripciones@revistasprofesionales.com Deseo me envíen los número/s: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . NOMBRE Y APELLIDOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .EDAD . . . . . . . . TELÉFONO . . . . . . . . . . . . . . . . DOMICILIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .C.P.: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CIUDAD . . . . . . . . . . . . . . . . . .PROVINCIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

 

FORMAS DE PAGO

Giro Postal a nombre de REVISTAS PROFESIONALES, S.L.  Talon Bancario a nombre de REVISTAS PROFESIONALES S.L. Domiciliación Bancaria  Contra Reembolso (5€ de gastos de envio por paquete) Banco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Domicilio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Firma: Numero de cuenta: _ _ _ _/ _ _ _ _/ _ _ / _ _ _ _ _ _ _ _ _ _ _ _ Titular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  Tarjeta de crédito _ _ _ _/ _ _ _ _/ _ _ _ _/ _ _ _ _/ Fecha de caducidad: Extranjero: Gastos de envio 5€ por paquete. Unica forma de pago tarjeta de crédito (VISA, Mastercard, American Express,...)


CDROM:CDROM

16/6/08

10:00

Página 66

CD-ROM

Contenido del CD-ROM Fuentes



RSS con Java III Los documentos RSS pueden servirse de forma optimizada sacando provecho de todos los recursos que ofrece el propio protocolo HTTP, empezando por la compresión de datos que transfieren al cliente. Además empleando la caché en el servidor, la caché en el cliente y las cabeceras HTTP, se crea una arquitectura que reduce la carga de trabajo. Con ello la aplicación está lista para servir más documentos RSS, en menor tiempo.

La OpenJavaDay 2008 se celebrará el 26 y 27 de junio  TagsMe  JBuilder  Un vistazo a Servlet 3.0  ExtJS cambia su licencia LGPL por GPLv3  Java ONE Sección entrevista: Entrevista a Ignacio Coloma donde nos presentará el framework Loom. Entrevistadores: Erick Camacho y Jorge Rubira.

Vídeo – Tutorial En esta ocasión, vamos a diseñar un clon del súper conocido juego del “Busca Minas”, desarrollado en Java con un nivel Básico/Medio.

Podcast javaHispano Edición número 13 del podcast de Javahispano. Este número esta dedicado a un interesante framework llamado Loom. Al igual que en los anteriores números está dividido en dos secciones: Sección noticias: Presentado por Abraham Otero y Alfredo Casado.

SOLO PROGRAMADORES nº 162

66

Las herramientas que utilizaremos en esta ocasión serán SDK 5 y Netbeans 5.5 Jorge nos enseñará paso a paso cómo cargar, configurar y utilizar las distintas aplicaciones, y el paso a paso de creación y depuración del juego.

Además … Solo Programadores 160 en formato pdf.

www.revistasprofesionales.com


ML en solop.qxd:ML en solop

17/6/08

12:46

Página 1

FreeBSD es un sistema operativo libre estilo Unix, compatible con este último, que está presente desde hace muchos años y dio origen a otros sistemas operativos. Estudiaremos su última versión, lanzada recientemente y los pasos para conseguir una instalación correcta.

-

FreeBSD versus Linux Web Setvices con Linux Endian Firewall Security Appliance Diseño gráfico con Linux (II) GIMP 2.4.3 (II) WifiSlax 3.1 LiveUSB

Ya en tu quiosco


210X280_G.indd 1

14/4/08 12:14:52

LOS BUENOS DESARROLLADORES SOLUCIONAN PROBLEMAS. LOS GRANDES EQUIPOS HACEN HISTORIA.

Crea aplicaciones más atractivas y más plataformas en menos tiempo, colaborando, comunicándote y alcanzando todos tus objetivos con Visual Studio® Team System. Más consejos y herramientas en desafiatodoslosretos.com


Solo Programadores #162