Introduction to BDD

I will be giving a short introduction to behavior driven development (BDD) at the XP forum on 13 August 2008.  As usual, I’m using the opportunity to subtly throw in some other practices such as coding for readability and designing good messages.  I will also touch on mocking in tests as well.

I’ve been having immense fun putting together some code examples for this talk and I hope to demo BDD using JUnitJBehaveRSpec (using the rbehave story runner on JRuby to test Java) and JTestR (which looks like a really exciting little project).

Come along and enjoy the fun.  Details and registration is on the JCSE web site.

Update 1: The Source Code for BDD Presentation is now available.

Update 2: The presentation is now available for download here.  It’s a 5MB Quicktime movie file. It’s not a continuous play movie, so you need to click through to the next slide.

Unconventional or Uber Coaches

Fortunately, there is always a balance in the universe. The people that balance out the power oriented architects are some of the true leaders in society, past and present. These are the people that live a value system intrinsically and that just becomes pervasive in the teams or groups with whom they work. They lead and they coach, they teach and are taught. After all, building software is a social exercise more than a technical exercise.
Here are some people that I think would have been fantastic agile coaches (in no particular order).

  • Mahatma Ghandi stopped ethnic violence between Hindus and Muslims by believing in the equality of everyone. There is one quote of his that stays with me when designing software: “The only solution is that which is just for everyone”. Ok, I may have got the exact wording wrong, but you know what I mean.
  • Bruce Lee was a man that sought perfection through serious introspection. He found meaning through the martial arts and when he found it, he realized it was not about the power but the subtleties of understanding yourself.  Again, something from Bruce Lee that helps me find build simpler solutions: “In building a statue, a sculptor doesn’t keep adding clay to his subject. Actually, he keeps chiselling away at the unessentials until the truth of its creation is revealed without obstructions”
  • Nelson Mandela forgave those that incarcerated him, completely and selflessly. And in doing that, he taught 45 million people that change is possible. He has an amazing ability to make everyone feel at ease with his humility. There is no private face nor public face. There is just him. So, for the toughest bits in every design, I turn to this great man: “It always seems impossible until its done.

Happy 90th Birthday, Madiba!

I just wish you could code as well as you coach 🙂

Power Oriented Architecture

I have been working on a project for the last 2 years.  It’s been 2 long years.  Those of you that know me personally will know the client.  The project has been technically challenging in the rather abstract domain of data and metadata.  Fascinating stuff, incredibly fun, bordering on pure research in a commercial environment.  We also committed to being agile in this project … with the client being agile, development being agile, project management being agile, everything agile.  It could not have been a better beginning.
It has been a spectacular mess!  It is a textbook on agile gone wrong.  It is a textbook on architecture gone wrong. It is a textbook on how not to write good code.  There are many lessons to be learnt and that has been the most valuable outcome of this project.  I will be speaking on some of these agile lessons at Oredev in November this year.  For now, I just want to reflect on one single thing that popped into my head during dinner with Chris Naidoo from Psybergate last night.

Here goes!  The project has failed because of power brokering.  Too many people are fighting for power.  Power gives control and control gives more power.  The fundamental value system of the entire team (client included) has been compromised because of the desire for power and control.

The net result is personal conflict.  Personal conflict is not healthy.  Conflict in driving at solving a problem is healthy.  If there is battle for power, there is always personal conflict because politicking will happen. Teams get fractured in power alliances and off-line caucusing occurs.  Egos are reinforced and confidences are destroyed.  One person posturing superior than the other, forever trying to be top dog for the sake of being top dog.  There is never a winner in a power battle and everyone loses.

At an architecture level, as designs emerged, they were shot down like moving tin ducks at a carnival game.  The power player won and the architecture and design that went into production was that of the person that had power at the time.  It was not the team’s architecture.  So there was not sense of responsibility in the team that resulted in no pride in work delivered.  Sensible and rational thinking is lost when a leader is blinded by power and the team exists without purpose.

