sábado, 11 de febrero de 2012

Generar Imágenes Compuestas con SWT

Siempre había pensado que combinar una imagen a partir de otras dos era una tarea no demasiado complicada, sobretodo cuando la mayoría hemos pasado por Java Swing... no obstante, al ir a hacerlo con SWT me encontré sin la suficiente información como para hacerlo.

Es por ello que he decidido hacer esta entrada sencilla, simplemente para poner un ejemplo de cómo se componen las imágenes en SWT. Para llevarlo a cabo necesitaremos utilizar el Graphics Context de SWT (GC). Y seguiremos los siguientes pasos:

  1. Crearemos una imagen con un tamaño específico con:
    Image compoundImage = new Image(Display.getDefault(), 22,22);
  2. Utilizaremos el contexto gráfico de la propia imagen para dibujar las imágenes con su offset:
GC gc = new GC(compoundImage );
 gc.drawImage(image1, 0, 0);
 gc.drawImage(image2, 6, 6);
Una vez hecho esto ya tendremos la imagen que queremos en compoundImage, que será una composición de las imágenes image1 y image2.

Observaciones

  1. A partir del gc de la imagen podremos dibujar lo que queramos encima de la imagen, ya sea texto, lineas, figuras...
  2. Una imagen creada, siempre la tendremos que liberar manualmente haciendo un compoundImage.dispose(), para no quedarnos sin handlers en el Sistema Operativo

jueves, 9 de febrero de 2012

Generar un producto RCP

Generar un producto RCP es un proceso muy sencillo y didáctico que puede llevarse a cabo a través de las herramientas que nos ofrece Eclipse.

¿Qué es un producto?
Un producto RCP realmente es un conjunto de plugins agrupados de tal manera que forman una aplicación final de usuario. Esto nos permite, a partir de una aplicación RCP modular, tener distintas versiones de nuestra aplicación según los plugins que lleven integrados.

Por otra parte, un producto va a ser la forma de exportar nuestra aplicación a un entorno ejecutable. Dicho de otra manera, a partir de este producto se generarán todos los archivos necesarios para poder ejecutar nuestra aplicación.

¿Cómo generar un producto?
Para generar un producto seguiremos los siguientes pasos:

1. Creación de un nuevo Product Configuration(*.product) a partir de Eclipse


2. Si ya teníamos un producto base, podremos generar el nuevo producto a partir de ese, sino crearemos un nuevo fichero de configuración.

3. Le dotamos de sus atributos principales (id, nombre y versión) en la pestaña Overview

4. Le asignamos todos los plugins que hayamos creado para nuestra aplicación en la pestaña Dependencies a través del botón Add...

Una vez añadidas las dependencias principales, agregaremos todos los plugins requeridos por éstas a través del botón de Add Required Plugins.

5. Le indicamos las extensiones org.eclipse.core.runtime.products y org.eclipse.core.runtime.applications que nos indicarán cómo se iniciará nuestra aplicación o producto. Ambas extensiones deberán estar ligadas al plugin.xml de alguno de los plugins ofrecidos por nuestra aplicación.


Con todo esto podremos exportar nuestro producto para tener un archivo ejecutable en una plataforma determinada, ya sea Windows, Linux, Mac o Solaris
Opciones opcionales

A través de las diferentes pestañas del editor de configuración de producto, Eclipse nos ofrece una serie de funcionalidades:
  • Launching: Nos permite definir los elementos que integrarán nuestro ejecutable, como su icono, el entorno Java necesaria así como también algún parámetro de ejecución de la máquina virtual de Java, todo según la plataforma a la que vaya destinada.
  • Splash: Nos permite crear el splash de nuestra aplicación. Esto lo que hará principalmente es introducirnos una nueva extensión en nuestro plugin principal.
  • Branching: Nos permite crear la "Ventana de Bienvenida" y de "Acerca de" de nuestra aplicación, en caso de no haberla creado anteriormente en el plugin. También nos permite asociar los iconos de la aplicación según la plataforma a la que vaya asignado (Iconos de ventana, de barra de inicio...)
  • Licensing: Nos permite indicar el tipo de licencia de nuestro producto en caso de tener.
Referencias
  1. http://www.eclipse.org/articles/Article-RCP-1/tutorial1.html
  2. http://www.vogella.de/articles/EclipseRCP/article.html#tutorialexport_productfile

viernes, 3 de febrero de 2012

RCP con Java Web Start (JNLP)

Las aplicaciones RCP nacieron a partir del IDE Eclipse, una aplicación standalone que parecía no tener nada que ver con Java Web Start. No obstante, muchas veces interesa poder tener una aplicación autoinstalable y autoactualizable desde la red, por lo que la utilización de la tecnología Java Web Start puede parecer ideal.

