Berichten met label OSGi

Online video: Beyond OSGi software architecture

Op 11 november 2009 gaf Marcel Offermans samen met Jeroen van Grondelle (Be Informed) een duo presentatie over “Beyond OSGi software architecture”. De video van deze presentatie is inmiddels online beschikbaar. De gehele presentatie van 50 minuten kan je hier downloaden. Maar de eerste tien minuten zijn hieronder gelijk online te bekijken.

OSGi is niet meer weg te denken uit het Enterprise Java domein. Dit lightweight framework krijgt al een aantal jaren flinke aandacht en is met name bekend om z’n modulaire applicaties op basis van bundles. Minder bekend is het services model, waarbij applicaties worden ontwikkeld op basis van service interfaces en van elkaar ontkoppelde implementaties (POJO’s) van die interfaces. Krachtige eigenschappen van dit model zijn:

  • complexiteitsreductie door stricte scheiding van services;
  • declaratieve services en dependency management (IoC);
  • aspect oriëntatie op basis van stub services;
  • security model.

Lean software is een nieuwe manier om enterprise applicaties te bouwen op basis van OSGi, die ook goed aansluit bij Agile methoden, waarbij non-functional requirements ingevuld kunnen worden in een compact gebleven framework. In die context kijken we naar:

  • applicaties deployen op allerlei platformen en omgevingen;
  • applicaties automatisch installeren en updaten;
  • applicaties voorzien van management interfaces;
  • product software uitbreidbaar maken middels een SDK;
  • product software verkopen als combinatie van standaard onderdelen en optionele uitbreidingen;
  • modulaire User Interfaces.

De slides van de presentatie zijn te vinden op de NLJUG website.

, , , , , ,

Nog geen reacties

Swing & OSGi — please play nice!

In a recent blog by Peter Karich, he showed how to create a pluggable Swing application using OSGi. While this works fine for smaller examples, you might run into more serious issues once you application starts to grow.

Plugging Swing: it leaks?

Let’s start with an application not unlike the one from aforementioned blog; it uses a window as host, and has a pluggable menu, and a pluggable table.

SWING_OSGI_Pluggable components600

You can find the code we used at the end of this entry (or, for the impatient, here).

Using this pluggable system, we could end up with several curious situations. For instance, you might have a mixed look and feel in you application.

SWING_OSGI_wrong_menus

Or worse, you might end up with a UI that (sometimes) fails to start, and spits a stacktrace your way.

swing_osgi_NPE

It leaks, but why?

Our host, and all components have been stored in separate bundles, meaning we don’t have full control about the order in which actions are performed (more about that later). However, we do know there are orders of execution that are less than ideal; let’s force one of those.

The project contains an Ant script to make things easier. From the root of the extracted project, run

$ > ant run1

This starts the framework, installing the necessary bundles, but does not start them (note that this step uses Pax Runner, and therefore needs internet access). We can now start our bundles in the order we like.

A tale of two look-and-feels

After starting the framework, wait for the “Welcome to Felix” message, and run

     [java] Welcome to Felix
     [java] ================
     [java]
start 2
start 1

The situation arises because the look and feel is a static concept in Swing. The menu bundle creates its JMenu before (see Menu.java, ln 30) the host sets its look and feel (Host.java, ln 51), and keep that look and feel, even when the host bundle changes it later.

Tables, ScrollPanes and NPEs

The NullPointerException above is a different story, but it goes back to the same staticness of Swing too. To force this situation, start only bundle 4.

     [java] Welcome to Felix
     [java] ================
     [java]
start 4
     [java] Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
     [java]      at net.luminis.swingosgi.part1.scrolltable.impl.TableComponent$1.run(TableComponent.java:31)
     [java]      at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
     [java]      at java.awt.EventQueue.dispatchEvent(EventQueue.java:633)
     [java]      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
     [java]      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
     [java]      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
     [java]      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
     [java]      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
     [java]      at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Let’s take a look at the line where this NPE happens:

JScrollPane scrollPane = new JScrollPane(table);
scrollPane.getColumnHeader().setBackground(Color.blue);
m_panel.add(scrollPane);

We know that the ColumnHeader is null. This is because its JTable’s responsibility to create the header, but this is only done once the table knows it is part of an AWT hierarchy. The following lines come from the 1.5 JDK on a Mac; configureEnclosingScrollPane() creates the column header. This addNotify method comes from Component, and notifies of, exactly, the event of being added to an AWT container.

public void addNotify() {
  super.addNotify();
  configureEnclosingScrollPane();
}

Order, order!

So, the static nature of Swing and the dynamic nature of OSGi seem to hurt each other seriously here.

One way to get the application right is by fixing the order in which Swing components can be created. By starting bundle 1 first in our application, we at least fix the look and feel. Getting the scrolling table to run correctly is an entirely different story.

