Single sourcing con Eclipse RAP

Introduzione a RAP

RAP (Rich Ajax Platform) è un framework che vi permette di sviluppare una applicazione RCP e renderla disponibile in rete semplicemente indirizzando il browser su un dato link.
In questo articolo vedremo come potete sviluppare una applicazione RCP e lanciarla sia come applicazione desktop che come applicazione web . Sì, certo, esattamente lo stesso codice sorgente!
Non ci credete? Provate voi stessi.

 

Setup dell’IDE per RAP

Il modo più veloce per lavorare con RAP è quello di scaricare la versione Eclipse for RCP and RAP Developers dalla pagina http://www.eclipse.org/downloads

Alternativamente potete aggiungere RAP a qualsiasi altra Eclipse Indigo SR2 (ovvero la versione 3.7.2), semplicemente selezionando Help -> Install New Software… -> scegliere l’update sitd di Indigo e installare Rich Ajax Platform (RAP) Tooling 1.4.2 sotto la categoria Web, XML, Java EE and OSGi Enterprise Development.

Ora dobbiamo effettuare il setup di una RAP target plaftorm. Quindi lanciamo Eclipse e selezioniamo Window -> Preferences -> Plug-in Development -> Target Platform

e premiamo il bottone Add… e poi Next

Diamo un nome alla platform, ad es. RAP_1.4 e premiamo Add… nel primo tab (Locations)

poi selezioniamo Software Site

e poi Next. Quindi aggiungiamo l’Update site RAP 1.4 Runtime
http://download.eclipse.org/rt/rap/1.4/runtime

deselezioniamo il radio button Include required software e premiamo Finish.

questa operazione potrebbe richiedere un po’ di tempo. Al termine questo è quello che dovreste vedere

premere Finish.
Quindi seguiamo la stessa procedura aggiungendo, dall’update site di Indigo http://download.eclipse.org/releases/indigo, la feature EMF RAP Target Components dalla Category EclipseRT Target Platform Components. Dovreste ora vedere quanto segue

La cosa importante da tenere presente qui è che ora avete due target platform: quella RCP e quella RAP. Selezionate quella RAP per questo workspace e premete OK.

Ora lanciate un’altra istanza Eclipse e scegliete un nuovo workspace, che sarà usato per lo sviluppo RCP.
Sta diventando chiaro quello che stiamo facendo? Vogliamo avere due differenti workspace, uno per eseguire il lancio RCP (=Desktop) e l’altro per eseguire il lancio RAP (=Web). Ma anche il progetto deve essere diverso? Niente affatto: stessi identici sorgenti!

Dopo aver lanciato Eclipse con il workspace RCP seguiamo uno degli wizard per creare una applicazione RCP: File -> New -> Plug-in Project, diamo un nome al plug-in (es. it.rcpvision.rcprap.application) e selezioniamo Yes alla domanda “Do you want to create a Rich Client Application?“. Poi scegliamo il secondo template “RCP application with a view” e premiamo Finish. Ora lanciamo l’applicazione; vedrete questo

Fin qui niente di nuovo, una cosa che probabilmente fate quasi quotidianamente.

Ora faremo un piccolo cambiamento nelle Dependencies di questo plug-in. Selezioniamo la dependenza da org.eclipse.ui per renderla Opzionale.

Andiamo quindi al tab MANIFEST.MF e aggiungiamo una dipendenza da org.eclipse.rap.ui e rendiamo anch’essa Opzionale.

Se eseguiamo di nuovo l’applicazione otterremo, naturalmente, lo stesso risultato. Abbiamo semplicemente introdotto una doppia dipendenza, alternativa, verso RCP e RAP. A seconda della platform verrà sfruttata l’una o l’altra, dallo stesso medesimo codice sorgente.

Ora torniamo all’altra istanza di Eclipse, quella che punta al workspace configurato per RAP, e importiamo lo stesso progetto dal file system.
Poi selezioniamo Run -> Run Configurations… -> RAP Application -> New

Nel primo tab (Main) premiamo il bottone Browse per il campo Entry Point or Application

e selezioniamo la nostra applicazione

Nel secondo folder (Bundles) premiamo Deselect All e aggiungiamo la nostra applicazione (it.rcpvision.rcprap.application) e i seguenti plug-in

