Eclipse Yoxos Services Downloads Blogs About
Home > Blogs >

Posts Tagged ‘OSGi’

on Jan 23rd, 2012An OSGi JAX-RS connector Part 1: Publishing REST services

In a recent blog post Peter Kriens commented that the OSGi service model is as important as object-orientation. I feel the same – I don’t want to write software without this concept anymore. But for me, the service model only makes sense when it’s used together with the modularity OSGi provides. I think the modularisation layer is the greatest advantage of the OSGi platform and the services are really only there to simplify the communication between modules.

When it comes to developing a REST API with Java, this advantage is missing in most of today’s libraries (e.g. Restlet or Jersey), because the Java language still lacks modularity. But especially for the design of a REST API this concept can be a great benefit, because it overcomes the limitation of only being able to separate REST services by url and Java packages. With modularity the service implementations can be separated into modules which improves the maintainability and the beauty of the whole system a lot.

A few months ago I discovered JAX-RS for developing REST services. (Before that I used Restlet.) I have to say that the JAX-RS API makes it really easy to develop REST services. See this article for a how-to. A reference implementation of this API is Jersey. The cool thing about this implementation is that it plays really well together with the OSGi HttpService and it ships as bundles. In this way we have the option to actively deploy REST services into the HttpService. But is this how we want to publish REST services? To me, it’s not!

In my ideal world I would write my @Path annotated Pojos and publish them as OSGi services. That’s it. The runtime should take care of publishing and service wiring. Sadly, Jersey has no built-in feature for that. This is the reason I wrote a little OSGi-JAX-RS connector. The only thing the connector does is that it publishes OSGi services as REST services using JAX-RS. Of course, there are OSGi remote services, but using them does not allow the use of JAX-RS the way I’d prefer, namely as a lightweight additional bundle.

You can find the connector in GitHub. To make it work simply install it into your OSGi instance by using this jar. (You’ll also find a p2 repository there). That’s it. The only thing you have to take care of is writing the REST services like the one in this example.

@Path( "/osgi-jax-rs" )
public class ExampleService {
 
  @GET
  public String seyHello() {
    return "JAX-RS and OSGi are a lovely couple.";
  }
}

The activator can then look like this:

public class Activator implements BundleActivator {
 
  private ServiceRegistration<?> registration;
 
  @Override
  public void start( BundleContext context ) throws Exception {
    ExampleService exampleService = new ExampleService();
    registration = context.registerService( ExampleService.class.getName(), exampleService, null );
  }
 
  @Override
  public void stop( BundleContext context ) throws Exception {
    registration.unregister();
  }
}

Further instructions can be found in the README of the git repository. It also contains two examples for using this connector with and without declarative services. In the second part of this blog series I will show you how to configure the services using the OSGi Configuration Admin Service and publish services on different ports within the same OSGi instance. I hope you enjoy this connector as much as I do.

followme An OSGi JAX RS connector Part 1: Publishing REST services

on Nov 14th, 2011Introducing restfuse – a JUnit Extension to test REST APIs

For several projects at EclipseSource we are creating REST APIs. I’m involved in most of them and there is one thing that bothers me with every project. That is, testing. I mean, of course we are writing our unit tests first and we mock our services to get fast unit tests, but at some point you also have to make sure that the whole system works with integration tests. And, when writing integration tests for REST APIs in Java, as far as I know, there are currently only two solutions.

The first one is to write plain JUnit tests and do all the requests yourself within the test methods (maybe with the help of utilities). The other option is to use a library called rest-assured. This library provides a kind of DSL for testing REST APIs. You can write your tests with JUnit and use mockito-like syntax to send a request and test the response. But this doesn’t feel like the right solution, because you always have to configure your request with real Java code within your test method. I would prefer a solution where I can simply configure the request using something like annotations and just execute the test after the request is sent.

Another thing that bugs me are asynchronous services. When it comes to handling asynchronous services you always have two options: callbacks or polling. How can I test those services? For polling it’s easier – you can loop the request code – but does this sound right to you? For callbacks you have to open a server, again within your test method or before. It seems there are no cool solutions for this right now – even rest-assured can’t handle these services very well. That’s why I took a little time and tried to solve these problems. The result is a small library called restfuse.

