Tuesday, February 2, 2010

Working with OSGi: The stuff you need to know

I am presenting a tutorial at EclipseCon 2010 with Paul VanderLei and Jeff McAffer that is based on the contents of our soon to be published OSGi and Equinox book.

I'm speaking at EclipseCon 2010

The conference runs from Monday 22nd March until the 25th. We hear that there will be plenty of copies of the book available, so be sure to pick one up while you're there!

Friday, November 27, 2009

Safari Updated!

The manuscript for our OSGi and Equinox book has been updated on Safari. The manuscript is now in the hands of the publisher and is due to be on shelves at the start of 2010. Too late for Christmas, but not for EclipseCon.

Tuesday, December 30, 2008

Truth, Technology and People

I'm reading an excellent novel, which was written in 1957, that contains the following interesting quote that caught my eye:
"It is only in the realm of pure science that truth is an absolute criterion. When we deal with applied science, with technology - we deal with people. And when we deal with people, considerations other than truth enter the question."

Wednesday, November 26, 2008

EclipseCon 2009 Submissions

Time is short for EclipseCon 2009 submissions! All submissions must be in by 28th November, so consider submitting something now. In the meantime, check out my submissions:

Wednesday, November 19, 2008

Rough Cuts

Our first Rough Cuts edition of Equinox and OSGi: The Power Behind Eclipse is available online now!

Tuesday, November 18, 2008

OSGi Book in the Works

As you might have heard by now, I'm working with Jeff McAffer and Paul Vanderlei on an OSGi book. The book will be published by Addison-Wesley and will be part of the Eclipse Series. The working title is Equinox and OSGi: The Power Behind Eclipse, and you can even find it listed by Amazon, but the book won't be available until 2009.

The book is firstly an OSGi book, and secondly an Equinox book, and it covers many of the best practices that we have learned from building real-world OSGi applications. The bulk of the book is a tutorial that develops an application as you proceed through the chapters. There's also some deep dive chapters that attempt to discuss more complicated issues in detail.

We've just submitted some chapters to be published online under the Rough Cuts program, so be sure to check it out! There's also a blog dedicated to the book that we intend to update as we get closer to the publication date.

Friday, June 13, 2008

Working with Multiple LogServices

The fact that there can be multiple registered services of a particular type can sometimes be problematic. Consider the LogService and it's cousin the LogReaderService. When there are multiple registered LogService and LogReaderService pairs it can be tricky for an application to be able to present a single view of the application's logged messages.

It is this reason that SAT now has a LogReaderAggregatorService. As its name implies, it aggregates each registered LogReaderService and presents a single service API with which to work with the application's entire log. The LogReaderAggregatorService is straight forward:
public interface LogReaderAggregatorService extends LogReaderService {
public Enumeration/*<LogEntry>*/ getLogInOrder();
public boolean isLoggingToConsole();
public void setLogToConsole(boolean logToConsole);
}
Since the interface extends the OSGi-defined LogReaderService you can use the API you're familiar with, such as getLog(), but of course what you'll get back is an Enumeration of every LogEvent for every registered LogReaderService, in reverse chronological order.

The LogReaderAggregatorService interfaces adds the method getLogInOrder() for accessing every logged message in chronological order, and a couple of methods for controlling whether logged messages will be echoed to the console.

While the LogReaderAggregatorService interface is part of the required bundle org.eclipse.soda.sat.core, the implementation lives in the optional bundle org.eclipse.soda.sat.core.log.

Wednesday, June 11, 2008

Eclipse 3.4 is almost here...

If you've not heard, Ganyemede is coming... Time is running out fast, so please consider downloading Eclipse 3.4RC4 and kicking the tires a little. Likewise, Equinox 3.4RC4 is available too. There is still time to report any bugs you might find.

Wednesday, March 19, 2008

Best Commercial Equinox Application: Cyrano

Congratulations to Band XI on their Best Commercial Equinox Application victory with Cyrano. See all the winners here. Here's a photo of John accepting the award, but where's Brett and Patrick?

Wednesday, March 12, 2008

More Equinox Command Provider Enhacements

