I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

Riena - A New Adventure In Eclipse

03.31.2009
| 51440 views |
  • submit to reddit

Remote Services

Another big part of Riena is the way it handles remote services. In summary, Riena allows OSGi services to be accessible from outside of the current JVM by publishing the service as a web service endpoint. From the client side, remote access to the service is possible through a proxy registered as an OSGi service in the client VM. This proxy transports the request and response between client and server.

This example will provide a foreign exchange service to clients. The code for the "foreign exchange" service is very simple, using a POJO to do the work. Throughout this section of the article, we will be dealing with OSGi bundles, rather than standard Eclipse plugins.

First, we'll create a common OSGi bundle for both the client and server to reference. To create an OSGi bundle in Eclipse, you just create a standard plug-in project, but the target platform for the bundle should be Equinox, rather than an Eclipse version. 

 

The main content here is the interface for our ForeignExchange class. 

public interface IForeignExchange {

double convertDollarToEuro(double dollarAmount);
}

The only other detail we need to complete here is to open the bundle's manifest to add one dependency: org.eclipse.riena.communication.core.

Ensure that you export the package containing this interface so that it is visible to all other bundles.

Riena on the Server Side 

In our server bundle, we create an implementation of this class. First, we need to organise the dependencies of this bundle to be as follows:

 

 

public class ForeignExchange implements IForeignExchange{

public double convertDollarToEuro(double dollarAmount)
{
double euro = dollarAmount * 0.7513;
return euro;
}

}

 

Now let's take a look at the extra properties required to publish the OSGi service as a web service through Riena. To do this we need to go to the Activator of this bundle. 


public class Activator implements BundleActivator {
private ServiceRegistration foreignExchangeService;


public void start(BundleContext context) throws Exception {

Hashtable<String, String> properties = new Hashtable<String, String>(3);

properties.put(RSDPublisherProperties.PROP_IS_REMOTE, Boolean.TRUE.toString());
properties.put(RSDPublisherProperties.PROP_REMOTE_PROTOCOL, "hessian"); //$NON-NLS-1$
properties.put(RSDPublisherProperties.PROP_REMOTE_PATH, "/currency"); //$NON-NLS-1$

foreignExchangeService = context.registerService(IForeignExchange.class.getName(), new ForeignExchange(), properties);
}

public void stop(BundleContext context) throws Exception {
foreignExchangeService.unregister();
foreignExchangeService = null;
}

}

So, when the plugin is started, the path to this service will now be http://localhost/hessian/currency. If the plugin is stopped, the web service endpoint will also be unavailable.  The following diagram, taken from the Riena Getting Started documentation explains how this works.

Riena_RemoteService_on_Server.png

Riena on the Client Side

On the client side, we'll need to create a web service proxy, and register that as an OSGi service. This will allow the client to access the foreign exchange service on the server side. It's best practice to create a seperate bundle for this. In the Riena examples this is bundle ends with .client.config.

First, edit the manifest to include the necessary plugins. 

 

You'll also need to manipulate the Activator for this plugin in order to get the remote service registered. 

	private IRemoteServiceRegistration serviceReg;

/**
* Creates a RemoteServiceReferences based on Hessian protocol and registers
* this as "remote" OSGi Service
*/
public void start(BundleContext context) throws Exception {
// register hessian proxy for riena remote service
serviceReg = Register.remoteProxy(IForeignExchange.class).usingUrl("http://${riena.hostname}/hessian/currency")
.withProtocol("hessian").andStart(context);
}

/**
* unregister end release the "remote" OSGi Service
*/
public void stop(BundleContext context) throws Exception {
if (serviceReg != null) {
serviceReg.unregister();
serviceReg = null;
}
}

You'll need to export the package containing this activator in the Runtime/Exported Packages section of the manifest also.

A final point on what I have implementing on the  the .config bundle, is the use of the ${riena.hostname} variable. I could have simply used localhost:8080, but in the plugin.xml of this bundle, I have included the following value variable, which provides an initial value to the ${riena.hostname} variable.

<plugin>
<extension
point="org.eclipse.core.variables.valueVariables">
<variable
description="Name of the host to connect to"
name="riena.hostname"
readOnly="true"
initialValue="localhost:8080"/>
</extension>

</plugin>

 

 

Now, we should be able to get at the service through this bundle, just the same as calling any local OSGi service. Our fourth bundle, the Client, should only need to be dependent on the common bundle. 

The client Activator code goes something like this: 

 

	private BundleContext context;