Regarding order, a few possible solutions spring to mind immediately,

  1. Put all UI stuff in one bundle
  2. Use OSGi bundle start levels

Sure, all UI in a single bundle will give you the control necessary, but it also defeats the purpose. OSGi start levels can at least solve the ordering issues, but will not get you out of the NullPointerException and might have more impact than you desire.

What order?

As we have seen, absolute order does not solve our problem. How about separating creation and initialization? Still, we need to impose some order, or at least some hierarchy.

SWING_OSGI_Application composition600

We represent each Swing component by an OSGi service, and leverage the OSGi service dependency resolution to build up our hierarchy; this way, we know the host service will be started last.

  1. Resolve services Once the host bundle starts, we know all components are locked and loaded; the host can now start setting up Swing’s static elements like the look and feel.
  2. Create components Component creation ripples downward: the host gets its direct children, adding them to its container, and in the process triggering the children to get their child components.
  3. Initialize components Once the component creation is done, the host instructs each component to initialize; we can now be certain that all components are part of the AWT hierarchy.

To reach this situation, we introduce a new OSGi service that wraps the component.

SWING_OSGI_Using component provider600

All components are handled by a service implementing ComponentProvider; notice how methods are required to be called on the EventDispatchThread, making sure that all components are created on the EDT, while retaining the order necessary.

public interface ComponentProvider {
 /**
 * Constant to identify ComponentProvider services.
 */
 public static final String COMPONENT_ID_KEY = "component.id";
 
 /**
 * This function should always be called from the EDT. The implementor
 * may assume that this function is called once and before {@link #addedToContainer()}
 *
 * @return the implementors (Swing) component which it provides.
 */
 public JComponent getComponent();
 
 /**
 * Triggered when the component is added to a container. The implementation
 * can validate some stuff. This function must be called on the EDT.
 * Implementors may assume this function is called after {@link #getComponent()}.
 */
 public void addedToContainer();
}

The getComponent function is analogous to the create step above; the addedToContainer triggers the initialize.

Let’s try that out!

To check that this actually works OK, run

$ > ant run2

from the root of the project, and start the bundles in any order you like. The UI will only show up once all required components are available; notice that the Table and the ScrollPane component can be used interchangeably.

Is it all good?

For the most part, yes. You do give up some flexibility: the UI is assembled at runtime, but it is no longer possible to (easily) plug components into a running system without special provisions. Then again, how often do you deploy new Swing-based functionality to a running application?

In the example application, we use ServiceTrackers to keep track of the components needed by the host. In a real system, you should consider using some dependency management mechanism; we have used the Apache Felix Dependency Manager in the past.

The project and the story

The project mentioned above is available as a zipped Eclipse project. You can directly import this into Eclipse, or just unzip it and run the Ant build file.

To run the examples, you will need Apache Ant. Also, since we use Pax Runner, you will need an internet connection.

The presentation we gave about this at Devoxx 09 is at SlideShare.

, ,

1 reactie

ApacheCon US 2009 – Celebrating a decade of open source leadership

The Apache Software Foundation celebrated its 10th anniversary last week at the ApacheCon US in Oakland, California. The event, which lasted from November 2nd to 6th, consisted of many different types of events, ranging from full-day trainings to lightning talks, from a hackathon to technical and marketing sessions. On friday, the event featured a full-day track about OSGi, where all OSGi related Apache projects like Felix, ACE, Sling and Tuscany where present. The big announcement of the conference was the fact that Subversion wanted to join Apache. In fact, during the event, just like with any other project, there was a vote to accept Subversion into the incubator. As with many projects, this triggered some discussion, debating the merits of doing a release during incubation, even though this is a project with many seasoned Apache committers on board.

A conference like no other

Apache probably is the strongest brand in the open source space, but the conference itself focusses strongly on content. Here you will see no sponsored talks by commercial vendors, no sales people trying to sell you anything, it’s all about the code, the community and collaborating with each other. In that sense it’s quite different from most other conferences and if you like meeting and discussing fellow developers, this is a great place to visit. Many events facilitate discussion, and power and internet connectivity are available everywhere.

What open source is all about

Brian Behlendorf summarized the three main cultural elements of Apache quite well:

  • write good code and debate it to the bone
  • be humble
  • collaborate

In essence, Apache is a meritocracy, of which only individuals can become a member. It’s sometimes also described as a do-ocracy as projects are driven by contributions: if you want something done, just do it. Another important aspect is that everything that is done on the Apache projects is discussed and archived on the mailing list. All discussions, code diffs and decisions must be recorded there.

Presenting Apache ACE

