miércoles, 16 de enero de 2013

De Swing a JavaFX

Bueno, el ecosistema Java vuelve a hacer obsoletos algunos de mis libros sobre Java y coincidencialmente el apartado es el mismo, las interfaces gráficas y es que por allá en mis inicios con Java las “gui’s” se hacían con el ya veterano AWT (Abstract Window Toolkit, creo que era) que como herramienta para desarrollo de interfaces era muy básico, quizás mas que suficiente para algunos pero para otros era demasiado elemental, las aplicaciones Java eran muy planas, fácilmente reconocibles por las particularidades de su apariencia.

Esto cambió radicalmente con el nacimiento de Swing, una aplastante propuesta que se incorporó de a poco como una biblioteca opcional hasta convertirse en parte fundamental del sistema, entre sus ventajas traia un rico conjunto de widgets, una modularidad y la capacidad de adquirir la apariencia del host con total facilidad, para ello existían versiones distintas para cada host, entre sus detractores estaban los que aducían un incremento en el tamaño de las aplicaciones y una ralentización de las mismas, de hecho, no estaban muy lejos de la realidad y aunque hoy dia con los sistemas actuales, apenas se logra percibir un cambio sustancial entre una aplicacion nativa y una aplicación Java con Swing, en sus inicios este exceso de tiempo en la carga de las aplicaciones provocaron que iniciativas como SWT nacieran y se hicieran eco en los desarrolladores.

Ahora, Oracle le apuesta a JavaFX, después de la adquisición de Sun por parte de Oracle, JavaFX sufrió un lavado de cara y una reingeniería que a mas de uno (incluyendome) logró desanimar pero que al final, fueron mas los aciertos que los fracasos en los cambios.

JavaFX, alternativa a tener en cuenta

Por qué deberíamos tener en cuenta en nuestros desarrollos a JavaFX?, personalmente pienso que terminará imponiéndose como sistema de interfaz de usuario por defecto, de hecho, las ventajas sobre Swing son múltiples, la innovación en widgets y efectos nativos hace que la creatividad del desarrollador sea fundamental para crear aplicaciones vistosas, atractivas y sobre todo funcionales, muy acordes a estos tiempos de cambio en donde las aplicaciones tienen identidad propia y se busca tiempos cortos de desarrollo, logrados solo con kits muy ricos y listos para usar.

Creando una aplicación

Este ejemplo es demasiado sencillo, pero vale la pena realizar porque se hace necesario tener una base para poder comparar y es que algo que si es cierto es que con cada innovación, el código tiende a ser mas complejo, pocas veces y pocos lenguajes logran innovación con simplicidad, aunque es posible y existen estas joyas por ahí, el caso de Java con Swing y JavaFX es de prestar atención. Son tres ventanas, realizadas con AWT, Swing, y JavaFX, en el caso de Swing, las líneas 40 a 53 se pueden obviar, ya que intentan establecer a Nimbus como un Look and Feel por defecto en la aplicación, para el caso de JavaFX las líneas que se pueden obviar son desde la 23 hasta la 33, lo que nos da una aproximación a las principales diferencias de este sistema de ventanas.

  1: package basicswing;
  2: 
  3: /**
  4:  *
  5:  * @author Wilmar
  6:  */
  7: public class AWT_Window extends java.awt.Frame {
  8: 
  9:     /**
 10:      * Creates new form AWT_Window
 11:      */
 12:     public AWT_Window() {
 13:         initComponents();
 14:     }
 15: 
 16:     private void initComponents() {
 17: 
 18:         setPreferredSize(new java.awt.Dimension(640, 480));
 19:         setTitle("Ventana AWT");
 20:         addWindowListener(new java.awt.event.WindowAdapter() {
 21:             public void windowClosing(java.awt.event.WindowEvent evt) {
 22:                 exitForm(evt);
 23:             }
 24:         });
 25: 
 26:         pack();
 27:     }
 28: 
 29:     /**
 30:      * Exit the Application
 31:      */
 32:     private void exitForm(java.awt.event.WindowEvent evt) {                          
 33:         System.exit(0);
 34:     }                         
 35: 
 36:     /**
 37:      * @param args the command line arguments
 38:      */
 39:     public static void main(String args[]) {
 40:         java.awt.EventQueue.invokeLater(new Runnable() {
 41:             @Override
 42:             public void run() {
 43:                 new AWT_Window().setVisible(true);
 44:             }
 45:         });
 46:     }
 47: }