Restfuse is a JUnit extension. It introduces an annotation called @HttpTest which can be used to configure a request. The request is sent before the annotated method is executed as a test method. The response is then injected into the test object and can be used within the test method. It also provides some new asserts like assertNotFound or assertOk to test response codes. A simple @HttpTest looks like this:

@RunWith( HttpJUnitRunner.class )
public class RestfuseTest {
 
  @Rule
  public Destination destination = new Destination( "http://restfuse.com" ); 
 
  @Context
  private Response response; // will be injected after every request
 
  @HttpTest( method = Method.GET, path = "/" )
  public void checkRestfuseOnlineStatus() {
    assertOk( response );
  }  
}

And of course, it also solves the problem with asynchronous services by introducing two annotations called @Callback and @Poll which can be used together with the @HttpTest annotation. For more information on these tests for asynchronous services take a look at the restfuse site.

Restfuse is open source, licensed under the EPL v – 1.0 and is hosted at github. The 1.0 version is also in the Maven Central and online as a p2 repository (yes, it’s an OSGi bundle).  I hope this small library will help you as much as it helped me. I would appreciate feedback on how to make restfuse even better.

followme Introducing restfuse   a JUnit Extension to test REST APIs

on Aug 29th, 2011Lightweight OSGi Applications using RAP’s Widget Toolkit

RAP is well known as an “RCP for the web browser”, including workbench, extension points, and all that stuff. Indeed, one of the greatest features of RAP is its ability to reuse RCP code in web applications. But did you know that you can also use RAP’s widget toolkit (RWT) to create simple web UIs for your applications, without the heavy weight Eclipse UI stack?

With RAP 1.5, you can now simply include RWT in any OSGi application. You only need two bundles: org.eclipse.rap.rwt (the RAP widget toolkit itself) and org.eclipse.rap.rwt.osgi which integrates RWT with the OSGi HTTP service. There are no tie-ins with Equinox anymore, thus RAP also works with other OSGi containers.

To create a UI with RWT, you have to implement the interface IEntryPoint, here’s a simple example:

  public int createUI() {
    // Create a maximized top-level shell without trimmings that represents the main "page"
    Display display = new Display();
    Shell page = new Shell( display, SWT.NO_TRIM );
    page.setMaximized( true );
    page.setLayout( new GridLayout() );
 
    // Create contents of main shell
    Label label = new Label( page, SWT.NONE );
    label.setText( "Hello" );
    Button button = new Button( page, SWT.PUSH );
    button.setText( "World" );
 
    // Open the top-level shell and run the main loop to process events
    page.layout();
    page.open();
    while( !page.isDisposed() ) {
      if( !display.readAndDispatch() ) {
        display.sleep();
      }
    }
    display.dispose();
    return 0;
  }

Now what’s new is that, instead of registering this entry point with an extension point, you can now implement the new Configurator interface like this:

  public void configure( Context context ) {
    context.addEntryPoint( "default", SimpleEntryPoint.class );
    context.addBranding( new AbstractBranding() {
      @Override
      public String getServletName() {
        return "simple";
      }
      @Override
      public String getTitle() {
        return "Simple RWT Example";
      }
    } );
  }

When this implementation is registered as an OSGi service, you can access the UI with a web browser:

RWTSimple Lightweight OSGi Applications using RAPs Widget Toolkit

You can check out the example project example.rwt.simple from my rap-helpers repository on github. Please note that for this example to run you need declarative services in your target platform, which are not included in the RAP 1.5M1 target but in the latest nightly build. Also be aware that the new API is still provisional and may change again until the final release.

Kudos to Frank Appel, who contributed the new OSGi integration. He has a more detailed introduction to the new OSGi integration and examples for configuration in his blog. BTW, Frank and me plan to demo the possibilities of this approach in our talk Dynamic web applications with OSGi and RAP at the EclipseCon Europe – vote for it if you’re interested!