Tuesday evenings “birds of a feather” session featured a discussion about Apache ACE, where questions mostly centered around the use cases for ACE and possible integrations with other OSGi components. One of the conclusions is that there are probably three different phases of deployment:

  1. Using Apache Felix File Installer, which allows you to drop components in a local folder to have them installed.
  2. Using Apache Felix Karaf’s provisioning components, which allow you to define features which basically group components and allow you to define dependencies on other features.
  3. Using Apache ACE, which allows you to group components and automatically deploy them to many remote systems.

Friday’s OSGi track started with an introduction to OSGi and moved into more advanced topics during the day. The Apache ACE talk was received well, with several people expressing an interest in wanting to use it and contribute to it.

Final thoughts

Summarizing the week, Floris and I had a great time talking to many interesting people and learning about various projects. ApacheCon is a great conference, and I’m already looking forward to the next one.

, , , , , , , , , ,

Nog geen reacties

Oredev 2009

This past week (4 – 6 November), I went to Øredev, probably the largest developer conference in Scandinavia. I had been invited as a speaker, thanks for having me!

Great food, nice ambiance

The first thing that strikes me about this conference is how well it has been prepared. The food is great, there is a good evening program, and overall both your inner geek and inner person are well looked after.

Highlights

Interactive Visualizations from Microsoft research – Eric Stollnitz (User Experience track)
One of the rare talks I actually did not like. Having not read the session description properly, I had totally wrong expectations; the session demoed visual tools like Photosynth, which are cool, but not something we haven’t seen before. And besides, running Vista on a Mac, and having to kill Internet Explorer…?

Open source Java: ten things you didn’t know you could do – Terrence Barr (Java track)
Early in the talk it felt like a plug for the greatness of Sun, making Java open source. Later, however, it mentions some seriously cool technology that has become possible now! Some honorable mentions,

  • The Maxine guest VM is an effort to run a Java VM directly on a HyperVisor, skipping the entire OS!
  • IKVM.NET is a project aiming to run Java code on a .NET VM. Somehow, it turns out that Java bytecode and .NET assembly language are so similar, that an effort has been started to create automatic translation tools between compiled Java and compiled .NET (and vice versa). I would like to add that this is allows not only Java to run on a .NET VM, but likely any language that runs on the Java VM! Interesting…
  • Zero writes a Java VM in plain C without using assembler code, making it easier to port it to new platforms.

The Manager’s Guide to Agile Adoption – Mike Cottmeyer (PM In Practice track)
A great talk showing the issues that might hamper agile adoption, especially in larger organizations. Some snippets,

  • “Agile adoption at the team level is not the issue, it’s adopting agile across teams.”
  • Don’t speak of features of a system, speak of capabilities (think about that one!)
  • Depending on the amount of dependencies between teams, we could use a Scrum of Scrums (resource dependency), Product Owner team (requirements dependency), or a Product Owner team with Architects (technical dependencies). Whatever method is used, this higher level should build a normalized backlog, intended to create some alignment along the teams. The team’s backlogs are based on this normalized backlog.
  • Feature teams will break down at some level; at a certain system size, it’s no longer possible to create a top-to-bottom slice of the system which is small enough for a single team to manage.

In short, I really enjoyed this talk, and I feel there might be some applications for these ideas somewhere near me…

How Exactly Can Developers Create a Compelling User Experience? – Ben Galbraith (User Experience track)
Exactly the way I would expect a user experience talk to look (and feel!) like: polished imagery, a well-oiled story line, and lots of inspiration. Besides, I have two new books to add to my reading list: About Face by Alan Cooper, which seems to be the standard volume on interaction design, and The humane interface by Jeff Raskin.

Reconsidering cherished design dogmas – Johannes Brodwall & Finn-Robert Kristensen (Architecture track)
I actually had a beer with these guys a few days earlier, and they told me about their ideas. In short, there are a number of dogmas in software design we came to hold true, but are they actually true? For instance, is generic code really more reusable than specific code?

It’s a shame the talk didn’t really come across, and I could not put my finger on the problem; it might have something to do with the over-abstracted example they chose.

Dynamic Deployment with OSGi – Angelo van der Sijpt (Java track)
Well, let the crowds decide on this one. Have you visited my talk, and have an opinion about it? Let me know in the comments?

Modeling in the Age of Agility – Kevlin Henney (Agile Architecture track)
“Working software over comprehensive documentation” sounds good, but how about modeling? Are all models potential waste? Of course not, but when applying modeling because it is modeling, is sure to create models no one will ever look at, and the few good ones in there are buried. Some snippets,

  • “Agile is all about doing.” Actually, I did not know the word ‘Agile’ comes from the Latin verb for ‘to do’.
  • “The most important aspect of modeling is the -ing.”

So?

Like I said, a great conference, and I’m sorry I missed the test track. I will leave you with a quote I picked up on Twitter (I don’t know which session it’s from),

“Don’t build frameworks, extract them”

