Remote Application Platform (RAP)

Deploy and Manage RAP Applications
on Equinox, Jetty, Virgo, Apache Karaf, and Tomcat

You've written a RAP-based application, and now you want to make it available to the public.

by Markus Knauer / @mknauer23, EclipseSource

EclipseCon 2013, Boston

Deployment habits are changing at the speed of a container ship

Container Ship

How will you run your RAP application in 2013?

Survey on our blog at elipsesource.com, January 2013, 150 replies

RAP on a plain Servlet Container (most participants)

RAP on an application server (some participants)

A small number deploys .war files in the cloud.

A third of the participants are running RAP on plain Equinox

A small group people uses OSGi containers like Virgo, Karaf or different OSGi implementation like Felix

Conclusions

  • Deployment habits seem to be rather conservative
  • Deployment environment seems to be influenced by op's and not dev's
  • Not much of a change compared to a similar survey 2011
  • We should re-think our deployment habits

Standalone RWT without OSGi

Minimal requirements:

  1. The org.eclipse.rap.rwt jar and
  2. A implementation of EntryPoint with UI code and
  3. A implementation of ApplicationConfiguration

EntryPoint

public class HelloWorld implements EntryPoint {
	public int createUI() {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout());
		Label label = new Label(shell, SWT.NONE);
		label.setText("Hello RAP World");
		shell.setSize(500, 400);
		shell.open();
		return 0;
	}
}

Note: Real-life applications should extend the new AbstractEntryPoint!

ApplicationConfiguration


public class HelloWorldConfig implements ApplicationConfiguration {
  public void configure( Application application ) {
    application.addEntryPoint( "/hello", HelloWorld.class, null );
  }
}
					

Run As... RWT Application

Standalone RWT Application

Start it from Eclipse without OSGi

Registering a RAP Application with OSGi

RAP on OSGi

RAP on OSGi

The Manual Way: In the Bundle Activator

public class Activator implements BundleActivator {
  ...

  public void start( BundleContext context ) throws Exception {
    ...
    Dictionary properties = new Hashtable();
    properties.put( "contextPath", "rapdemo" );
    registration 
      = context.registerService( 
            ApplicationConfiguration.class.getName(),
            new ExampleApplication(),
            properties 
            );
  }
			  	  

The OSGi Declarative Services Way

contribution.xml

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="BasicApplication">
   <implementation class="org.eclipse.example.rap.BasicApplication"/>
   <service>
      <provide interface="org.eclipse.rap.rwt.application.ApplicationConfiguration"/>
   </service>
</scr:component>

MANIFEST.MF

Service-Component: OSGI-INF/contribution.xml

...and do not forget to add and to start an OSGi DS bundle...

Registering a RAP Application with Blueprint

Very similar to the registration via DS

<blueprint 
  xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="...">

	<bean 
	  id="applicationConfiguration" 
	  class="com.eclipsesource.virgo.examples.rap.blueprint.HelloWorldConfiguration" />

	<service 
	  ref="applicationConfiguration" 
	  interface="org.eclipse.rap.rwt.application.ApplicationConfiguration" />

</blueprint>

RAP Application on Equinox and embedded Jetty

Jetty

Strategy: Start Equinox runtime together with more bundles.

  1. The org.eclipse.rap.rwt jar and
  2. The org.eclipse.rap.rwt.osgi jar and
  3. A implementation of ApplicationConfiguration and
  4. A implementation of EntryPoint
  5. Plus the Jetty bundles...
  6. Plus a number of Equinox OSGi Runtime bundles
  7. And: Your application bundles

Wiring of the Example Application

osgi> 
services org.eclipse.rap.rwt.application.ApplicationConfiguration

{org.eclipse.rap.rwt.application.ApplicationConfiguration}
  ={contextPath=rapdemo, service.id=34}
  
  "Registered by bundle:" 
    org.eclipse.rap.examples_2.1.0.qualifier [8]
  