on Aug 12th, 2011How to build a cluster with Jetty / OSGi

In this blog post I describe how to set up a cluster node with an embedded Jetty Server inside Equinox.

Basically I followed the instructions available at the Jetty Wiki page Session Clustering Using a Database [1].

There are two Jetty configuration files involved:

  • /etc/jetty.xml defining a JDBCSessionIdManager
  • /WEB-INF/jetty-web.xml defining a JDBCSessionManager

The main jetty.xml resides in the folder etc of the jetty.home.bundle which itself is a fragment of org.eclipse.jetty.osgi.boot. The jetty.osgi.boot bundle is provided by the Jetty team and is responsible for bootstrapping Jetty in an OSGi environment.

The main configuration file contains the JDBCSessionIdManager definition using a H2 database:

 <Set name="sessionIdManager">
  <New id="jdbcidmgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager">
    <Arg>
      <Ref id="Server" />
    </Arg>
    <Set name="workerName">
      <SystemProperty name="worker.name" default="primary" />
    </Set>
    <Call name="setDriverInfo">
      <Arg>org.h2.Driver</Arg>
      <Arg>jdbc:h2:tcp://localhost:9101/sessions</Arg>
    </Call>
    <Set name="scavengeInterval">60</Set>
  </New>
</Set>
<Call name="setAttribute">
  <Arg>jdbcIdMgr</Arg>
  <Arg>
    <Ref id="jdbcidmgr" />
  </Arg>
</Call>

Note: To reuse the configuration in multiple cluster nodes I use a SystemProperty tag to give every node a unique “worker.name”. The database configuration is hardwired to a local H2 database.

With additional system properties I can tell the Jetty bootstrapper where to look for the global Jetty configuration and which port the Jetty instance should bind to:

-Dworker.name=primary
-Djetty.port=18081
-Djetty.home.bundle=com.eclipsesource.cluster.jetty.home.bundle

To enable the Jetty server to load the H2 database drivers I added a dynamic import directive via the fragment org.eclipse.jetty.serverdynamic.import:

Fragment-Host: org.eclipse.jetty.server;bundle-version="7.4.2"
DynamicImport-Package: *

The web application specific configuration /WEB-INF/jetty-web.xml is located in the web bundle, com.eclipsesource.cluster.jetty.demo.webbundle. This configuration file contains the JDBCSessionManager definition.

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Get name="server">
    <Get id="jdbcIdMgr" name="sessionIdManager" />
  </Get>
  <Set name="sessionHandler">
    <New class="org.eclipse.jetty.server.session.SessionHandler">
      <Arg>
        <New class="org.eclipse.jetty.server.session.JDBCSessionManager">
          <Set name="idManager">
            <Ref id="jdbcIdMgr" />
          </Set>
        </New>
      </Arg>
    </New>
  </Set>
</Configure>

Note: “jdbcIdMgr” is a Reference to the jetty.xml from jetty.home.bundle.

If you want to try it out yourself, the code is available at GitHUB [2].

Note: The bundle com.eclipsesource.cluster.h2 contains an Eclipse launch configuration to start a local H2 database which is needed to run the example.

[1] http://wiki.eclipse.org/Jetty/Feature/Session_Clustering_Using_a_Database
[2] https://github.com/eclipsesource/com.eclipsesource.cluster

on Aug 10th, 2011How to extend the Virgo Jetty Server to support the RAP Widget Toolkit

First, a bit of news for developers following the Virgo project:  The release day for Virgo Maya is getting closer[1] with the successful RC1 release a few weeks ago.

Meantime, in this blog post I’ll describe another way of running RWT (the RAP Widget Tookit) based applications on the Virgo Jetty Server. I want to use Virgo’s RFC66 support to deploy web applications in OSGi.
The RFC66 Web Container specification creates an open standard that enables developers to deploy WAR files on OSGi. With a few modifications (see below) it is possible to deploy an RWT standalone application into an RFC66 container like Virgo.