Al no ser una de las funcionalidades básicas del entorno PDE, puede resultar un poco difícil entender que se debe hacer para poder exportar aplicaciones RCP a JNLP. En esta entrada del blog os detallaré los pasos a seguir.

Tener listo nuestro producto (product)

Es importante tener un producto realizado y listo para exportar, lo ideal sería probarlo primero exportándolo como un producto Eclipse (mediante la herramienta "Export..." del IDE Eclipse).


Una vez generado, deberemos asegurarnos de que todo funciona correctamente, ya que una vez exportado a JNLP puede ser difícil saber con seguridad que es lo que está fallando.

Crear un wrapper de nuestro producto a través de una Feature

Uno de los requisitos fundamentales de Java Web Start es que todas las librerías que se descarguen dentro de un mismo producto deben estar firmadas con la misma clave (keystore). Por ello, Eclipse nos ofrece la posibilidad de firmar todos los plugins de nuestro producto con su herramienta de exportación (la misma que en el apartado anterior).
El problema que nos plantea esta herramienta es que necesitamos que nuestro producto sea una feature y no un plugin, por lo que necesitamos una pequeña transformación. Deberemos crear una feature que haga de wrapper de nuestro plugin, cosa que es realmente sencilla. Estos son los pasos a seguir:
1. Creamos un nuevo proyecto de eclipse, eligiendo la opción Plug-in Development-->Feature Project.

2. Rellenamos los atributos del proyecto. (Dicen que es importante rellenar el provider, por lo que que mejor lo rellenamos)


3. Seleccionamos el producto anteriormente creado


4. Finalizamos la creación del proyecto.
5. Una vez hecho esto tendremos que añadirle una sola feature más dentro del apartado Included Features del feature.xml de nuestro wrapper: org.eclipse.rcp


Con todo esto ya tendremos creado nuestro wrapper.

Exportar wrapper a JNLP

Para exportar a JNLP nuestra feature utilizaremos de nueva la herramienta de exportación de Eclipse, seleccionando esta vez la opción de Deployable Features. Esta opción la tenemos disponible en la esquina superior-derecha del editor del feature.xml (lo podemos observar en la imagen anterior).
 Para la exportación tenemos que asegurarnos de seguir los siguientes pasos:
1. Seleccionar un directorio de destino donde se situaran los archivos generados.
2. Seleccionar en la pestaña de opciones solamente la opción de empaquetar en archivos JAR individuales y si queremos exportarlo a diferentes plataformas (en este último caso necesitaremos el Delta Pack de Eclipse)


4. Introducir el keystore con el que se firmarán todas las librerías generadas.
5. Seleccionar la opción de generar los archivos JNLP que nos servirán de enlace con la aplicación y introducir el path desde donde se descargará (es probable que tengamos que editar este path más adelante según la distribución de directorios de nuestro servidor)
Una vez hecho todo esto finalizamos y esperamos a que se generen todos los archivos con un poco paciencia, ya que suele ser un proceso un poco largo.

Generar nuestro JNLP base
Tiene que quedar claro que no es suficiente disponer de los archivos JNLP generados por eclipse para poder lanzar nuestra aplicación. Deberemos generar un archivo JNLP parecido al siguiente que nos sirva para lanzar el jnlp adecuado según el sistema operativo del que se disponga:

<?xml version="1.0" encoding="UTF-8"?>
<jnlp
    spec="1.0+"
    codebase="http://url" href="ARCHIVO_JNLP_CREADO.jnlp">

  <information>
    <title> Product </title>
    <vendor>COMPANY</vendor>
    <homepage href="http://www.WEBSITE.es" />
    <description>DESCRIPTION</description>
    <offline-allowed/>

 <icon href="images/logo.png" kind="default"/>
    <shortcut online="true">
        <desktop/>
            <menu submenu="menu">
            <menu submenu="SUBMENU"/>
            </menu>
    </shortcut>

  </information>
  <security>
    <all-permissions/>
  </security>

  <application-desc main-class="org.eclipse.equinox.launcher.WebStartMain">
    <argument>-showsplash</argument>
  </application-desc>

<resources>
<property
        name="eclipse.product"
        value="es.company.product"/>
<jar href="plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar"/>
<property name="osgi.instance.area" value="@user.home"/>
<property name="osgi.install.area" value="@user.home/osgi"/>
<property name="osgi.configuration.area" value="@user.home"/>
<property name="osgi.sharedConfiguration.area" value="@user.home/configuration"/>
<property name="osgi.splashPath" value="platform:/base/plugins/PLUGIN_DONDE_SE_ENCUENTRA_EL_SPLASH"/>
</resources>
<resources os="Linux" arch="x86">
        <property name="osgi.ws" value="gtk"/>
 <extension
        name="Product"
        href="features/product.gtk.x86.jnlp"/>
  </resources>