com.ibm.icu.base
javax.servlet
org.eclipse.core.commands
org.eclipse.core.contenttype
org.eclipse.core.databinding
org.eclipse.core.databinding.beans
org.eclipse.core.databinding.observable
org.eclipse.core.databinding.property
org.eclipse.core.expressions
org.eclipse.core.jobs
org.eclipse.core.runtime
org.eclipse.equinox.app
org.eclipse.equinox.common
org.eclipse.equinox.http.jetty
org.eclipse.equinox.http.registry
org.eclipse.equinox.http.servlet
org.eclipse.equinox.http.servletbridge
org.eclipse.equinox.preferences
org.eclipse.equinox.registry
org.eclipse.equinox.servletbridge
org.eclipse.equinox.servletbridge.extensionbundle
org.eclipse.help
org.eclipse.jdt.junit.runtime
org.eclipse.osgi
org.eclipse.osgi.services
org.eclipse.rap.jface
org.eclipse.rap.jface.databinding
org.eclipse.rap.junit
org.eclipse.rap.junit.runtime
org.eclipse.rap.rwt
org.eclipse.rap.rwt.q07
org.eclipse.rap.rwt.theme.classic
org.eclipse.rap.ui
org.eclipse.rap.ui.cheatsheets
org.eclipse.rap.ui.forms
org.eclipse.rap.ui.views
org.eclipse.rap.ui.workbench
org.junit
org.mortbay.jetty.server
org.mortbay.jetty.util

Nota: se non avete intenzione di aggiungerli uno ad uno, potete persistere il lancio (tab Common -> Save as -> Shared file) e poi aprire il lancio stesso come testo e cambiare la seguente linea

con il seguente contenuto

<stringAttribute key=”target_bundles” value=”com.ibm.icu.base@default:default,javax.servlet@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.beans@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.runtime@default:true,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.http.jetty@default:default,org.eclipse.equinox.http.registry@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.equinox.http.servletbridge@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.servletbridge.extensionbundle@default:false,org.eclipse.equinox.servletbridge@default:default,org.eclipse.help@default:default,org.eclipse.jdt.junit.runtime@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.rap.jface.databinding@default:default,org.eclipse.rap.jface@default:default,org.eclipse.rap.junit.runtime@default:default,org.eclipse.rap.junit@default:default,org.eclipse.rap.rwt.q07@default:false,org.eclipse.rap.rwt.theme.classic@default:default,org.eclipse.rap.rwt@default:default,org.eclipse.rap.ui.cheatsheets@default:default,org.eclipse.rap.ui.forms@default:default,org.eclipse.rap.ui.views@default:default,org.eclipse.rap.ui.workbench@default:default,org.eclipse.rap.ui@default:default,org.junit@default:default,org.mortbay.jetty.server@default:default,org.mortbay.jetty.util@default:default”/>

Ok, siamo pronti a partire: eseguite il lancio e dovreste vedere il browser interno aprire la vostra applicazione come applicazione Web!

Potete copiare lo stesso URL su vostro browser preferito dallo stesso pc, ma ovviamente anche da un’altro pc sulla stessa rete, semplicemente sostituendo l’IP (127.0.0.1) con quello che identifica il vostro pc sulla rete.

Buon divertimento con RAP a tutti!

Riconoscimenti
Grazie al Team di RAP e a Hendy Irawan per questo suo prezioso articolo
http://eclipsedriven.blogspot.it/2010/12/eclipse-rap-single-sourcing-awesomeness.html, che ha ispirato la creazione di questo tutorial.

 

 

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Application
Bundle-SymbolicName: it.rcpvision.rcprap.application; singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: it.rcpvision.rcprap.application.Activator
Require-Bundle: org.eclipse.ui;resolution:=optional,
org.eclipse.rap.ui;resolution:=optional,
org.eclipse.core.runtime
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
This entry was tagged , , , , . Bookmark the permalink.