, , , ,

Nog geen reacties

Using GWT to create an OSGi-aware web application

Update 2010-02-20 Both Pax Runner 1.3.0 and GWT 2.0 have caused quite some changes to this post. I have tried to stay up to date as well as I could (the zipped project now uses GWT 2.0), but you might find some inconsistencies when following the tutorial.

Google Web Toolkit is cool, and so is OSGi. However, when building a web UI for Apache ACE, I found out that creating a web application that can use OSGi services is not that easy. By the end of this tutorial, you will have created a GWT project that delivers a usable jar. If you’re impatient, skip to the end for the downloadable Eclipse project.

Step 1: Create a GWT project

Create a regular GWT project using the regular webAppCreator; this will give you a project that includes an Ant buildfile, we will need that later on.

angelos:workspace angelos$ ./gwt-mac-1.6.4/webAppCreator -out GwtDemo net.luminis.gwt.gwtdemo
Created directory GwtDemo/src
Created directory GwtDemo/war
Created directory GwtDemo/war/WEB-INF
Created directory GwtDemo/war/WEB-INF/lib
Created directory GwtDemo/src/net/luminis/gwt
Created directory GwtDemo/src/net/luminis/gwt/client
Created directory GwtDemo/src/net/luminis/gwt/server
Created file GwtDemo/src/net/luminis/gwt/gwtdemo.gwt.xml
Created file GwtDemo/war/gwtdemo.html
Created file GwtDemo/war/gwtdemo.css
Created file GwtDemo/war/WEB-INF/web.xml
Created file GwtDemo/src/net/luminis/gwt/client/gwtdemo.java
Created file GwtDemo/src/net/luminis/gwt/client/GreetingService.java
Created file GwtDemo/src/net/luminis/gwt/client/GreetingServiceAsync.java
Created file GwtDemo/src/net/luminis/gwt/server/GreetingServiceImpl.java
Created file GwtDemo/build.xml
Created file GwtDemo/README.txt
Created file GwtDemo/.project
Created file GwtDemo/.classpath
Created file GwtDemo/gwtdemo.launch
Created file GwtDemo/war/WEB-INF/lib/gwt-servlet.jar

If you want to, you can import this project directly into your Eclipse. If you check the mark “use Google Web Toolkit” in the project properties, you can use all the same goodies that creating the project in Eclipse would have given you. Remember to replace the buildpath entries for gwt-user.jar and gwt-dev-*.jar by a Library import for GWT.

Step 2: Include the necessary OSGi references

Create an ‘ext’ directory, and add org.osgi.core.jar to that. In Eclipse, add this jar to your build path.

Step 3: Use OSGi services from your web applicaiton

We will first add a simple Activator on the server side.

package net.luminis.gwt.server;
 
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
 
public class Activator implements BundleActivator {
    private static BundleContext m_context;
 
    public static BundleContext getContext() {
        return m_context;
    }
 
    public void start(BundleContext context) throws Exception {
        m_context = context;
    }
 
    public void stop(BundleContext context) throws Exception {
    }
}

Then, we up the GreetingServiceImpl to actually use this BundleContext (note that we use it directly here, but you could use it to get other services, create a ServiceTracker, etc.)

public String greetServer(String input) {
  String serverInfo = getServletContext().getServerInfo();
  String userAgent = getThreadLocalRequest().getHeader("User-Agent");
  return "Hello, " + input + "!
 
I am running " + serverInfo
    + ".
 
It looks like you are using:" + userAgent +
    "The framework we run from has " + Activator.getContext().getBundles().length + " bundles in it.";
}

Step 4: Add OSGi dependencies for the compiler

Add our OSGi dependencies to the classpath, so the compiler can find all of it.

    <!-- Add any additional non-server libs (such as JUnit) -->

Right, let’s give it a try!

angelos:GwtDemo angelos$ ant war
Buildfile: build.xml
 
...some output removed...
 
war:
[zip] Building zip: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.war
 
BUILD SUCCESSFUL
Total time: 36 seconds

You will find a war in your project directory now. There still is one ingredient we need. We need to make this into a proper bundle. We can use bnd to help us with that.

Step 5: use bnd to create a proper war

Download bnd, and put into a lib directory, and add it to your buildfile.

We create a new target that transforms our war into a jar.

<target name="jar">
    <copy file="gwtdemo.war" tofile="gwtdemo.jar"/>
    <echo file="gwtdemo.bnd">Import-Package: junit.framework;resolution:=optional, com.google.gwt.*;resolution:=optional, org.w3c.*;resolution:=optional, sun.misc;resolution:=optional, javax.imageio;resolution:=optional, javax.servlet.*;resolution:=optional, *
