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