<resources os="Linux" arch="x86_64">
        <property name="osgi.ws" value="gtk"/>
 <extension
        name="Product"
        href="features/product.gtk.x86_64.jnlp"/>
  </resources>
<resources os="Mac" arch="ppc">
  <extension
        name="Product"
        href="features/product.cocoa.ppc.jnlp"/>
  </resources>
  </resources>
<resources os="Mac" arch="x86">
<extension
        name="Product"
        href="features/product.cocoa.x86.jnlp"/>
  </resources>
  </resources>

<resources os="Mac" arch="x86_64">
 <extension
        name="Product"
        href="features/product.cocoa.x86_64.jnlp"/>
  </resources>

  <resources os="Windows" arch="x86">
    <extension
        name="Product"
        href="features/product.win32.x86.jnlp"/>
<property name="osgi.instance.area" value="@user.home/Application Data"/>
        <property name="osgi.configuration.area" value="@user.home/Application Data"/>
  </resources>

<resources os="Windows" arch="x86_64">
    <extension
        name="Product"
        href="features/product.win32.x86_64.jnlp"/>
<property name="osgi.instance.area" value="@user.home/Application Data"/>
        <property name="osgi.configuration.area" value="@user.home/Application Data"/>

  </resources>

</jnlp>
Este archivo es un ejemplo y no es común para todas las aplicaciones, simplemente os puede ayudar a la hora de generar vuestro script. Para más información sobre cómo generar este tipo de scripts podéis ir aquí.
NOTA: Las propiedades introducidas son necesarias para el correcto funcionamiento de las aplicaciones RCP, es probable que si no se pone alguna de ellas, pueda dejar de funcionar

Problemas encontrados al exportar en multiplataforma
Existen una serie de problemas exportando a un producto RCP a un jnlp multiplataforma, como mínimo en mi caso particular (exportando con Windows7 y Eclipse Indigo).

El error tipo es el siguiente:
org.osgi.framework.BundleException: The activator org.eclipse.ui.internal.WorkbenchPlugin for bundle org.eclipse.ui.workbench is invalid
    at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadBundleActivator(AbstractBundle.java:171)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:679)
    at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
    at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
    at org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
    at org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)

En mi caso particular he observado como dentro de los jnlps para Linux y para Mac Os X se incluían enlaces a librerías de Windows. Es por ello que para solucionarlo deberemos firmar los archivos correctos. Este sería el workaround:

1. Firmar los plugins del Delta Pack para subirlos a nuestra carpeta plugins del servidor
2. Modificar los archivos JNLP de cada plataforma para que no se enlacen con los plugins nativos de Windows.

Subir los archivos a nuestro servidor de aplicaciones Java
Por último, solamente falta subir los archivos al servidor y disfrutar de nuestra aplicación en nuestro sistema operativo preferido. Espero que os haya servido de ayuda.

Referencias 
1.http://thomaswabner.wordpress.com/2011/03/28/run-eclipse-rcp-application-via-webstart/ 
2.http://www.toedter.com/blog/?p=650 
3.http://www.techjava.de/topics/2010/02/launching-rcp-via-jws/ 

lunes, 23 de enero de 2012

Bienvenidos

Este blog va a intentar ser una referencia para aquellos desarrolladores de Java, RCP y Android que tengan problemas y que no dominen el inglés (sin quitarle trabajo a Google Translate ^^). Básicamente os trasladaré mis experiencias con estas tecnologías, sobre todo aquellas que involucren un trabajo de búsqueda intensa por internet para hallar la solución.

Como creo que para enseñaros qué es cada una de estas tecnologías ya existen sus debidas páginas, con sus tutoriales y explicaciones técnicas, simplemente indicaré mis motivaciones por las tecnologías elegidas.

RCP es simplemente una tecnología que me apasiona por dotar de modularidad a la plataforma Java. Me parece una forma muy correcta de trabajar, aunque como en todo hay cosas que tienen su aprendizaje hasta que las haces bien.

Por otra parte, como las tecnologías móviles están en auge desde hace ya algunos años, me comencé a interesar por las primeras versiones de la plataforma Android y la he ido siguiendo hasta el día de hoy (de la M0.5 hasta la 4.0, sí existía la M05 ^^). Es por ello que intentaré descubriros cómo solucionar algunos de los problemas comunes con esta plataforma.

Espero ir subiendo cosas a menudo, tendré que aprovechar el tiempo.

Saludos de bienvenida