The bundle org.eclipse.soda.sat.equinox.console.cmdprov extends the Equinox console by registering four org.eclipse.osgi.framework.console.CommandProvider services.

  • Bundle Dependencies: These commands allow you to query the dependency and prerequisite relationships that exist between bundles.

  • Configuration Admin: These commands allow you to query the ConfigurationAdmin service for configuration PIDs, factory PIDs and configuration properties. This command provider requires a ConfigurationAdminservice to be registered.

  • Logging: These commands let you query and set the log level, and query and control whether tracing is on or off.

  • Missing Imported Services of Bundles and Configurations: These commands allow you to query the missing required and optional imported services of SAT bundles and configurations created by ConfigurationAdmin.

To use the Equinox console, launch the OSGi framework with the -console program argument, which is present by default for an OSGi Framework launch configuration. Typing help at the Equinox console will display the following additional command usage information:

---Bundle Dependencies---
adep - show all dependents of the specified bundle
apre - show all prerequisites of the specified bundle
dep - show dependents the specified bundle
pre - show prerequisites of the specified bundle
---Configuration Admin---
cprops [pid] - display the configuration properties
fpids [filter] - display the factory pids
pids [filter] - display the pids
---Logging---
logLevel [(debug|info|warning|error)] - query and control log level
trace [(on|off)] - query and control tracing
---Missing Imported Services of Bundles and Configurations---
ams [id] - show all missing imported services
mos [id] - show missing optional imported services
mrs [id] - show missing required imported services

Friday, March 7, 2008

SAT Support Proxy Service Equality

Previous posts talked about the problem of comparing the equality of two proxies, and a solution that involves unwrapping each proxy before performing the equality test. Today's post is short and sweet in that it simply shows the code to test SAT's support for proxy equality. The following snippet of code creates a proxied service and compares it with itself.

FactoryUtility utility = FactoryUtility.getInstance();
BundleContext context = getBundleContext();
IProxyServiceHandler handler = new ProxyServiceHandlerAdapter() {
public Object createService() {
return new HotdogVendor();
}
};
IServiceRecord record = utility.createExportProxyServiceRecord(context, VendorService.class, handler, null);
Object service = record.getService();
boolean equal = service.equals(service);
System.out.println("service.equals(service) = " + equal);

The console output is, as follows:

service.equals(service) = true

Thursday, March 6, 2008

Supporting Proxy Equality

Yesterday's post talked about how using the equals(Object) method to compare two Proxy objects always evaluates to false, even when the receiver and the parameter are the same instance. Today's topic is how to implement the InvocationHandler interface such that the equals(Object) method is handled correctly.

The solution is to intercept the invocation of the equals(Object) method and invoke it with an unwrapped receiver and parameter. Here's how...

public class MyInvocationHandler extends Object implements InvocationHandler {
private Object object;

public MyInvocationHandler(Object object) {
super();
this.object = object;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
String name = method.getName();
if (name.equals("equals") && args.length == 1) {
MyInvocationHandler handler = toMyInvocationHandler(args [ 0 ]);
if (handler != null) {
Object[] parameters= new Object[] {
handler.object
};
result = method.invoke(object, parameters);
}
}

if (result == null) {
result = method.invoke(object, args);
}

return result;
}

private MyInvocationHandler toMyInvocationHandler(Object parameter) {
InvocationHandler handler = Proxy.getInvocationHandler(parameter);
boolean valid = handler instanceof MyInvocationHandler;
if (valid == false) return null;
MyInvocationHandler myHandler = (MyInvocationHandler) handler;
return myHandler;
}
}

Rather than anonymously implementing the InvocationHandler interface, we have the class MyInvocationHandler. The object field is used to store the object that is being proxied.

We must intercept the invocation of the equals(Object) method, and where the parameter is an instance of MyInvocationHandler, we must invoke the Method, passing as a parameter the MyInvocationHandler instance's object field.

This technique of unwrapping the parameter Proxy only works when the proxy is one that has an invocation handler that is an instance of MyInvocationHandler. In cases where the parameter is not an appropriate proxy, execute continues as normal in the invocation handler.