La versión con Swing solo tiene unos ligeros cambios:

  1: package basicswing;
  2: 
  3: /**
  4:  *
  5:  * @author Wilmar
  6:  */
  7: public class Swing_Window extends javax.swing.JFrame {
  8: 
  9:     /**
 10:      * Creates new form Swing_Window
 11:      */
 12:     public Swing_Window() {
 13:         initComponents();
 14:     }
 15: 
 16:     @SuppressWarnings("unchecked")
 17:     private void initComponents() {
 18: 
 19:         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
 20:         setTitle("Ventana Swing");
 21: 
 22:         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
 23:         getContentPane().setLayout(layout);
 24:         layout.setHorizontalGroup(
 25:             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 26:             .addGap(0, 400, Short.MAX_VALUE)
 27:         );
 28:         layout.setVerticalGroup(
 29:             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 30:             .addGap(0, 300, Short.MAX_VALUE)
 31:         );
 32: 
 33:         pack();
 34:     }
 35: 
 36:     /**
 37:      * @param args the command line arguments
 38:      */
 39:     public static void main(String args[]) {
 40:         /* Set the Nimbus look and feel */
 41:         /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
 42:          * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
 43:          */
 44:         try {
 45:             for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
 46:                 if ("Nimbus".equals(info.getName())) {
 47:                     javax.swing.UIManager.setLookAndFeel(info.getClassName());
 48:                     break;
 49:                 }
 50:             }
 51:         } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
 52:             java.util.logging.Logger.getLogger(Swing_Window.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
 53:         }
 54:         
 55: 
 56:         /* Create and display the form */
 57:         java.awt.EventQueue.invokeLater(new Runnable() {
 58:             @Override
 59:             public void run() {
 60:                 new Swing_Window().setVisible(true);
 61:             }
 62:         });
 63:     }
 64: }

La versión en JavaFX…

  1: package basicjavafx;
  2: 
  3: import javafx.application.Application;
  4: import javafx.scene.Scene;
  5: import javafx.scene.layout.StackPane;
  6: import javafx.stage.Stage;
  7: 
  8: /**
  9:  *
 10:  * @author Wilmar
 11:  */
 12: public class BasicJavaFX extends Application {
 13:     
 14:     @Override
 15:     public void start(Stage primaryStage) {
 16:         StackPane root = new StackPane();
 17:         Scene scene = new Scene(root, 300, 250);
 18:         primaryStage.setTitle("Ventana con JavaFX");
 19:         primaryStage.setScene(scene);
 20:         primaryStage.show();
 21:     }
 22: 
 23:     /**
 24:      * The main() method is ignored in correctly deployed JavaFX application.
 25:      * main() serves only as fallback in case the application can not be
 26:      * launched through deployment artifacts, e.g., in IDEs with limited FX
 27:      * support. NetBeans ignores main().
 28:      *
 29:      * @param args the command line arguments
 30:      */
 31:     public static void main(String[] args) {
 32:         launch(args);
 33:     }
 34: }

 


Con una sintaxis limpia y clara, podemos empezar a trabajar en nuestras aplicaciones. A probar JavaFX…

Ser o no ser usuario Java ¡Esa es la cuestión!

Últimamente Java, como herramienta de despliegue de aplicaciones se ha hecho tristemente célebre por una serie de vulnerabilidades que afectan su plataforma, hay mucho rumor mediático y se especula mucho sobre sus alcances, pero, ¿que tan importantes son estas vulnerabilidades?, ¿que tanto afectan al usuario de “a pie”?, ¿es tan crítica la vulnerabilidad como para prescindir del entorno de ejecución?, ¿que medidas puedo tomar al respecto?. Trataré de esbozar un poco estos y otros interrogantes.

 

Java, JDK, JRE y otros demonios

Si hay una tecnología que acumule acrónimos en cantidades sorprendentes es precisamente el ecosistema JAVA, y es que cada tecnología, cada nicho que se cubre tiene su clientela de acrónimos que pueden asustar y confundir a mas de uno así que partamos de lo principal, Java para el usuario final y Java para el desarrollador.

Una aplicación Java puede ejecutarse casi que en cualquier dispositivo, hemos visto aplicaciones Java consiente o inconscientemente, celulares, gps’s, televisores, hornos microondas y como no, computadoras, ejecutan aplicaciones Java de forma transparente para el usuario, y es que Java nace con esa premisa, fue fundado sobre los cimientos de “Escribir una vez, ejecutar en cualquier lado”, es por esta razón que el instalador del entorno de ejecución se jacta de coexistir con otros 3 billones de dispositivos, cifra que puede no ser descabellada si tenemos en cuenta en todos los aparatos en donde se puede encontrar. Ahora bien, para ejecutar una aplicación Java se necesita un entorno de ejecución, es el denominado JRE o Java Runtime Environment, este entorno proporciona todos los requisitos base para que una aplicación se ejecute en un sistema determinado (pc’s, neveras o donde sea). Algunos de estos entornos vienen embebidos en el dispositivo y no se pueden modificar o actualizar, otros, como el que instalamos en la computadora recibe constantes actualizaciones y parches que entre otras cosas, mejoran el rendimiento, añaden funcionalidades o simplemente corrigen errores.

Para el desarrollador la cosa está mas clara, empezando con la base de que el desarrollador sabe lo que hace, vemos que el el Kit de desarrollo Java o JDK por sus siglas en inglés viene con todo lo necesario para empezar a escribir aplicaciones de escritorio, applets, o lo que se nos ocurra, además contiene el propio JRE así que no es necesario descargar e instalar independientemente estas dos herramientas.