So we had a power oriented architecture.  We also had a power oriented methodology.  And a power oriented value system.  And power oriented development.  I am not innocent.  I did my own bit of power grabbing as well.  I destroyed myself and violated my value system … a bit.  I did realise that if I stopped fighting against power, there will be no fight for power.

I have only 3 people from the original team, me included.  One of the power brokers has moved on to a position of greater power but has less direct influence on the team.  There is a new power player in the wings.  The team is fresh, new, no power battle scars.  So we won’t fight the battle.  Too many lives have been lost.  This is not Ghandi’s passive resistance.  To resist, even passively, is to take a position in the battle.  Instead, we will resort to a value system that treats people equally, responsibly and give each person the dignity they deserve.  I wish could give that dignity back to those that have left, fallen in battle.  You know who you are.  I wish I could have done more.

Architecturally, we have resurrected one of the tin ducks that was shot down about 18 months ago.  Not by me, but by someone else who came to the same solution independently.  But it’s not a “I told you so” situation … that will start the power battles again.  So BDUF has returned, TDD has returned.  The agile practices that we cherish and shout out will be implemented again, through natural and progressive adoption, each person adopting agile practices at their own pace, guided by a value system shared by all.

Power oriented architectures and power based management does not work.  Agile embraces a simple philosophy:  think about the next person before you think about yourself.  Agile is not about loss or gain of control, it is about collective ownership.  Once you grok that and live that, then it does not matter how bad your architecture is, how unreadable your code is, or how late your are on the project. It is simple: because the team is still equally responsible for everything, moving forward out of the mess, in small steps is do-able.  There is no blame because there is no power battle.

This project has changed me to be a worse person and it has changed me to be a better person.  I hope the others on the project have the same carthatic realisation that I had with Chris Naidoo.  Chris just didn’t know that happened during our conversation.  Now he knows.

By the way, I now realised that there are many power oriented architects in many teams that I have worked with in the past.  I just did not know that it was always a power issue.  Drop me note if you have come across any power oriented architects that create power oriented architectures.

Top Down SOA: Aligning Business Functions

Yesterday I had a really fun time running a workshop at the IQPC SOA conference on Structuring your SOA Project.  It was interesting to see that SOA is still not clearly understood and that the “silver bullet” answers are a still being sought after by a few.
The heart of my workshop centered on the theme that you cannot steer clear of business or domain knowledge, even if you try to design your services by wrapping existing software assets.  It just has to align to reality in the business, otherwise you will just create another architecture that has a fractured line to the business needs.

The other interesting theme that arose, unintentionally, was that it may well be easier to sneak in SOA by thinking in services and building some solutions covertly.  Once value is delivered and becomes noticeable, then start spreading out to the next cell … almost virally.

I summarised the main thoughts in the article on DZone at http://architects.dzone.com/articles/top-down-soa-aligning-business.

Tongue tied and twisted, just an earth bound misfit, I**

The architecture of business intelligence solutions is as archaic and carved in stone as a clay tablet from Mesopotamia.  It is old, stale, behind the times and controlled by a dictatorship that tries to portray a fake benevolence in all its propagandist messages.  The dictator is data itself.  Data has enslaved procedures and actions and treat them as second class citizens.  Every single time something needs doing, the data just force another action into slavery.
But everything is not everything.  A raucous revolt has been going on for a long time and there are just a few dictators hanging around clinging onto power.  The actions have created their own federated colony where they rule over the data.  “Rule” is a tough description.  Data are actually the protected citizens.  They are governed by a glorious constitution that ensures that their rights are not violated.  They behave within the guidelines of the constitution.

This new frontier is, indeed, a difficult world to understand.  It is even more difficult for the tourist companies putting together glossy brochures selling vacation trips to this world.  How do you describe a vacation utopia for something that is abstract.  Really, we can’t see an action but we can see data!  It is genuinely abstract; the action is a kind of energy that exists and binds the data.  It’s like saying that we can’t see the 4th dimension, but we understand it and know it exists because we can see the three dimensional shadows it casts into our universe.