Bundle-Name: GWT Demo
Bundle-ClassPath: WEB-INF/classes, WEB-INF/lib/gwt-servlet.jar
Bundle-SymbolicName: net.luminis.gwt.gwtdemo
Webapp-Context: gwtdemo
Bundle-Activator: net.luminis.gwt.server.Activator
    </echo>
    <bndwrap jars="gwtdemo.jar" output="gwtdemo.jar"/>
    <jar file="gwtdemo.jar" update="true">
    <manifest>
        <attribute name="Bundle-ClassPath" value="WEB-INF/classes, WEB-INF/lib/gwt-servlet.jar, ."/>
     </manifest>
    </jar>
    <delete file="gwtdemo.bnd"/>
</target>

What’s happening here?

  • we copy our war to the same file, but with a jar extension,
  • we create a file for bnd to use, stating that we
    • want optional imports for junit and the gwt benchmarks, and non-optional imports for everything else (that what the * is for),
    • have some classes that we want bnd to scan for finding dependencies,
    • want to use a given Webapp-Context (this is a Pax war extender specific entry),
  • let bnd do its magic,
  • update our manifest: we put the . back on the classpath. This is important for the web application to find all resources, but if we would tell bnd to do it like this, it would treat . as the root of the classpath.
  • Finally, we delete that temporary bnd file.

What does that give us?

angelos:GwtDemo angelos$ ant jar
Buildfile: build.xml
 
...some output removed...
 
jar:
[copy] Copying 1 file to /Users/angelos/workspace/workspace/GwtDemo
[bndwrap] gwtdemo 41 910305
[bndwrap] Warnings
[bndwrap] Superfluous export-package instructions: [WEB-INF.classes.net, gwtdemo.gwt.standard.images, WEB-INF, gwtdemo, WEB-INF.classes.net.luminis.gwt, gwtdemo.gwt.standard, WEB-INF.classes.net.luminis, WEB-INF.lib, WEB-INF.classes, gwtdemo.gwt.standard.images.ie6, WEB-INF.classes.net.luminis.gwt.client, WEB-INF.classes.net.luminis.gwt.server, gwtdemo.gwt]
[jar] Updating jar: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.jar
[delete] Deleting: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.bnd
 
BUILD SUCCESSFUL
Total time: 23 seconds

That’s it! You can now deploy this jar into a framework that uses the pax web tools. Right, let’s give that a try.

Download pax-runner, and unzip that somewhere. Copy in your new jar, an try the following command

angelos:pax-runner angelos$ sh bin/pax-run.sh --profiles=war,compendium gwtdemo.jar

Now visit http://localhost:8080/gwtdemo:

gwtdemo

Summary

So, what did we need?

  • A fairly regular GWT project, create with an Ant file,
  • some code that tries to use OSGi services,
  • some bnd magic to make the war into a jar,
  • Pax tools to get it all running quickly.

If you don’t want to use pax runner, you can need to deploy pax-web-extender-war(jar, snapshot 23 June) and an http server, preferably pax-web-service(jar), into your framework.

You can download the gwtdemo Eclipse project to play around with it. I have not provided the GWT runtime in this download; you should edit line 4 of the build.xml to point to your installation of GWT.

, , , , , , , , , , ,

9 reacties

EZdroid launched


The EZdroid initiative is launched: www.ezdroid.com

We are pleased to announce the launch of EZdroid, the world’s first open-source, collaborative platform for the safe deployment of component-based software applications and content across Android, and other Linux-based mobile devices.
EZdroid was founded by two of Europe’s leading companies in the field of OSS technology; the platform consists of Android, Apache Felix and a number of their own enhancements (e.g. software license-, device- and integrated software-management). EZdroid supports the secure deployment of software applications and content (known as Provisioning) to Android phones and in the future, other Linux-based operating systems. It is available to any organization or individual wishing to make software and content available to Android users world-wide. Further information and a demonstration of the platform is now available and downloadable to Android phones at: http://www.ezdroid.com.

EZdroid’s founders: Luminis BV (www.luminis.nl/en) of The Netherlands and Akquinet GmbH (www.akquinet.com/en) of Germany are now inviting partners and collaborators to become part of the EZdroid community – whether these are developers, wishing to show-case their applications, business partners interested in co-development or an OEM relationship, or organizations which are interested in owning and controlling their own application repository/App Store.

The launch of EZdroid is very significant; it is the world’s first platform, built from open source components, which will allow the mass deployment of applications without proprietary licensing issues. The founders intend to supplement the platform with a validation and quality assurance system – to ensure that applications are safe and do not interfere with Android’s normal operations.

, , , , , , ,

Nog geen reacties

J-Spring 2009