7 Responses to Single sourcing con Eclipse RAP

  1. Lars Vogel says:

    AFAIK the Entrypoint is not required that you can re-use your application definition.

  2. David S says:

    Works great! ;-)
    Thanks for the great information.

  3. Claus says:

    The article was very useful, thank you.
    Regarding the workspaces:
    Is it possible do have RAP & RCP in just one workspace?

    AHoi,
    Claus

    • Vincenzo says:

      Claus,
      yes, you can switch between two (or more) Target Platforms (RAP & RCP) while staying in the same workspace.
      Vincenzo

  4. Darren says:

    I have an example on Juno that I cannot get to work at all.
    It is the table of authors example, with CDO, but trying to run as RAP.

    I get the following in my stack trace from the RAP launcher:

    java.lang.NoSuchMethodException: org.eclipse.e4.ui.css.swt.internal.theme.BootstrapTheme3x.(org.eclipse.swt.widgets.Display)
    at java.lang.Class.getConstructor0(Unknown Source)
    at java.lang.Class.getConstructor(Unknown Source)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2568)
    at org.eclipse.ui.internal.Workbench.access$5(Workbench.java:2530)
    at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:702)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:685)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:157)
    at darren.emf.example.rcp.Application.start(Application.java:20)
    at org.eclipse.rap.ui.internal.application.EntryPointApplicationWrapper.createUI(EntryPointApplicationWrapper.java:38)
    at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle.createUI(RWTLifeCycle.java:177)
    at org.eclipse.rwt.internal.lifecycle.RWTLifeCycle$UIThreadController.run(RWTLifeCycle.java:289)
    at java.lang.Thread.run(Unknown Source)
    at org.eclipse.rwt.internal.lifecycle.UIThread.run(UIThread.java:102)

    The application starts up and shows me a basic Library Manager UI in the browser, with a button for the View Authors (which is supposed to open the view part). When I press the View Authors button, nothing happens ( btw, this does all work when run as RCP).

    Do you have any idea what I might be doing wrong here?

    • Darren says:

      It does register my button press in the web server in that it logs some stuff when I press the button, but the view fails to open…..

      15:01:03.635 [qtp759121585-39] DEBUG org.eclipse.jetty.http.HttpParser – filled 610/610
      15:01:03.635 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG org.eclipse.jetty.server.Server – REQUEST /rap on AsyncHttpConnection@2fff2784,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=2,l=65,c=72},r=2
      15:01:03.636 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG o.e.j.server.handler.ContextHandler – scope null||/rap @ o.e.j.s.ServletContextHandler{/,null}
      15:01:03.636 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG o.e.j.server.handler.ContextHandler – context=||/rap @ o.e.j.s.ServletContextHandler{/,null}
      15:01:03.636 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG org.eclipse.jetty.server.session – Got Session ID 560itklghk8ls8o1v7vgrycx from cookie
      15:01:03.636 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG org.eclipse.jetty.server.session – sessionManager=org.eclipse.jetty.server.session.HashSessionManager@68d93a9e
      15:01:03.636 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG org.eclipse.jetty.server.session – session=org.eclipse.jetty.server.session.HashedSession:560itklghk8ls8o1v7vgrycx@1281894017
      15:01:03.636 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG o.e.jetty.servlet.ServletHandler – servlet ||/rap -> org.eclipse.equinox.http.jetty.internal.HttpServerManager$InternalHttpServiceServlet-655028946
      15:01:03.636 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG o.e.jetty.servlet.ServletHandler – chain=null
      15:01:03.640 [qtp759121585-39 - /rap?nocache=1370008863633] DEBUG org.eclipse.jetty.server.Server – RESPONSE /rap 200
      15:01:03.641 [qtp759121585-39] DEBUG o.e.jetty.server.AsyncHttpConnection – Enabled read interest SCEP@32ee2213{l(/127.0.0.1:53331)r(/127.0.0.1:53001),d=true,open=true,ishut=false,oshut=false,rb=false,wb=false,w=true,i=1r}-{AsyncHttpConnection@2fff2784,g=HttpGenerator{s=4,h=0,b=0,c=-1},p=HttpParser{s=0,l=65,c=72},r=2}
      15:01:03.641 [qtp759121585-39] DEBUG org.eclipse.jetty.http.HttpParser – filled 0/0

      • Vincenzo says:

        Hi Darren,
        from the stacktrace I cannot tell what the problem may be.
        I suggest to follow the article step by step on a brand new workspace and then start putting your code, again step by step, each time checking that all is working.
        In this way you can focus on the single step that (maybe) bring the problem.
        Let me know.
        Vincenzo

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *


*

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>