If you’re still wondering what these extended metaphors are rambling about, then let me cut the meat closer to the bone.  BI architecture is stuck in stale techniques of moving and accessing data around the enterprise and it uses procedural techniques (the actions) to achieve this.  Everything is centered on data and data is centered on creating efficient actions as slaves.  In the world of equality – the one with the nice constitution – encapsulated behaviors (actions) protect the integrity of the data.  There are defined contracts and objects are the carriers for behavior and data.

There is so much that can be learned from this ignored world.  For example, the problems of scalability has been solved with statelessness.  Contention for shared resources have been solved with highly concurrent techniques that remove semaphores and other dead lock creating protection schemes.  The freedom to work with data in forms that are natural to the data is clean and efficient.  If data looks hierarchical in structure, then we can use use storage that naturally works with directed graphs, with lazy loading thrown in for good measure.  If data looks dimensional, then we can use a single multi-dimensional table that tolerates variant hash maps for individual columns.  If there is a need for massively parallel processing, then we can use map-reduction techniques over a distributed file system in a massive cluster of commodity hardware.

BI desperately needs change.  So throw away the clay tablets and start thinking laterally.  It’s a lot more flexible.  And if the tourist companies selling vacations want to take advantage of the new frontier, then they better understand the laws that govern this world.

Data exists because of the actions and not the other way around.  Get with the program and embrace the techniques, tools and agility of the new frontier to build better BI solutions, instead of trying to get everything to conform to that old clay tablet.  The body did not create consciousness, consciousness created the body.  Here’s the bottom line:  BI is stuck because it is a body without consciousness.

For me, I’m “just an earth bound misfit learning to fly” .   I’m still grappling with impedances and shear planes between these dichotomous worlds, trying to get others to see the value of using multiple disciplines for the symbiotic benefit of both.  I’m still “tongue tied and twisted” but a little step closer to “learning to fly”.

** Lyrics from “Learning to Fly” by Pink Floyd.

 Note: Most people know that I work for a company that crafts business intelligence solutions and that I work on the enterprise application development side of the company.  Unfortunately, I really do think that BI is lagging behind the times and that it needs a serious jolt.  The plethora of proprietary, non-agile tools and practices is still a problem.  Perhaps there are others out there that can enlighten me on the strides they have taken to built better BI architectures.

An Inconvenient Truth

I finally watched Al Gore’s documentary An Inconvenient Truth. Apart from the remarkable case put forward about the state of our planet, there was one tiny bit which caught my attention. Al Gore mentions two formulae in his presentation.

  1. Old Habits + Old Technology = Predictable Outcomes
  2. Old Habits + New Technology = Drastically Altered Consequences

Note: I may have got the wording a bit wrong but the essence is the same.

On the same weekend I was reading Jimmy Nilsson’s book Applying Domain Driven Design and Patterns (which is an excellent read, by the way). In the opening part of the book Jimmy describes what he has tried previously in his attempts to achieve good object oriented designs. By his own admission, he was not very successful. I’ll put my neck on the line and say that the problem was a case of formula 2 (but it’s not the first time I’ve been wrong :-))

I see formula 2 playing out often. A new technology emerges and we want to push the boundaries but our mindset is still a step behind. We use old habits with something new, miss the target, and sometimes create a mess of consequences which was never expected. I am certainly not innocent in this, either. To make matters worse, we sometimes use the “drastically altered consequences” to prematurely judge the new technology. The problem is not necessarily the technology, it is more likely that we used the new technology with a perspective of old habits. (Aside: Maybe formula 2 is also one reason for misuse of technologies.)