Aan de druk bezochte J-Spring Java conferentie in een zomers warm Spant! in Bussum, heeft luminis weer een flinke bijdrage geleverd. Bij de stand werd de bezoeker getrakteerd op een overheerlijke tompouce (van de echte bakker!) en werden lootjes uitgedeeld voor een boekverloting. Op inhoudelijk vlak bestond de bijdrage uit 3 presentaties over uiteenlopende onderwerpen. En voor de bezoekers die het uithoudingsvermogen hadden om tot het eind te blijven, was er dan nog de door luminis gesponsorde borrel!

De presentatie van Jaap Vriend ging over LWUIT, een UI library voor J2ME. Deze library biedt een op Swing lijkend programmeermodel en maakt het veel makkelijker om een J2ME applicatie er op alle telefoons hetzelfde uit te laten zien.

Richard van der Laan presenteerde samen met Tony Sloos van ArchitecIT een pragmatische benadering van MDA. Aan de hand van een concreet voorbeeld lieten ze zien hoe je bottom-up MDA kunt invoeren, waarbij je er vanaf het begin voordeel van hebt.

Onze OSGi guru, Marcel Offermans, had een leuke demo samengesteld op basis van de leukste bug. Nu is een live demo natuurlijk altijd riskant, maar Marcel is typisch iemand die dat wel aan kan. Helaas voor hem (en voor het publiek) waren de goden hem dit keer niet zo goed gezind en lukte het niet de demo dat te laten doen wat hij had moeten doen. Dus die houden we van hem tegoed! Bij de J-Fall op de luminis stand?

De presentaties kun je als pdf downloaden:

, , , , , , ,

1 reactie

Enterprise Javabeans 3 in OSGi — part 2

This blog picks up on some unfinished items mentioned in the first blog. More specifically, this blog will focus on:

  • auto-injecting session beans;
  • entity-only bundles;
  • transaction rollback.

Note that if the reader wants to run the example source, he or she is referred to the aformentioned previous blog in which more information on setting up the environment and getting the sources to compile/run can be found. To get the samples running, you always need to start ezb-command.jar and entitybeans.jar. Besides those 2 bundles, you either need to start combinedbean.jar (includes 2 stateless beans) or statelessbean1.jar and statelessbean2.jar (both bundles contain 1 stateless bean).

Auto-injecting session beans

In EJB3 (and therefore also in EZB) it is possible to inject a reference to a session bean through using the ‘@EJB’ annotation. When using this annotation, you can supply the product-specific name of the EJB to which it should be mapped (could be any kind of name – even though it is often a JNDI one). As it turns out, EZB almost completely supports this feature; both when the EJB to be injected is defined within the same bundle (use combinedbean.jar) and when it is defined in a different bundle (use statelessbean1.jar and statelessbean2.jar) the reference is injected properly and no lookup takes place:

    @EJB(mappedName="SL2")
    private Stateless2Remote m_stateless2 = null;

    @EJB
    private Stateless2Remote m_stateless2NotAutoInjected = null;

    // ... and some code using it:

    if (m_stateless2 == null) {
        // '@EJB' injection did not take place, performing lookup
        try {
            m_stateless2 = (Stateless2Remote)new InitialContext().lookup(
                String.format("%s_%s@Remote", "net.luminis.ezb.stateless2.impl.Stateless2Impl", Stateless2Remote.class.getName()));
        } catch (NamingException e) {
            e.printStackTrace(); // lookup failed.
        }
    }

Note though, that the mappedName must be set both here and in the implementation of the session bean to be injected. If this is not done, EZB cannot find/inject it. I.e. in the code above, at the point where m_stateless2 has been set, the member variable m_stateless2NotAutoInjected is still null.

Entity-only bundles

When deploying ones bundles you’re likely to combine related functionality. It’s possible to simply put everything in a single bundle, but not desirable; the more fine-grained your design, the easier it is to re-use a specific bit of functionality. When you decide to define an entity-only bundle, EZB requires that you include the line

net.luminis.ezb.entitybeans.Kangaroo

both in persistence.xml of the entity-bundle, but also in all bundles using the entity-bundle. This inconvenience may be corrected, but for now, it’s not a very flexible way of working; when you add an entity bean to your entity-bundle, you not only have to update the persistence.xml in that bundle, but also in all bundles using it!

Rollback

Finally, the source code attached to this blog also includes an example of how EZB handles a transaction rollback. It is possible to trigger such a rollback by using:

m_sessionContext.setRollbackOnly();

to signal the session to perform a rollback of every action associated with the current transaction. In this example the functionality is illustrated through using the command

ezb use_injected_max