public void start(BundleContext context) throws Exception {
this.context = context;

ServiceReference serviceRef = context.getServiceReference(IForeignExchange.class.getName());
if (serviceRef != null) {
IForeignExchange exchangeService = (IForeignExchange)context.getService(serviceRef);

System.err.println("Result of exchange: " + exchangeService.convertDollarToEuro(2.0));

} else {

context.addServiceListener(new ForeignExchangeClient(), "(objectClass=" + IForeignExchange.class.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
}

}

public void stop(BundleContext context) throws Exception {
this.context = null;
}

In this case we have added a Service listener, in case the service isn't ready when we first run. The code for the ForeignExchangeClient is quite simple: 

 

class ForeignExchangeClient implements ServiceListener {

public void serviceChanged(ServiceEvent event) {

ServiceReference serviceReference = event.getServiceReference();

IForeignExchange exchangeService = (IForeignExchange) context.getService(serviceReference);
if (exchangeService == null) {
return;
}
System.err.println("Result of exchange: " + exchangeService.convertDollarToEuro(2.0));

}


}

Time to test this out - to do this, we'll set up two different Run Configurations. As we are running OSGi bundles, rather than standard Eclipse plugins, your Configurations will appear under OSGi Framework rather than Eclipse Application in the Run Configurations dialog.

The server will run as follows: 

A good way of making sure you have the bundles you need here is to just select the server bundle first, and then just choose "Add Required Bundles". 

For the client, we'll do the same thing. Make sure you select the client.config bundle also.

Because we'll want to see the console output for this run, add in the -consoleLog parameter in the Arguments tab. 

All the source used in this example is available here for you to run. The following diagram shows the server bundle dependencies: 


And the client bundle dependencies: 

 

Summary

The following is a summary of the main steps behind providing remote services using Riena

  • The server can be run anywhere. In the Activator of the service, you will need to provide a URL to the service. Most importantly you will need to register your service.
  • The client.config class does the work of registering the remote service for access on the client side.
  • The client will get the service reference as if it was a local OSGi bundle.

Riena gives Eclipse a new edge, with it's different approach to user interfaces, and the flexible implemenation of remote services. Over the next few weeks I'll be looking at Riena more closely. As you can see from the list at the start of the article, covering UI and Remote Services only scratches the surface of what Riena can provide for Eclipse developers.

 

Legacy
Article Resources: 

Comments

Christopher Brind replied on Tue, 2009/03/31 - 3:51am

Great stuff.  Wasn't aware of Rienna, but I am definatlely putting this on my hot list.  Thanks for the info.

Tom Meier replied on Tue, 2009/03/31 - 6:33am

Nice article, James. Rienna looks quite nice and looks like it's making life for us RCP developers a lot easier. However I think there's one big disadvantage to Rienna: Again we're relying on a different framework for multiple application layers such as services and UI. On the other hand an all-in-one solution such as seems to be good enough for small to mid-sized applications. I'm curious as to see whether this framework finds its place among all the other frameworks in the Java world.

Nevertheless a great article and surely looks like you spent a bit of time here :) Keep up the good work!

Tom

James Sugrue replied on Tue, 2009/03/31 - 7:05am in response to: Tom Meier

Thanks Tom

I see what you mean, and it has crossed my mind that this is another approach to the same problem. But I think projects in Eclipse work closely enough, and that there could be some crossover with what Riena does and what ECF provides in remote services.  I'm sure we'll see one recommended approach to remote services soon enough, at least in the Eclipse community 

 James

Slim Ouertani replied on Tue, 2009/03/31 - 11:03am

Great project and article. I started a small developing a small kernel using Hessian and Osgi transparently. So where can I get source code ? :)
 

James Sugrue replied on Tue, 2009/03/31 - 11:05am in response to: Slim Ouertani

Thanks Slim!

Should appear just at the bottom of the article : http://java.dzone.com/sites/all/files/RienaExample.zip

 

Denis Robert replied on Tue, 2009/03/31 - 1:32pm

Have you tested your code? There's a reference there to a "org.eclipse.riena.communication.core.factory.Register" class which I can't find anywhere, and certainly not in the "org.eclipse.riena.communication.core" bundle where I'd expect it to be. Or are you using non-release level code?

Elias Volanakis replied on Tue, 2009/03/31 - 2:04pm

Works for me using the Riena 1.1.0.M6 download. HTH, Elias.

Ekkehard Gentz replied on Tue, 2009/03/31 - 2:20pm in response to: Tom Meier

tom, you're not relying to a complete framework if using Riena. You can choose what you like: remote services from Riena ... or ECF or another one UI complete from Riena or only the Ridgets in normal RCP Views. Riena is completely build as an OSGI client-server solution and you can use and combine the bundles as you like it. so you can start perhaps with remoting and your current RCP app or you start using Ridgets to make your life with SWT Widgets and Eclipse Databinding easier. ekke

Slim Ouertani replied on Tue, 2009/03/31 - 5:40pm in response to: James Sugrue

Thanks, but I speak about Riena source code. Is it possible to get it?

James Sugrue replied on Wed, 2009/04/01 - 1:38am in response to: Denis Robert

Hi Denis

 I ran this using Gailileo 3.5M6 and the latest release  of Riena. All fully tested 

James

James Sugrue replied on Wed, 2009/04/01 - 1:44am in response to: Slim Ouertani

You should be able to get it on the Eclipse CVS repository. It's an RT project so will be under /cvsroot/rt/org.eclipse.riena/

Roman Porotnikov replied on Wed, 2009/04/01 - 4:55am

UI wizard update site URL at Riena wiki: fixed.

Gavin Mogensen replied on Sun, 2009/04/12 - 10:14pm

Nice - thanks for the article

James Ervin replied on Thu, 2009/04/30 - 10:20am

You know this is just like a project I worked on a few years ago, well at least the OSGi service publishing part. It makes me wonder though, how hard would it be to leverage this through Spring DM? Spring DM is meant to do all the stuff about registering the service and getting access to it (all the things you are doing with the BundleContext) and handle it for you, making use of DI. In fact, this is probably so obvious that it is already being done somewhere, I am just not aware of it.

James Sugrue replied on Thu, 2009/05/14 - 2:14am in response to: James Ervin

Interesting point James - it should be possible in Spring DM. I haven't seen it with DM yet.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.