Wednesday, March 5, 2008

Question: When is an object not equal to itself?

Most developers would agree that the expression object.equal(object) aways evaluates to true, and I thought so too until a short while ago where I found that it can sometimes evaluate to false. Trust me, it can happen. Consider the following code:
  public interface IPerson {
//...
};

private class Person extends Object implements IPerson {
//...
};
The Person class inherits its equals(Object) method from Object, the implementation of which is:
  public boolean equals (Object object) {
return this == object;
}
So if the expression object == object always evaluates to true, and yes, it always evaluates to true, how could it be possible for the expression object.equals(object) to ever evaluate to false?

Answer: When it's a proxy. This is a serious problem, since in most cases where proxies are used the fact that you're using a Proxy should not be something you need to think about. Consider the following code that creates a proxy and then compares it with itself:
  final IPerson person = new Person();

ClassLoader classLoader = Person.class.getClassLoader();
Class[] interfaces = {
IPerson.class
};
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(person, args);
}
};
Object object = Proxy.newProxyInstance(classLoader, interfaces, handler);

boolean equal = object.equals(object);
System.out.println("object.equals(object): " + equal);

boolean identical = object == object;
System.out.println("object == object: " + identical);
This code outputs the following to the console:
  object.equals(object): false
object == object: true
When I first saw this I could not believe my eyes, thinking that it must be a bug in either the JVM or the implementation of the Proxy class, when of course it was neither. The problem lies in the anonymous inner-class implementation of the InvocationHandler interface:
  InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(person, args);
}
};
The receiver is always a Proxy, so when we evaluate object.equals(object), execution quickly jumps to the handler's invoke method, where the expression method.invoke(person, args) is evaluated. The trick is to remember that this line of code is equivalent to:
  object.equals(person)
This evaluates to false because:
  • The object is an instance of Proxy.
  • The person is an instance of IPerson.
  • Both instances are distinct objects.
  • The Proxy class inherits its equals(Object) method from Object.
  • The expression object == person evaluate to false.

It is unfortunate that the Proxy class does not take care of ensuring that the equals(Object) method just works as you would expect, but sadly this is not the case. If you want it to work, and you really do want it to work, your InvocationHandler must be smarter. But I'm saving that for another day.

Thursday, July 12, 2007

SAT for Eclipse 3.3 (Europa)

Now that Eclipse 3.3 (Europa) is released, SAT has been rebuilt and a link to the build has been posted on the SAT Downloads section.

Monday, May 14, 2007

SAT Steps Up to Eclipse 3.3 M7

As the release date of Eclipse 3.3 quickly approaches, SAT has stepped up to M7. The SAT Downloads section, on the right, now includes links for both Eclipse 3.2.2 and Eclipse 3.3 M7.

Eclipse 3.3 is shaping up to be an important release for everyone that cares about OSGi. The PDE team has out done themselves by addressing over 900 bugs reports. I am particular pleased to see strides towards making the PDE tooling more friendly towards the needs of OSGi developers. Here's a list of PDE bug reports in which I have been involved.

If you're just getting to Eclipse 3.3 now, be sure to check out the New and Noteworthy document for M7 and for the earlier milestones.

Saturday, April 21, 2007

The Simplest Thing That Could Possibly Work

Motivated by a recent thread on the osgi-dev mailing list, here's the infamous Buns 'n Wieners example of building an OSGi service-oriented bundle activator using SAT.

This is a good showcase for SAT since it demonstrates the simplicity of building a bundle that imports multiple dynamic services as a prerequisite to exporting a service.