which not only uses an injected session bean to create a Kangaroo entity, but also triggers a rollback if 4 Kangaroos have already been created. (Check the methods addKangaroo() and addKangarooWithMaximumCheck() in Stateless2Impl to find out more.

, ,

Nog geen reacties

Unboxing the Bug

First of all, happy new year! I’m sure 2009 will be a great year for everybody.

Today, the long anticipated Bug arrived in the mail. I met Ken almost a year ago now, at EclipseCon, where he did a very nice demo of a new device. Call it LEGO for adults. The box contains hotpluggable hardware modules, such as motion sensors, a touch screen, a GPS locator, a generic I/O board for custom extensions which makes the hardware as dynamic as the software inside. That software, of course, is OSGi based, so there is full modularity there too. Add a well designed SDK for developing and deploying bundles for the system and you have a system that is very appealing to developers and can be used for all kinds of technology demos. Today’s blog ends with a nice picture of the opened box, showing some of the goodies inside. Expect more in depth articles in the near future!

, , , , ,

Nog geen reacties

Enterprise Javabeans 3 in OSGI

Previous blogs (look here and here) have shown that it’s fairly easy to use (open)JPA within OSGi. Moving on on this path of attempting persistence solutions for OSGi led to an encounter with Easybeans (EZB from now on), an Enterprise Javabeans 3 (EJB3) container for OSGi.

This blog assumes that the felix 1.4.0 environment is used. All source code used and all relevant bundles can be found in this zip.

Some of the reasons EJB3 can be of interest when moving beyond what JPA has to offer:

  • container managed transactions;
  • dependency injection.

For more detailed information on the advantages of EJB3, refer to this article on javaworld


Using EZB within an OSGi context may be of interest to you if you’re working with an:

  • EJB3 environment and you’re thinking about migrating towards OSGi;
  • OSGi environment, but you don’t have a satisfactory solution for handling persistency issues.

In this blog we will use a simple example that uses some basic EJB3 functionality; we’ll use a command line client that connects to a stateless session bean. The session bean is able to interact with an entity bean called Wombat and is able to create, update and delete (Wombat) entities. We’ll walk through the specifics of each step below.

In order to execute a command, the client first has to connect to (i.e. obtain a reference to) the stateless session bean (EzbCommand.java):

    private static final String STATELESS_REMOTE = "net.luminis.ezb.example1.stateless.StatelessRemote";

    public void execute(String commandLine, PrintStream out, PrintStream err) {
        ServiceReference ref = m_bundleContext.getServiceReference(STATELESS_REMOTE);
        m_stateless = (StatelessRemote)m_bundleContext.getService(ref);

EZB registers each stateless session bean as an OSGi service when the bundle that contains the service (and using the org.ow2.easybeans.osgi.ejbjar.Activator) is started. Because of this, it is possible to use the service without EJB3/EZB specific code in the client or the service interface, even though you can still use JNDI to lookup the service. When trying this, be warned that there’s a class loader issue. When dealing with stateful beans, this mechanism does not work and a JNDI lookup must always be used.

Following that, the session bean receives a command from the client, e.g. a ‘create’ command. StatelessImpl.java then picks up the command and creates a new Wombat object with the supplied values. Once that is done, it uses the EntityManager injected into the implementation by EZB (because of the @PersistenceContext annotation – default EJB3 behaviour) to persist the newly created Wombat entity:

    @PersistenceContext
    private EntityManager m_entityManager = null;

    public void createWombat(int id, String name) {
        Wombat entity = new Wombat();
        entity.setId(id);
        entity.setName(name);
        m_entityManager.persist(entity);
        System.out.println("Created entity bean: " + findWombat(id));

The entity bean used (defined in Wombat.java) contains three EJB3 annotations, denoting it as an entity bean (’@Entity’), indicating which table to create/use for the entity (’@Table’) and indicating which of the bean’s attributes can be used as its primary key (’@Id’):

@Entity

@Table(name = "WOMBATS")
public class Wombat implements Serializable {

    // [cut some code]

    @Id
    public int getId() {
        return m_id;
    }

Update the Felix configuration

Once again, please note that a felix 1.4.x environment should be used. For more information on previous releases, refer to the README in the zip file. In order to start the EZB bundles, a few changes need to be made in the configuration.

A pre-configured conf/config.properties file can be downloaded from here.
Of course, you can also apply the required changes yourself; an overview of the changes that need to be applied to the conf/config.properties file will follow.

Note that you’ll need the file config.properties of a previous release to copy two specific configuration entries: ‘org.osgi.framework.system.packages’ and ‘jre-1.x’ (depending on the JRE used, this is a list of packages that are exported by default).
Now, edit the config.properties of your newly installed Felix configuration and:

  • Uncomment the ‘org.osgi.framework.system.packages’ entry and set the value to the one copied from a previous release.
  • Add the complete ‘jre-1.x’ entry to (the bottom of) the file.

The ‘org.osgi.framework.system.packages’ entry should now look something like:

org.osgi.framework.system.packages=org.osgi.framework; version=1.4.0, \
 org.osgi.service.packageadmin; version=1.2.0, \
 org.osgi.service.startlevel; version=1.1.0, \
 org.osgi.service.url; version=1.0.0, \
 org.osgi.util.tracker; version=1.3.3 \
 ${jre-${java.specification.version}}

Note that the last line (with the ${jre-${java.specification.version}} construct) includes all items that are set in the copied ‘jre-1.x’ configuration and that this means that you must have at least 1 section in your config file that starts like:

jre-1.5=, \
 javax.accessibility; \

Also, add the sun.rmi packages to the config.properties file, which can now be done more cleanly through:

org.osgi.framework.system.packages.extra= \
 sun.rmi.server; \
 sun.rmi.transport; \
 sun.rmi.registry;

Finally, make sure Felix only logs a warning if it encounters unsupported fragment behavior through uncommenting the line with the felix.fragment.validation option:

felix.fragment.validation=warning

Download the EZB bundles

The required easybean jars can be downloaded from here. This blog is based on usage of the ‘1.1.0-M1′ release, select that release (or possibly a newer release) and then download the package available under “OSGi bundles of EasyBeans”. Unzip the file and note the location of the ‘bundles’ folder.

Install the EZB bundles

Note that this this step should be performed using a felix-1.0.x configuration or a felix-1.4.x configuration only!
In order to install the bundles, start Felix (make sure you’re using the updated configuration!) and execute the following commands in Felix:

-> cd file:/<absolute_path_to_bundle_folder>/
-> start org.apache.felix.configadmin-1.0.4.jar
-> start org.apache.felix.dependencymanager-1.1.0-2008.07.10.jar
-> start org.apache.felix.log-0.9.0-incubator-2007.12.14.jar
-> start org.apache.felix.scr-1.0.6.jar
-> start ow2-bundles-externals-commons-logging-1.0.8.jar
-> start ow2-bundles-externals-commons-modeler-1.0.8.jar
-> start ow2-util-event-api-1.0.8.jar
-> install ow2-util-event-impl-1.0.8.jar
-> start ow2-util-jmx-api-1.0.8.jar
-> install ow2-util-jmx-impl-1.0.8.jar
-> start slf4j-api-1.5.2.jar
-> start slf4j-jcl-1.5.2.jar
-> install easybeans-core-1.1.0-M1.jar
-> install easybeans-component-carol-1.1.0-M1.jar
-> install easybeans-component-jdbcpool-1.1.0-M1.jar
-> install easybeans-component-joram-1.1.0-M1.jar
-> install easybeans-component-jotm-1.1.0-M1.jar
-> install easybeans-component-quartz-1.1.0-M1.jar
-> install easybeans-component-hsqldb-1.1.0-M1.jar
-> install easybeans-agent-1.1.0-M1.jar

Once all these bundles are Active or Installed, start the easybeans-agent bundle. Once that bundle is Active, all bundles should be. Now you can start the ezb-command.jar and the statelessbean.jar bundles (same command structure as above). If you want to build the bundles yourself, copy the file easybeans-core-1.1.0-M1.jar from the ezb bundles dir and use ant to create the bundles:

cd <example1-location>
cp <ezb-bundledir-location>/easybeans-core-1.1.0-M1.jar lib
ant clean bundle.all

Once that is done, you can use the jars that can be found in the output dir.

An interesting point to note for this section is the use of the ‘easybeans-agent’ bundle. This bundle is used to stop and start the ‘ow2-util-event-impl’, the ‘ow2-util-jmx-impl’, the ‘easybeans-core’ and all ‘easybeans-component’ bundles in the right order (also refer to ‘issues encountered’ section below).

Issues encountered

  • When a bundle defines an entity bean in an exported package, it must import the package ‘javassist.util.proxy’ with ‘optional’ resolution;
  • The fact that EZB uses the easybeans-agent instead of using dependencies was often a source of confusion, if not errors: it felt like the startup order could not always be reproduced and only by stopping the agent, shutting down the framework and restarting both, could problems be resolved;
  • Running a client from the outside (not deployed in osgi / running in another JVM) that attempts to lookup (JNDI) a session bean was a real bother (and is therefore not included in this blog);
  • Injecting a session bean service that is not defined in the same bundle is not (yet) possible;
  • When using entity beans defined in a separate bundle, it is required to include the entity class name to be used both in the entity bundle itself and the bundle using it;

Maybe a follow-up of this blog will elaborate on the last two issues when moving on from using a single bundle to using multiple bundles.

Conclusion

All in all, the ability to use EJB3 related features from within OSGi is definitely a good thing, even though there’s a couple of usability issues to take into account still. Keeping in mind that the product is still in development and that the support is very good (when posting a question in the ow2 mailing, a response will usually follow within a day, if not within the hour), the EZB container is definitely one to keep an eye on!

, , , , ,

1 reactie