On the hand, I think formula 1 is the reason that we have legacy code and tried and tested technologies. The comfort and safety of old habits working with old technology makes a lot of sense. I still come across high quality Visual Basic 6 or Delphi applications written by highly productive teams that are not just in maintenance, but are actively being developed with new enhancements, etc.

In order to make a difference, we need to change our thinking which forces us to consciously alter our habits. It is only when we shift perspectives and behaviors will we be able to grasp a new technology or technique and make progress with minimal side-effects. The next time I am up against something new, I need to make a conscious effort to drop preconceptions and habits and make some adjustments.

There are some classic cases of formula 2 that I come across in many projects and teams. Here’s my top two.

  1. Relational/Set Oriented Thinking + Object Oriented Language = High Maintenance Consequences
  2. Stateful Client + Stateless HTTP = Low Scalability Consequences

What else have you come across?

Are your modules really modules?

I’ve been struggling with the problem of modules for almost my entire working life. And I am convinced that this area of architecture is one of the most underrated challenges. By definition, a module is a set of parts that can be used to construct a more complex structure. Let’s work backwards. Given a complete design or architecture for a problem domain, we should be able to break into parts and then reassemble these parts to reconstitute the original architecture. We, most probably, can justify any form of decomposition strategy, be it functional, sub-system boundaries, sources and sinks of data, etc. Working forwards is a lot more difficult. Creating parts from nothing that can then be assembled into a complex structure is not easy because we often don’t know what the final structure will look like. This exercise is complicated further when working in an agile manner, where a big design up front is against the grain of short, sharp iterations of analysis, design, test, code, release.

Now think back to the start of a new project, those days where you first tackled a new problem domain. Those days are spent analyzing the domain. And if it was complex domain, you most likely started fragmenting it so that it was conceptually possible to understand little parts at a time. Eventually, you reach a single point where everything clicks into place. That’s your light-bulb moment. It’s an immensely satisfying moment that is filled with a great sense of achievement. And with this fulfilling sense of accomplishment, you naturally carry that conceptual decomposition into the design exercises.

In this very act lurks the conflict. Our modular decompositions created for conceptual understanding is often carried, unconsciously, into architectural designs. In my experience, it is very seldom that the conceptual parts are left alone for conceptual understanding of the problem domain and that a separate effort is expended to focus on modular decomposition for architectural soundness. This resonates back to the days when a huge database design was created early in the project and it was the most static design artifact of the solution. Anything that came afterwards, was morphed to fit in with uber-database design.

I think that the reason for trying to maintain that static set of modules (or that database-design-cast-in-stone) is that refactoring of modules is very immature. At best, it is downright painful because it often results in pruning your source tree. Domain Driven Design is very explicit about modules. There are modules of varying granularity. Tiny modules made up of aggregates or an aggregate and its repository. Big, fat modules based on bounded contexts. Medium sized modules that cohesively fit together because they tell a story in the domain. This is great, but refactoring modules as you discover more of the domain is still frightening. But I digress and will elaborate on module refactoring in another post.

I do view modules as parts that can be assembled to construct the complex whole. But I also view modules as part of a graph, kind of. Every module has a meaningful domain relationship to another module. Each module needs another module to fulfill some feature that is required of the complex structure. It is rare for a module to be completely disassociated from every other module. If a module is disassociated, then is it part of the whole? Hence, the module graph perspective. The graph of modules is likely to be significantly different to the modules that are the result of conceptual decomposition during analysis. This graph of modules is a design exercise, not an analysis exercise. By focusing on domain correctness and meaningful relationships that are true within the problem domain, we can still achieve sound architectural principles. Each module has a public interface and shields internal complexity from its neighbors. This gives us low coupling and good separation of concerns that reflect the reality within the problem domain.

I also believe that using a domain driven design approach that focuses on reflecting reality, will allow for less painful experiences in refactoring modules because the domain must change significantly to force changes to the natural interconnection of its parts. Sure enough, when a business changes strategy, its domain changes which will result in significant changes to modules. But that’s an exception.