  "Bundles using service"
    org.eclipse.rap.rwt.osgi_2.1.0.qualifier [1]

RAP Application as a .war in a Tomcat

Tomcat

Strategy: Wrap a OSGi Runtime in a .war

RAP on OSGi

RAP on OSGi

Inside a .war file

WEB-INF/
  web.xml
  launch.ini
  lib/
    org.eclipse.equinox.servletbridge_1.2.0.v20100201.jar
  plugins/
    org.eclipse.equinox.servletbridge.extensionbundle_1.2.100...jar
    org.eclipse.osgi_3.9.0.v20130305-2200.jar
    org.eclipse.osgi.services_3.3.100.v20130225-1645.jar
    org.eclipse.equinox.common_3.6.100.v20130225-1702.jar
    org.eclipse.equinox.http.registry_1.1.200.v20130225-1702.jar
    org.eclipse.equinox.http.servlet_1.1.300.v20130225-1702.jar
    org.eclipse.rap.rwt.osgi_2.1.0.20130220-2001.jar
    org.eclipse.rap.rwt_2.1.0.20130321-1447.jar
    org.eclipse.rap.examples_2.1.0.20130220-2001.jar
    org.eclipse.rap.examples.pages_2.1.0.20130309-0049.jar
    ...
			  	  

The web.xml

<servlet id="bridge">
    <servlet-name>equinoxbridgeservlet</servlet-name>
    <display-name>Equinox Bridge Servlet</display-name>
    <description>Equinox Bridge Servlet</description>
    <servlet-class>org.eclipse.equinox.servletbridge.BridgeServlet</servlet-class>
...

How to assemble a .war file

  • warproducts export from the IDE
  • Build integration into Tycho
    We are using Tycho in the RAP Examples:
    • A feature that defines the content, the web.xml, and ServletBridge
    • A .product that assembles the pieces and creates a .war

RAP Application in Karaf with Felix and PAX-WEB

Apache Karaf
  1. Download and install Karaf 3.x
  2. Download the RAP Karaf Feature from the RAP Incubator
    and put it into the deploy directory
  3. Write your RAP application bundle
    and put it into the deploy directory
  4. Karaf will manage the dependencies for you and install the required bundles

Deploying the RAP Examples into Karaf

RAP on OSGi

Inside the Karaf RAP Feature

Feature rap 2.0.0
Description:
  Eclipse RAP bundles
Feature depends on:
  http (2.0.0,4.0.0]
Feature contains followed bundles:
  mvn:org.eclipse.rap/jface/2.1.0-20130225-1108
  mvn:org.eclipse.equinox/common/3.6.100-v20130225-1702
  mvn:org.eclipse.core/jobs/3.5.300-v20130221-0103
  mvn:org.eclipse.rap/rwt/2.1.0-20130320-1454
  mvn:org.eclipse.rap.rwt/osgi/2.1.0-20130220-2001
  mvn:org.eclipse.core.databinding/property/1.4.200-v20130220-2151
  mvn:com.ibm.icu/base/50.1.0-v20121116-2
  mvn:org.eclipse.core/commands/3.6.100-v20130220-2151
  mvn:org.eclipse.rap.jface/databinding/2.1.0-20130220-2001
  mvn:org.eclipse.core/databinding/1.4.1-v20130220-2151
  mvn:org.eclipse.equinox/supplement/1.5.0-v20121210-201226
  mvn:org.eclipse.core.databinding/observable/1.4.1-v20130220-2151
  mvn:org.eclipse.core.databinding/beans/1.2.200-v20130220-2151

Available from the RAP Incubator project

RAP Application running on Virgo as a Web Application Bundle

Eclipse Virgo
  • Using the Virgo Jetty Server in this demo
  • Web Application Bundles import their dependencies via OSGi manifest metadata
    (whereas .war files include all dependencies in WEB-INF/lib)
  • Similar to Karaf example: Provide RAP application as a bundle

The Web-Bundle web.xml

<web-app 
  xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="..." version="2.4">

  <context-param>
    <param-name>o.e.rap.applicationConfiguration</param-name>
    <param-value>...webbundle.HelloWorldConfiguration</param-value>
  </context-param>

  <listener>
    <listener-class>o.e.rap.rwt.engine.RWTServletContextListener</listener-class>
  </listener>

  <servlet>
    <servlet-name>rwtServlet</servlet-name>
    <servlet-class>o.e.rap.rwt.engine.RWTServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>rwtServlet</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

The Web-Bundle MANIFEST.MF

Web-ContextPath: /helloworld

URL together with web.xml:

http://localhost:8081/helloworld/hello

Thank You!

Markus Knauer / @mknauer23, EclipseSource