public class Activator extends BaseBundleActivator {
private HotdogVendor vendorService;
 
public Activator() {
super();
vendorService= new HotdogVendor();
}
 
protected String[] getImportedServiceNames() {
return new String[] {
BunService.SERVICE_NAME,
WienerService.SERVICE_NAME
};
}
 
protected void activate() {
System.out.println("Hotdog Vendor has been activated");
BunService bunService = getBunService();
WienerService wienerService = getWienerService();
vendorService.bind(bunService, wienerService);
addExportedService(VendorService.SERVICE_NAME, vendorService, null);
}
 
protected void deactivate() {
vendorService.unbind();
System.out.println("Hotdog Vendor has been deactivated");
}
 
private BunService getBunService() {
return (BunService) getImportedService(BunService.SERVICE_NAME);
}
 
private WienerService getWienerService() {
return (WienerService) getImportedService(WienerService.SERVICE_NAME);
}
}


  • The method getImportedServiceNames() returns the names of the imported services. The SERVICE_NAME field is the fully qualified name of the service interface and is an SAT convention.


  • The methods getBunService() and getWienerService() are helper methods; another SAT convention.


  • The activate() method is a hook method that only gets called when all the bundle's imported services have been acquired. When called from the activate() method, the getBunService() and getWienerService() method are guaranteed to not return null.


  • The deactivate() method is a hook method that only gets called when the bundle loses one of its imported services.


  • The use of a bind method in activate() and an unbind method in deactivate() is another SAT convention that simplifies the binding and unbinding of imported services. It would be equally valid to call setter methods instead.


  • The methods activate() and deactivate() are a pair and will get called multiple times during the lifetime of the bundle as its imported services change.


Historically this has always been the first example used to teach SAT since everyone understand that you're not selling hotdogs without both buns and wieners!

Credit for this example goes squarely to Paul Vanderlei, my colleague and buddy at IBM. Paul has been involved with SAT from the very start while developing it at OTI and later at IBM. Paul is the first person to tell me when "it's too hard for the caveman". Much of SAT's simplicity is thanks to Paul and his alter-ego, the caveman, who has existed long before the Geico ad campaign.

To learn more about SAT, check out the introductory tutorial.

Monday, April 2, 2007

Implementing Equinox's CommandProvider to Extend the Console

The Equinox console can be extended by any bundle that registers a CommandProvider service. SAT now includes such a bundle that adds the following commands to the console:

---SAT Bundle Dependencies---
  depend <id> - show dependents the specified bundle
  dependall <id> - show all dependents of the specified bundle
  prereq <id> - show prerequisites of the specified bundle
  prereqall <id> - show all prerequisites of the specified bundle
---SAT Logging---
  loglevel {(debug|info|warning|error)} - query and control log level
  trace {(on|off)} - query and control tracing

The bundle is called org.eclipse.soda.sat.equinox.console.cmdprov, and is optional and specific to the Equinox console.

Chris Aniszczyk has a good article on developerWorks titled "Explore Eclipse's OSGi console".

Thursday, March 29, 2007

Service-Oriented Device Architecture at Eclipse.org

The Eclipse Open Healthcare Framework project has recently added a page that describes SODA, of which SAT is a part.

"Service-Oriented Device Architecture (SODA) is an initiative to standardize and simplify the integration of devices with enterprise solutions by introducing a services-based programming model. SODA leverages existing and emerging standards from both the embedded-device and IT domains to provide well-defined interfaces for hardware devices to a service-oriented architecture (SOA)."

On the page you'll also find links to Device Kit and SAT resources, and you can find the official OHF downloads for SODA here.

Monday, March 12, 2007

A Successful OSGi Tutorial at EclipseCon

The EclipseCon tutorial Building Service Oriented Bundle Architectures was a huge success and generated a lot of positive publicity for SAT. At the tutorial the attendees learned how to build service-oriented bundles and worked with both fake and real hardware devices.

If you missed the tutorial, the materials are available here at the Band XI site.

Thank you John, Brett, Patrick, Paul, Randy, Bill and Kristen for developing the materials and doing such a fantastic job at the conference. See you next year!

Saturday, March 3, 2007

EclipseCon Tutorial: Building Service Oriented Bundle Architectures

Going to EclipseCon next week? Then be sure to sign up for the tutorial Building Service Oriented Bundle Architectures to learn more about how to use SAT.

The tutorial, presented by BandXI International and IBM, is going to a great opportunity to learn more about how best to use Eclipse to build OSGi applications and the benefits of being service oriented.

Planet Eclipse

Jazz Community News