So, ask yourself these questions:

  • Are my modules artifacts of conceptual decomposition during analysis?
  • Can I combine my modules to reconstruct the complete complex structure?
  • Do my modules reflect the realities and deep truths of the problem domain?
  • Are my modules, modules?

Subtleties of Ubiquitous Language

There is a thought that has been floating in my mind like an infectious song over the last few weeks and it is Niclas Nilsson’s fault! He posed the question “AOP- Why don’t people get it?” The essence of AOP is the application of old fashioned patterns, mixins and interceptors, using, most commonly, run-time sub-classing techniques. Also, important is that the mixins and interceptors (i.e. the aspects) can be weaved into any object, immaterial of it’s type, place in a class hierarchy, etc. The fact that this happens at run-time in a non-linear fashion (sort of) creates this air of magic around AOP. Not to mention that AOP has some really weird terminology to describe previously well understood concepts.

Andrea Provaglio also participated in the discussion and made the observation that a style class in CSS is, perhaps, an aspect because it alters the appearance of the HTML element to which the CSS style is applied at run-time. Again, I think that if CSS was explained in the language of AOP, it would probably have taken a longer time to gain wide-spread acceptance. What CSS succeeded in doing was to apply a language set consistently, introducing new terms that could be explained using existing, easily understood terms. Even though certain terms (e.g. class) have different meanings when used in the CSS domain, these terms have a foundation in clearly understood concepts.

From a DDD perspective, the use of ubiquitous language is very apparent and thorough in the domain of AOP (i.e point cuts, join points, introductions, advices, etc.). However, I think that the bridge between the language set in the AOP domain and language set of the patterns domain and object orientation domain, from which AOP is derived, is missing. Let me clarify my point with another question: “Would AOP have gained greater acceptance and understanding if it adopted a ubiquitous language set that transitioned already understood concepts (interceptor, mixin, subclassing, etc.) to introduce the newer terms (point cut, join point, advice, etc.)?”

There are three DDD subtleties lurking here:

  1. Having a ubiquitous language is not enough; the language set must be easily understood and explain new terms using already understood terms. It’s like mathematics. We prove new theorems based on fundamental laws and the already proven theorems. Because we have confidence and faith in the fundamental laws and proven theorems, we gain confidence in the correctness of the new theorem. This results in the acceptance of the new theorem. Similarly, explaining new concepts in a problem domain using already understood and accepted concepts increases overall understanding.
  2. The ubiquitous language must aim for simplicity and high readability. If complex concepts are explained in a simple language that is highly readable, it is more likely that the concepts stand a better chance of being understood. Overall, our design and solution for the problem domain will stand a greater chance of acceptance from all stakeholders.
  3. As we explore and gain further understanding of the domain, our language set will change to introduce new terms, bridges between old and new terms, transitions from retired terms to superceded terms, deprecated terms, etc. This occurs during conversation and natural dialog in an attempt to gain further understanding of the domain. But we need to be aware of these changes. What we are actually doing is refactoring our ubiquitous language set. In DDD, the language of the domain is reflected in code. If we refactor our code, we are refactoring our language set. If we refactor our language set, we are refactoring our code.

DDD – Just Entities and Repositories?

Earlier this year Jimmy Nilsson of factor10 presented a great talk entitled “Domain Driven Design – Is it more than just Entities and Repositories?” at PBT Group in Cape Town.  I certainly agree with Jimmy: it is more than just entities and repositories.  While the entity, value object, repository, factory and other patterns are commonly sprinkled in a rich domain model, the subtleties of DDD such as bounded contexts in strategic design are easily forgotten.

A recent article on infoq.com raised the question Can DDD be adequately implemented with DI and AOP?  The arguments are valid in that infrastructure code can be best isolated from a rich domain model using AOP and DI.  This is not at all different to Mats Helander’s earlier article on Looking after your domain model.