Note: In addition to using the HttpService described here[2] with RAP 1.5 you can register RWT directly with an OSGi HTTP service. We’ll describe this in a follow-up post.

To extend Virgo you need to:

  1. Get a Virgo Jetty Server Release Candidate[3].
  2. Install our extension of Virgo as suggested here[4] into /repository/ext.

Note: You can get a patched RWT bundle here that  supports RFC66 deployment of RWT applications and the plan here. The Virgo deployment plan describes all bundles needed to support RWT applications in Virgo.

Copy the two downloaded artifacts into repository/ext:

~virgo-jetty-server> ls -1 repository/ext/*rwt*
repository/ext/org.eclipse.rap.rwt-1.5.0.plan
repository/ext/org.eclipse.rap.rwt_1.5.0.201108081102.jar

Next I added our RWT extension to the initial Virgo artifacts. This is configured in
config/org.eclipse.virgo.kernel.userregion.properties. We simply add our plan:

initialArtifacts=repository:plan/org.eclipse.virgo.kernel.userregion.springdm,\
         repository:plan/org.eclipse.virgo.jetty.web,\
         repository:plan/org.eclipse.rap.rwt

That’s all that has to be done on the Virgo side. If you start Virgo Jetty Server you should
see the extension starting properly:

[2011-08-08 12:23:45.909] system-artifacts              Installing plan 'org.eclipse.rap.rwt' version '1.5.0'.
[2011-08-08 12:23:47.626] system-artifacts              Installing bundle 'org.eclipse.rap.rwt' version '1.5.0.201108081102'.
[2011-08-08 12:23:47.663] system-artifacts              Installed bundle 'org.eclipse.rap.rwt' version '1.5.0.201108081102'.
[2011-08-08 12:23:47.665] system-artifacts              Installed plan 'org.eclipse.rap.rwt' version '1.5.0'.
[2011-08-08 12:23:47.725] system-artifacts              Starting plan 'org.eclipse.rap.rwt' version '1.5.0'.
[2011-08-08 12:23:47.729] system-artifacts              Starting bundle 'org.eclipse.rap.rwt' version '1.5.0.201108081102'.
[2011-08-08 12:23:47.734] start-signalling-2            Started bundle 'org.eclipse.rap.rwt' version '1.5.0.201108081102'.
[2011-08-08 12:23:47.737] start-signalling-2            Started plan 'org.eclipse.rap.rwt' version '1.5.0'.

Because an RWT standalone application doesn’t know about OSGi classloading, I thought that one solution might be to use buddy classloading. First, I enabled buddy classloading in org.eclipse.rap.rwt.

Bundle-SymbolicName: org.eclipse.rap.rwt
Bundle-Version: 1.5.0.qualifier
...
Eclipse-BuddyPolicy: registered

Then I registered the RWT application com.eclipsesource.sovereign.swt.layout.web as a buddy:

Bundle-SymbolicName: com.eclipsesource.sovereign.swt.dialog
...
Require-Bundle:
 org.eclipse.rap.rwt
Export-Package: com.eclipsesource.sovereign.swt.dialog
Eclipse-RegisterBuddy: org.eclipse.rap.rwt
Web-ContextPath: /rap

Note: In the MANIFEST.MF of the web bundle we specified the context path to “/rap”.

Next I setup the RAP web application. The web.xml almost looks like that of a standard RWT standalone application. For more details please go to the RAP Wiki [5]:

<context-param>
  <param-name>org.eclipse.rwt.entryPoints</param-name>
  <param-value>com.eclipsesource.sovereign.swt.dialog.SwtDialogEntryPoint</param-value>
</context-param>
<listener>
  <listener-class>org.eclipse.rwt.internal.engine.RWTServletContextListener</listener-class>
</listener>
 
<servlet>
  <servlet-name>rwtDelegate</servlet-name>
  <servlet-class>org.eclipse.rwt.internal.engine.RWTDelegate</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>rwtDelegate</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

You’ll see an additional section for the RWT resources:

<servlet>
  <servlet-name>rwtResources</servlet-name>
  <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>rwtResources</servlet-name>
  <url-pattern>/rwt-resources/*</url-pattern>
</servlet-mapping>

Now I was ready to deploy my RAP application. I simply copied the webbundle into Virgo’s pickup folder.

Note: You can get the sample RAP webbundle here.

[2011-08-08 12:25:34.421] fs-watcher                    Hot deployer processing 'CREATED' event for file 'com.eclipsesource.sovereign.swt.dialog_0.1.0.201108081127.jar'.
[2011-08-08 12:25:34.476] fs-watcher                    Installing bundle 'com.eclipsesource.sovereign.swt.dialog' version '0.1.0.201108081127'.
[2011-08-08 12:25:34.486] fs-watcher                    Installed bundle 'com.eclipsesource.sovereign.swt.dialog' version '0.1.0.201108081127'.
[2011-08-08 12:25:34.492] fs-watcher                    Starting bundle 'com.eclipsesource.sovereign.swt.dialog' version '0.1.0.201108081127'.
[2011-08-08 12:25:34.494] start-signalling-3            Started bundle 'com.eclipsesource.sovereign.swt.dialog' version '0.1.0.201108081127'.

And the application is available at localhost:8080/rap

[1] Virgo 3.0 (Maya) Release Candidate 1
[2] Running RAP on Virgo
[3] Milestone Downloads
[4] Extending Virgo with a HttpService
[5] How do I use an RWT standalone application in Tomcat

on Jul 18th, 2011RAP on the Maven Central Repository

Have you ever heard about RWT standalone?  RWT standalone applications use the widget toolkit of RAP called RWT for their user interface.  These applications can be standard Java applications with no need to create an OSGi based application.

For Java applications it can be quite challenging to find the required dependencies but Maven can help here. And, to make the life easier for RWT standalone developers, we contributed the RAP bundles and the dependencies needed for a RWT standalone application to the Maven Central Repository. To find the RAP bundles in the Maven Central Repository just search for “org.eclpse.rap”.

mvc RAP on the Maven Central Repository

To try it yourself,  I recommend that you download the latest Eclipse for RCP and RAP Developers package from here. Then you can install the Eclipse Maven Integration into your IDE from here.  After that you can import the example project into your IDE. The example project contains a launch configuration which you can start with the RWT-Launcher included in the RCP and RAP Developers package.

on Jul 13th, 2011Building OSGi applications that use AspectJ with Tycho / Maven 3

I just pushed a template for creating AspectJ applications with Tycho and will give you a quick tour of it here. You’ll find the template on github [1]

The template contains four infrastructure projects. One defines an OSGi command to calculate faculties and another contains an aspect to measure the duration of the calculation.

Let’s take a closer look. com.eclipsesource.weaving.demo.releng contains the Maven parent pom.xml file which defines the modules of the application:

<groupId>com.eclipsesource.sandbox.weaving.demo</groupId>
<artifactId>com.eclipsesource.sandbox.weaving.demo.parent</artifactId>
<version>0.1.0-SNAPSHOT</version>
 
<packaging>pom</packaging>
...
<modules>
 <module>../platform</module>
 
 <module>../weaving.demo.chronometry</module>
 <module>../weaving.demo.faculty</module>
 <module>../weaving.demo.feature</module>
 
 <module>../repository</module>
</modules>

com.eclipsesource.weaving.demo.platform – contains the target definition

weaving demo target Building OSGi applications that use AspectJ with Tycho / Maven 3

com.eclipsesource.weaving.demo.feature – defines the application scope

weaving demo feature Building OSGi applications that use AspectJ with Tycho / Maven 3

com.eclipsesource.weaving.demo.repository contains the product definition. One very important VM argument, almost hidden from the debug arguments, registers the framework weaving extension:

-Dosgi.framework.extensions=org.eclipse.equinox.weaving.hook

weaving demo arguments Building OSGi applications that use AspectJ with Tycho / Maven 3

The weaving service has to be started early.

weaving demo startlevel Building OSGi applications that use AspectJ with Tycho / Maven 3

As well as the four infrastructure projects, the template contains the application code:
com.eclipsesource.weaving.demo.faculty – provides an OSGi console command to calculate faculty.

public class FacultyCommandProvider implements CommandProvider {
 
  public void _faculty(CommandInterpreter ci) {
    String argument = ci.nextArgument();
    int argumentAsInteger = Integer.valueOf(argument).intValue();
    System.out.println("Faculty of " + argumentAsInteger + " is "
          + recur(argumentAsInteger));
  }
...

com.eclipsesource.weaving.demo.chronometry – contains the Aspect to measure the faculty execution time.

public aspect CommandProviderChronometer {
  void around(CommandInterpreter ci):
        execution(void CommandProvider+._faculty(CommandInterpreter))
          &amp;&amp; args(ci) {
    long start = System.nanoTime();
    proceed(ci);
    long duration = System.nanoTime() - start;
    System.out.println("Result calculated in " + (duration / 1000) + " micro seconds");
  }
}

The following snippet from the project’s pom.xml file tells Tycho to use the aspectj compiler:

...
<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>aspectj-maven-plugin</artifactId>
      <version>1.3.1</version>
      <configuration>
        <verbose>true</verbose>
        <complianceLevel>1.5</complianceLevel>
     </configuration>
     <executions>
       <execution>
        <goals>
          <goal>compile</goal>
        </goals>
      </execution>
    </executions>
 </plugin>
 </plugins>
</build>
...

We build the application the Tycho way, from the command line with Maven 3.x:

> cd releng
> mvn package
...
[INFO] --- tycho-p2-director-plugin:0.12.0:archive-products (archive-products) @ com.eclipsesource.sandbox.weaving.demo.repository ---
[INFO] Building zip: .../weaving.demo_...-macosx.cocoa.x86_64.zip
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] com.es..weaving.demo.parent ..... SUCCESS [0.002s]
[INFO] com.es..weaving.demo.platform ... SUCCESS [0.269s]
[INFO] com.es..weaving.demo.faculty .... SUCCESS [1.995s]
[INFO] com.es..weaving.demo.chronometry  SUCCESS [0.482s]
[INFO] com.es..weaving.demo.feature .... SUCCESS [0.533s]
[INFO] com.es..weaving.demo.repository . SUCCESS [7.262s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

We can now unzip the artifact and launch the application:

> unzip weaving.demo_selfcontained-macosx.cocoa.x86_64.zip
> Eclipse.app/Contents/MacOS/eclipse

The following output shows that weaving was successful:

osgi> [org.eclipse.equinox.weaving.aspectj] info Starting AspectJ weaving service ...
...
[com.eclipsesource.weaving.demo.faculty] info register aspect com.es..CommandProviderChronometer
[org.eclipse.equinox.weaving.aspectj] info weaving bundle 'com.eclipsesource.weaving.demo.faculty'
[com.eclipsesource.weaving.demo.faculty] weaveinfo Join point 'method-execution(void com.es..FacultyCommandProvider._faculty(org.eclipse..CommandInterpreter))'
in Type 'com.es..FacultyCommandProvider' (FacultyCommandProvider.java:9)
advised by around advice from 'com.es..CommandProviderChronometer' (CommandProviderChronometer.aj:8)

Running the OSGi console command shows the measurement in action:

osgi> faculty 23
Faculty of 23 is 862453760
Result calculated in 1165 micro seconds

[1] https://github.com/eclipsesource/com.eclipsesource.tycho.aspectj.demo

on Jul 8th, 2011Single-Sourcing with declarative services

In my last blog post I introduced the idea of using OSGi services for single sourcing a RAP/RCP application. I think this approach is quite elegant, but it has one major drawback. When you use normal OSGi services in your application you will mix your application code with the OSGi Framework code everytime you reference or register a service. Not only does this look ugly, it’s also hard to test.

Luckily there is a lifesaver called Declarative Services. (For those of you who are familiar with declarative services, skip to the next paragraph.) The OSGi declarative services (ds) are specified in the OSGi compendium so they are standardized. It’s just a component framework on top of OSGi services. It gives you the ability to register and consume services in a declarative way using some xml files and simple accessors in your classes.

I’ll take the same example from in my last blog post and use it to look at ds for single sourcing.  In that blog, we single sourced a themed button widget.  We can use the same interfaces and service implementations, and the only differences will be how the services will be registered and referenced.

First, let’s take a look at the service registration. In our example we need to register the services in the rap and rcp bundles. It’s common practice to put all service declarations in a folder called OSGI-INF in the root of your project. Once you’ve created this folder you can create a “component definition” using the wizard. After this you need to fill in three things: first, the filename of your choice, second, the component name which needs to be unique in the framework and third, the component itself.

componentWizard Single Sourcing with declarative services

The component is the fully qualified classname of your implementation. In the case of service registration, it’s your service implementation. To add the service registration, press ‘Finish’ to open the component editor. We only want to register a service, so we jump to the service tab. In the bottom section you can add the service interface.

To understand what happens in the background let’s recap what we have declared. We defined a service interface, a service implementation, a component name and a filename. The component framework takes care of instantiating the service implementation and registering it as a service using the service interface. It registers the component using the component name. The filename will be automatically added to your bundle’s manifest. That’s all, the next time we start this bundle the service will be registered. Your component definition should look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="com.eclipsesource.app.rap.service.provider">
   <implementation class="com.eclipsesource.app.rap.RAPSingelSourcingService"/>
   <service>
      <provide interface="com.eclipsesource.app.ISingleSourcingService"/>
   </service>
</scr:component>

Now we get to the service referencing. As you recall, we need to reference the service in our app bundle. Therefore, we need to create a component in this bundle too. In this example I decided to reference the service in the bundle’s activator and provide it with a static accessor. But you can reference it wherever you want. In this case the component is our Activator. The only difference to the service registration is in the service tab of the component editor. Instead of providing a service, we are now referencing one. You can do this by clicking ‘Add’ in the upper section of this tab.

serviceReferencing Single Sourcing with declarative services

After this you need to declare the Interface of the service you want to reference, in our case the ISingleSoucingService. The question is now, “how does this service finds its way to the Activator?” The answer is binding methods. In the reference you can specify a bind and an unbind method e.g. setService and unsetService. You need to add these methods to your activator with the service as a parameter. That’s all – we are referencing the service now. Your component should look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true" name="com.eclipsesource.app.servic.consumer">
   <implementation class="com.eclipsesource.internal.app.Activator" />
   <reference bind="setSingleSourcingService" cardinality="1..1" interface="com.eclipsesource.app.ISingleSourcingService" name="ISingleSourcingService" policy="dynamic" unbind="unsetSingleSourcingService"/>
</scr:component>

The last thing we need is a little bit of glue to bring these components together. The glue is in the org.eclipse.equinox.ds bundle. This bundle contains the component framework implementation, and to make everything work together you need to add this bundle to your launch configuration. It’s not included in the RAP target components, but you can download it using the Indigo release site or the Equinox SDK.

I added a branch called “ds” to the repository on github from the last blog. This branch represents an example implementation using ds for single sourcing.

Have fun declaring services icon wink Single Sourcing with declarative services

on Jun 20th, 2011Using OSGi services to single-source an RCP and RAP Application

Probably one of RAP’s best known features is its single-sourcing capabilities. Some time ago we created a guide on Single-Sourcing RCP and RAP applications. The guide recommended a technique where a facade and fragments were used to invoke the RCP or RAP implementation during runtime. With this post I want to show you how to achieve the same the OSGi way.

For single-sourcing a RAP or RCP application, its straightforward to use the power of OSGi because it’s included in both platforms out-of-the-box. OSGi has a central concept called services which are simply POJOs and are used to allow communication between modules. And, you can register or resolve services at any time in your code.

The basic Idea behind using OSGi services for single-sourcing is as follows. We need to extract all the things that vary into separate, platform specific bundles. To use the different implementations, we have to create an interface in a “common” bundle that contains the methods we want to use. The platform specific bundles have to register an implementation of this interface as a service. In the “common” bundle we can reference the registered services and use them to get the platform specific stuff. More specifically, we register a RAP implementation in a “rap” bundle and an RCP implementation in an “rcp” bundle. The only thing we need to do then is to start the right bundles on the associated platform to get the right service.

With this solution we can extract the platform specific stuff into separate bundles and we don’t have to rely on fragments. So enough talking. Let’s look at some code. I decided to create a very simple single-sourcing interface which can be used to get the WidgetUtil.CUSTOM_VARIANT constant value. This constant exists only in RAP so, it’s a good example for showing how to handle the differences.

public interface ISingleSourcingService {
  String getCustomVariantString();
}

I have created three bundles: one that contains the application which is entitled “com.eclipsesource.app” and one for each platform. These are called “com.eclipsesource.app.rap” and “com.eclipsesource.app.rcp”. Both platform bundles implement the interface.
RAP:

  @Override
  public String getCustomVariantString() {
    return WidgetUtil.CUSTOM_VARIANT;
  }

RCP:

  @Override
  public String getCustomVariantString() {
    // There are no custom variants in RCP
    return "";
  }

And both bundles are registering the service in their Activator during the start method call.

  public void start( BundleContext bundleContext ) throws Exception {
    Activator.context = bundleContext;
    registration = context.registerService( ISingleSourcingService.class.getName(),
                                            new RAPSingelSourcingService(),
                                            null);
  }

When it comes to using the service in the common “app” bundle we can use a ServiceTracker to get the service implementation (you can also use DS).

  private ISingleSourcingService getSingleSourcingService() {
    // We use a tracker to get the service. We also can use DS to get it.
    Bundle bundle = FrameworkUtil.getBundle( getClass() );
    BundleContext context = bundle.getBundleContext();
    ServiceTracker tracker
      = new ServiceTracker( context,
                            ISingleSourcingService.class.getName(),
                            null );
    tracker.open();
    ISingleSourcingService service = tracker.getService();
    tracker.close();
    return service;
  }

The only thing we have to do now is to create two launch configurations which contain the associated platform-specific bundle.

That’s it! You can find the sources in this github repository. Have fun using OSGi services to single-source applications.

 

on May 4th, 2011Launch an OSGi app and automatically kill its running instance

If you use Eclipse to develop OSGi based applications you may use the OSGi Launcher provided by the PDE Tooling. It’s cool tooling because it gives you full control over the OSGi instance to be launched.  You can choose the OSGi framework (e.g. Equinox or Felix), select the bundles to install and much more.

But this launcher has one drawback that hurts every time I run across it. It appears when an OSGi application uses the OSGi HttpService. When you used this service you may have configured a port for it via the property “org.osgi.service.http.port” VM Argument.  I use this configuration all the time.

When I launch the application everything works fine the first time. But, during development I often come to the point where I need to relaunch the application. When I forget to kill the previous running instance I get a java.net.BindException because the address is already in use. So, to fix this I have to kill both instances and launch it again. This happens to me a lot just because I forget to terminate the previous instance. Of course this isn’t a bug because it’s often useful to launch a second instance of the same configuration. But, not when it comes to developing with the HttpService.

bindException Launch an OSGi app and automatically kill its running instance

There is a fix now (though not necessarily for my forgetfulness icon wink Launch an OSGi app and automatically kill its running instance ).  Luckily we live in a modular world in Eclipse. As a result, I was able to develop a separate bundle called the “OSGi Eliminator” (what a descriptive name icon smile Launch an OSGi app and automatically kill its running instance ). The bundle contributes the functionality to automatically terminate a running OSGi Instance when you try to launch the same instance a second time. This functionality already existed in the RAP launcher created by Rüdiger Hermann. All I did was to refactor the functionality out to make it run in a separate bundle and contribute to the OSGi Launcher instead of the RAP Launcher. This solves an annoying problem for me – maybe for you as well?

You can find this bundle on GitHub. I also created a p2 repository that lets you install the OSGi Eliminator directly into Eclipse.

© EclipseSource 2008 - 2011