Resumiendo hasta ahora, el JRE nos sirve para ejecutar aplicaciones Java, el JDK nos sirve además de poder ejecutar las aplicaciones Java (contiene el JRE), compilar aplicaciones Java (incluye un completo set de herramientas para desarrollo).

 

Las vulnerabilidades…

Ningún sistema está completamente exento de sufrir vulnerabilidades y Java no puede ser la excepción, de hecho, la dinámica de corrección de errores para algunos casos ha sido bastante buena con correcciones muy rápidas, para otros casos no tanto y este ha sido el talón de Aquiles del equipo de respuesta de los responsables del mantenimiento de Java como plataforma, si existe un punto débil es la demora en la corrección de algunos errores que incluso llevan años, pero sin ánimo de extendernos en el tema, hablemos de la “última” vulnerabilidad detectada, se ha hecho tanto eco de ella que vamos a ver de que se trata.

La vulnerabilidad en cuestión es la CVE-2013-0422 , de la que hay que destacar varios hitos muy importantes y que a veces no son tenidos en cuenta por las personas que difunden la noticia, a veces en tono muy amarillista y alarmista, con esto no estoy diciendo de que se debe menospreciar el problema, sino que hay que tratar de dar la información de la forma correcta.

  • La vulnerabilidad afecta solo a Java ejecutándose en los navegadores (Firefox, IExplorer, Opera, etc.…) y no afecta aplicaciones de escritorio (JDownloader, jEdit, entre otras… ), tampoco afecta a servidores ni a las aplicaciones embebidas (dispositivos que corren Java de forma nativa).
  • La vulnerabilidad permite ejecutar código en los sistemas expuestos, con su consecuente riesgo
  • Para afectar, la victima potencial debe visitar páginas ( de dudosa procedencia ) especialmente diseñadas para explotar esta vulnerabilidad, el usuario promedio rara vez se encuentra con estos sitios dañinos
  • Otro probable vector de ataque, pueden ser los applets con publicidad, la verdad me molestan mucho pero para algunos usuarios pasan inadvertidos.

Teniendo en cuenta esto, la problemática que se genera con estas vulnerabilidades, debemos preguntarnos lo mas importante ¿Necesitamos Java? y la verdad es que solo lo necesitaremos cuando realmente lo necesitemos (ambiguo y confuso…). Aclaremos esto, aplicaciones comerciales como Maple incluyen su propia versión de Java, en otras palabras, vienen con su propio JRE adecuado para sus necesidades, la instalación de este JRE es transparente al usuario y solo es utilizado cuando usamos, en este caso, Maple. Netbeans por su parte nos pide tener instalado un JDK, el oficial proporcionado por Oracle, así que para instalar Netbeans debimos haber instalado a Java con anterioridad, necesitamos Java para algo y lo instalamos.

Entonces, ¿que hacer?, bueno, llegamos al punto crucial de todo el tema, y es que partiendo del hecho de que todo sistema es potencialmente vulnerable, debemos cambiar nuestro modo de pensar y adquirir hábitos que minimicen estos problemas, entre las buenas prácticas que podemos hacer encontramos:

  • Desinstalar Java… Jajajaj, es broma, para nada estos es estrictamente necesario, aunque siempre he pensado que si algo no necesitamos, no debería habitar en nuestros sistemas, sin embargo, alrededor de Java podíamos pensar en una cultura de mantenimiento, actualizar Java es buena idea, y más cuando estas actualizaciones corrigen errores, siempre es buen hábito actualizar nuestro sistema y aplicaciones a sus versiones mas recientes o corregidas.
  • Las últimas versiones de Java permiten deshabilitar el plugin de los navegadores de una forma rápida y efectiva, a través de su propio panel de control, ante la alarma, deshabilitar  el plugin debería minimizar el riesgo a punto de desaparecer.
  • Antivirus, en Windows es un mal necesario, personalmente hace mucho que no uso antivirus, pero es mi caso particular, tener un buen antivirus y mantenerlo actualizado puede protegernos de muchas amenazas.

Al final la responsabilidad termina recayendo en el usuario, y es que la vulnerabilidad mas importante de todo sistema siempre el usuario, en el recaen las funciones de salvaguardar las credenciales de acceso, el mantenimiento de los sistemas, la instalación de aplicaciones y un largo etcétera que puede verse afectado en cualquier momento y por cualquier problema, convertirnos en usuarios responsables hará que nuestros sistemas se ejecuten apropiadamente y libres de riesgo.

Enlaces de interés:

Alerta de seguridad: https://blogs.oracle.com/security/entry/security_alert_for_cve_2013

Información sobre la vulnerabilidad http://www.infosecurity-magazine.com/view/30165/another-day-another-java-0day-exploit-in-the-wild/