However, I cannot help the aching feeling that a large part of DDD is being lost with an often blinkered focus on the lifecycle patterns (repositories, aggregates, factories, etc.) and structural patterns (entities, value objects, services, etc.).  For example, I am currently focusing a lot of energy with Tania van Niekerk (a work colleague) on the issue of designing for modularity.  Modularity is deceptively complex and DDD’s strategic design (bounded contexts, anti-corruption layers, transformations, etc) is certainly helping in us finding a solution.

My take:  I agree that AOP and DI do contribute in keeping infrastructure out of a domain model but, more importantly, I agree with Jimmy that there is a lot more to DDD than entities and repositories.

OSGi Cookbook: #1. A Simple Bean

This is something that I have been meaning to do for some time now, i.e. an OSGi cookbook. So this is the first in a series of recipes, with each one building on the next in usefulness and complexity. This recipe is really for newbies, just to take some of the mystery out of OSGi and to introduce some of the emerging tools for OSGi development.  If you have never done anything with OSGi before, then I recommend that you work through Neil Bartlett’s excellent series on getting started with OSGi.

Getting ready

 Ensure that you have maven andthe pax-construct scripts installed.The installation is straight forward, just follow the instructions on their respective web sites.

#1. A Simple Bean

This recipe creates a service out of a simple POJO. The service doesn’t do anything useful, but the recipe is a simple way to getyour development environment up and running.

  1. Create a project using pax-construct.The pax-construct scripts uses maven and the maven-pax-plugin.Using the familiar maven terminology of groupId and artifactId, create the project with a groupId of net.aslamkhan and artifactId of osgi-simplebean.
    /> pax-create-project -g net.aslamkhan -a osgi-simplebean
    ...
    [INFO] Archetype created in dir: /Users/aslam/projects/osgi/osgi-simplebean
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] ------------------------------------------------------------------------
  2. Have a look at what’s in the project and make sure that it does build cleanly (well, there’s actually nothing worthwhile to build here, but let’s make sure that everything is still ok).
    /> cd osgi-simplebean		
    /> ls -l
    -rw-r--r--   1 aslam  aslam  2354 Jan  9 10:26 pom.xml
    drwxr-xr-x   5 aslam  aslam   170 Jan  9 10:26 poms
    drwxr-xr-x   3 aslam  aslam   102 Jan  9 10:26 provision			
    /> mvn package
    ...
    [INFO] ------------------------------------------------------------------------
    [INFO] Reactor Summary:
    [INFO] ------------------------------------------------------------------------
    [INFO] net.aslamkhan.osgi-simplebean (OSGi project) .......... SUCCESS [1.689s]
    [INFO] osgi-simplebean - plugin configuration ................ SUCCESS [0.004s]
    [INFO] osgi-simplebean - wrapper instructions................. SUCCESS [32.144s]
    [INFO] osgi-simplebean - bundle instructions ................. SUCCESS [0.003s]
    [INFO] osgi-simplebean - imported bundles .................... SUCCESS [0.002s]
    ...
  3. We now need to add in the dependencies for Spring Dynamic Modules for OSGi.  Instead of hand crafting our maven pom.xml file(s), we again use a pax-construct script to add the repositoriesfor the Spring distributions.  From this point onwards, I will not show the output of commands unless it helps to illustrate a point.
    /> pax-add-repository -i spring-milestones 
       -u http://s3.amazonaws.com/maven.springframework.org/milestone
    /> pax-add-repository -i spring-snapshots 
       -u http://static.springframework.org/maven2-snapshots 
       -- -Dsnapshots "-Dreleases=false"
  4. Import the spring-osgi-extender bundle, and the slf4j logging service bundle.
    /> pax-import-bundle -g org.springframework.osgi 
       -a spring-osgi-extender -v 1.0-rc1 
       -- -DwidenScope -DimportTransitive

    If you look at the contents of the provision/pom.xml file, you will see a bunch of dependencies that have been pulled inthe moment we imported the spring-osgi-extender bundle.

    <dependency>
    	<groupId>org.springframework.osgi</groupId>
    	<artifactId>spring-osgi-extender</artifactId>
    	<version>1.0-rc1</version>
    	<scope>provided</scope>
    </dependency>
    ...
  5. Now that we have all the infrastructure things sorted out, we can start cooking. The quickest way to get cooking is to usethe pax-construct pax-create-bundle script. In this instance, we will create a sample bean with the necessaryboilerplate files needed for Spring Dynamic Modules. 
    /> pax-create-bundle -p org.example.bean 
       -- -Dspring -Djunit

    Notice that another directory org.example.bean has been created. Furthermore, this maven module has been added to the root (i.e. parent) ./pom.xml file. Also conveniently created, is asample bean and associated unit tests in org.example.bean/src directory.Edit the org.example.bean/src/main/resources/META-INF/spring/bundle-context-osgi.xml file to contain the following.

    <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"			  
        ...
        xmlns:osgi="http://www.springframework.org/schema/osgi"
        ...>
    	<osgi:service ref="myExampleBean">			        
    	  <osgi:interfaces>			            
    	    <value>org.example.bean.ExampleBean</value>			        
    	  </osgi:interfaces>			    
    	</osgi:service>
    </beans>
  6. We should be able to build this and fire it up in the Apache Felix OSGi implementation.  But wait!  We have not downloaded, nor installed Felix.  Not to worry, maven-pax-plugin will download Felix and fire it up for you, allpart of the pax:provision goal.
    /> mvn clean install pax:provision
    ... properties (org.springframework.context.service.name=org.example.bean)
    ->

    Let’s check if our org.example.bean bundle is installed and active. From the Felix console, enter the following.Also notice that the spring-osgi-extender bundle and spring 2.5 jars are now available as bundles as well.

    -> ps
    START LEVEL 6			   ID   State         Level  Name
    [   0] [Active     ] [    0] System Bundle (1.0.1)
    [   1] [Active     ] [    1] org.osgi.r4.compendium (1.0.0)
    [   2] [Active     ] [    1] Apache Felix Shell Service (1.0.0)
    [   3] [Active     ] [    1] Apache Felix Shell TUI (1.0.0)
    [   4] [Active     ] [    5] spring-osgi-extender (1.0.0.rc1)
    [   5] [Active     ] [    5] jcl104-over-slf4j (1.4.3)
    [   6] [Active     ] [    5] slf4j-api (1.4.3)
    [   7] [Active     ] [    5] spring-osgi-core (1.0.0.rc1)
    [   8] [Active     ] [    5] spring-osgi-io (1.0.0.rc1)
    [   9] [Active     ] [    5] spring-aop (2.5.0)
    [  10] [Active     ] [    5] spring-beans (2.5.0)
    [  11] [Active     ] [    5] spring-context (2.5.0)
    [  12] [Active     ] [    5] spring-core (2.5.0)
    [  13] [Active     ] [    5] spring-web (2.5.0)
    [  14] [Active     ] [    5] spring-test (2.5.0)
    [  15] [Active     ] [    5] aopalliance.osgi (1.0.0.SNAPSHOT)
    [  16] [Active     ] [    5] backport-util-concurrent.osgi (3.0.0.SNAPSHOT)
    [  17] [Active     ] [    5] slf4j-simple (1.4.3)			
    [  18] [Active     ] [    5] org.example.bean (1.0.0.SNAPSHOT)
    ->

    Now, check that the service is available.

    -> services
    ...
    org.example.bean (18) provides:
    -------------------------------			
    org.example.bean.ExampleBean
    org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext, 
    ...

That’s it for this recipe.  Overall, pax makes it really painless to get your OSGi implementation up and running in your developmentenvironment.  Combined with the convenience of spring-dm, we have the start of something really productive.