» tagged pages
» logout

sorted by: recent | see : popular
Content Tagged with Container + 2.0

Source for demos shown at NL-JUG session June 13th 2007

Alef Arendsen

Yesterday, Joris and I gave a session at the Dutch Java Users Group. We did the session twice and had about 250 people in total attending the sessions. A lot of people asked for the code for the demos we did during the sessions. Attached you'll find the code for the AOP and Dependency Injection demos. It shows a simple aspect flushing the Hibernate session before every JDBC operation (not as robust as you'd want it in production code, but it's a start) and it also shows the CarPlant system (demo'd before in other sessions and previously attached to another blog entry) configured using the various to do Dependency Injection in Spring 2.1 (i.e. using <bean>, @Bean and @Autowired).

It's a Maven2 project, so you'll need to have Maven2 installed. To prepare an Eclipse project including all libraries, run mvn eclipse:eclipse at the command line in the carplant directory.

The sources: carplant.zip

During the session a question came up about multiple <aop:config> blocks inside one application contexts. The guy in the audience wasn't sure if two or more blocks of AOP configuration showed the expected result (advising two or more times). I don't have the guys email address, so I wanted to clarify this here a little bit. Consider the following code. The doIt() will be advised. The actual advice (for simplicity) is kept in the same class, just as the main method bootstrapping the ApplicationContext.

public class Logger {

  public void doIt() {

  }

  public void log() {
    System.out.println("Log!");
  }

  public static void main(String args[]) {
    ApplicationContext context =
      new ClassPathXmlApplicationContext(
        new String[] {"com/carplant/context1.xml", "com/carplant/context2.xml"});

    Logger logger = (Logger)context.getBean("logger");

    logger.doIt();
  }
}

Configuration 1: one simple AOP config block

The file context2.xml is empty in this case, whereas context1.xml contains the following code:

<bean id="logger" class="Logger"/>

<aop:config>
        <aop:pointcut id="doItOperation" expression="execution(* doIt(..))"/>
        <aop:aspect ref="logger">
                <aop:before pointcut-ref="doItOperation" method="log"/>
        </aop:aspect>
</aop:config>

As expected, upon calling the doIt() method we'll only get one line of output from the logger (it's only advised once).

Configuration 2: two AOP config blocks in two different files

context2.xml now is identical to context1.xml (in the example above) with the only difference that in context2.xml we don't have bean called logger. When running this scenario, we'll see two Log! output entries. The doIt() method is advised twice.

Configuration 3: two AOP config blocks in the same configuration file

context2.xml is empty again. context1.xml on the other hand now contains two <aop:config> blocks. The only difference between the two is the pointcut identifier (this is an XML ID, so should be unique in the XML file).

<bean id="logger" class="Logger"/>

<aop:config>
        <aop:pointcut id="doItOperation" expression="execution(* doIt(..))"/>
        <aop:aspect ref="logger">
                <aop:before pointcut-ref="doItOperation" method="log"/>
        </aop:aspect>
</aop:config>

<aop:config>
        <aop:pointcut id="doItOperation2" expression="execution(* doIt(..))"/>
        <aop:aspect ref="logger">
                <aop:before pointcut-ref="doItOperation2" method="log"/>
        </aop:aspect>
</aop:config>

Running this will also show that the bean will be advised twice.

Note that I'm using a 2.1 milestone release here.

Spring: Interface21 Team Blog

Setter injection versus constructor injection and the use of @Required

Alef Arendsen

A couple of month ago, we start publishing polls on www.springframework.org asking people to provide their feedback about Spring, some of its features and how they are using those features. The first question I posted was whether or not people were checking required dependencies and if so, what mechanisms they used. I quickly followed up on this question asking the community what transaction management strategy it used.

To my delight when I first checked the results, back in March, a lot of people told us by voting in the first poll that they were using the @Required annotation. The second poll–on transaction management, quickly showed that a lot of people were using the @Transactional annotation. Below you can find some of the results of the poll about checking required dependencies. Together with the poll on transaction management (about 30% of all respondents are using the @Transactional annotation to demarcate transaction boundaries) they consistently show that people are using Spring 2.0 a lot, which was very good news for us. Because upgrading an application that uses Spring 1.x to use Spring 2.0 shouldn't be any issue, we really hoped people would not stick to Spring 1.x and in fact, people massively upgraded.

How are you checking required dependencies

8% I check them in my business methods
9% Using init-method and an assert mechanism (c.f. Assert)
9% Using the dependency-check attribute in XML
13% I don't have to, I use constructor injection
15% Using InitializingBean and an assert mechanism
17% Using the Spring 2.0 @Required annotation
29% I do not check required dependencies

What's interesting however is that 29 percent of all people do not check required dependencies. In the forum thread that accompanied the discussion, interesting suggestions came up as to why some people weren't doing this and how people solved it otherwise. Let's review some of those.

Constructor injection

I'd like to begin with reviewing constructor injection. Any object that has a constructor that takes arguments, can (obviously) not be constructed without passing in arguments. In Java, we have a default or implicit constructor added to our class as long as we do not add one ourselves. This default or implicit constructor does not take arguments, so as long as you do not add a constructor with arguments at all, or specifically add one without any arguments, it will be possible for Spring (or any other user of your class for that matter) to instantiate your class without passing it anything.

In other words, we can force a user of our class (again, this might be Spring but it could also be a unit test that instantiates your class directly) to instantiate it while passing in arguments.

public class Service {

  public Collaborator collaborator;

  // constructor with arguments, you *have* to
  // satisfy the argument to instantiate this class
  public Service(Collaborator collaborator) {
    this.collaborator = collaborator;
  }
}

We can use this to our advantage when in need to check required dependencies. If we modify the above code example to include assertions, we are 100% sure the class will never be instantiated without its collaborators injected:

public Service(Collaborator collaborator) {
  if (collaborator == null) {
    throw new IllegalArgumentException("Collaborator cannot be null");
  }
  this.collaborator = collaborator;
}

In other words, we do not need a dependency checking mechanism if we're using constructor injection in combination with an assertion mechanism like I've showed above.

Why do people not use constructor injection mostly

The question of course now is, why so few people are using constructor injection to enforce required dependencies, if it is the simplest way to get the job done! There are two reasons for this–one is a bit more historical, the other being the nature of the Spring Framework itself.

Historical reasons

Early 2003, when Spring was first published as an open source project, it primarily focused on setter injection. Other frameworks also pioneered ways of doing dependency injection and one of those was PicoContainer, which strongly focused on constructor injection. Spring maintained its focus on setter injection because at the time, we believed that the lack of default arguments and argument names for constructor arguments resulted in less clarity for developers. We however also implemented constructor injection, to be able to offer that feature to developers that wanted to instantiate and manage objects they didn't control.

This is one of the reasons why you're seeing a lot of setter injection throughout the Spring Framework itself. The fact that setter injection was used in Spring itself, as well as us advocating it mostly also caused many pieces of third-party software to start using setter injection as well as blog and articles to start mentioning setter injection.

(By the way, do people still remember type 1, 2 and M inversion of control ;-) )

Frameworks need to be a lot more configurable

The second reason why setter injection is used a lot more often than you would expect, is the fact that frameworks like Spring in general, are much more suited to be configured by setter injection than by constructor injection. This is mostly because frameworks that need to be configured often contain lots of optional values. Making optional values configurable using constructor injection would lead to needless clutter and proliferating constructors, especially when used in combination with class inheritance.

For those exact two reasons, I think constructor injection is much more usable for application code than it is for framework code. In application code, you inherently have a lesser need for optional values that you need to configure (you're application code is less likely to be used in many situations, which would require configurable properties). Second of all, application code uses class inheritance a lot less often than framework code does. Specialization in an application does not occur as often in application code as it does in framework code for example–again the number of use cases in which application code is far less.

So what should you use?

We usually advise people to use constructor injection for all mandatory collaborators and setter injection for all other properties. Again, constructor injection ensures all mandatory properties have been satisfied, and it is simply not possible to instantiate an object in an invalid state (not having passed its collaborators). In other words, when using constructor injection you do not have to use a dedicated mechanism to ensure required properties are set (other than normal Java mechanisms).

One of the other arguments for not using constructor injection is the lack of argument names in constructors and the fact that these do not appear in the XML. I would argue that in most applications, this does not matter that much. First consider the variant that uses setter injection:

<bean id="authenticator" class="com.mycompany.service.AuthenticatorImpl"/>

<bean id="accountService" class="com.mycompany.service.AccountService">
  <property name="authenticator" ref="authenticator"/>
</bean>

This version mentions the authenticator as a property name as well as a bean name. This is the pattern that I frequently encounter. I would argue that while using constructor injection, the lack of constructor argument names (and those not appearing in XML), doesn't really confuse us a lot.

<bean id="authenticator" class="com.mycompany.service.AuthenticatorImpl"/>

<bean id="accountService" class="com.mycompany.service.AccountService">
  <constructor-arg ref="authenticator"/>
</bean>

Using the alternative mechanisms

That brings us back to the topic of this blog entry, which also included a mention of @Required. This the new Spring 2.0 annotation we introduced back in 2006. @Required allows you to instruct Spring to check required dependencies for you. In case you are not in the position to use constructor injection, or for whatever other reasons, you prefer setter injection, @Required is the way to go. Annotation a property's setter an registering the RequiredAnnotationBeanFactoryPostProcessor as a bean in your application context is all you need to do:

public class Service {

  private Collaborator collaborator;

  @Required
  public void setCollaborator(Collaborator c) {
    this.collaborator = c;
  }
}

<bean class="org.sfw.beans.factory.annotation.RequiredAnnotationBeanFactoryPostProcessor"/>

Other mechanisms to check required dependencies

There are a few other mechanisms to enforce the checking of required dependencies. Most of those rely on Spring's ability to allow you to get callbacks at certain points in the construction an initialization of an object, such as the Spring InitializingBean interface or Spring's an arbitrary init method you can configure in the XML (using the init-method attribute). Those all resemble the use of constructor injection a lot, with the difference that you are relying on Spring to call the method in which the assertions take place for you.

public class Service implements InitializingBean {

  private Collaborator collaborator;

  public void setCollaborator(Collaborator c) {
    this.collaborator = c;
  }

  // from the InitializingBean interface
  public void afterPropertiesSet() {
    if (collaborator == null) {
      throw new IllegalStateException("Collaborator must be set in order for service to work");
    }
  }
}

Another mechanism, similar to @Required in Java is the dependency-check attribute in XML, which strangely enough is not used all that much. Enabling the dependency check by tweaking this attribute (it's turned off by default) will tell Spring to start checking certain dependencies on beans. Refer to the reference for more information about this features.

So why NOT check required dependencies

There are a lof of people that actually do not check if dependencies have been accurately set. The biggest reason people gave for not doing so is because they would find out quickly enough is they fired up the ApplicationContext and somehow used the classes that had dependencies. This is of course very true. If you're using Spring's integration testing support for example, you can have Spring load up an application context for you. If you're also making sure some of the actual code gets tested in your integration test, you can probably pretty much guarantee all the dependencies the classes need to work are set. It is an approach that bugs me a little bit though. You have to be confident in your test cases covering your code enough though, because if your tests do not test the code that depends on the collaborators being set, you're screwed, as you might not detect things! Of course a smoke test when you are deploying your application would probably do the trick right then and there, but I wouldn't want to be the one that only finds out about missing dependencies at runtime!

Conclusion

There is a lot to be said about constructor injection versus setter injection and I know a lot of people still prefer setter injection. I think though (and with me a lot of people) that constructor injection in combination with checking dependencies in your constructor is the better way (for code that does not have a lot of optional and configurable values or collaborators) to enforce checking of required dependencies. Combining this with final fields immediately gives you the other benefit of increased safety in a multi-threaded environment and because usually that does not prove to be a big deal anyway, I'm not going to touch on that in this blog entry.

There are situations in which I would not use constructor injection. One of those for example is a class with a lot of dependencies or other configurable values. I personally do not consider a constructor with 20 arguments as a good example of nice code. Of course, the question is, if a class with 20 dependencies does not have too many responsibilities…

One thing is for sure–enforcing required dependencies by checking them in your business methods is something I would certainly not do.

Spring: Interface21 Team Blog

Source for demos shown at NL-JUG session June 13th 2007

Alef Arendsen

Yesterday, Joris and I gave a session at the Dutch Java Users Group. We did the session twice and had about 250 people in total attending the sessions. A lot of people asked for the code for the demos we did during the sessions. Attached you'll find the code for the AOP and Dependency Injection demos. It shows a simple aspect flushing the Hibernate session before every JDBC operation (not as robust as you'd want it in production code, but it's a start) and it also shows the CarPlant system (demo'd before in other sessions and previously attached to another blog entry) configured using the various to do Dependency Injection in Spring 2.1 (i.e. using <bean>, @Bean and @Autowired).

It's a Maven2 project, so you'll need to have Maven2 installed. To prepare an Eclipse project including all libraries, run mvn eclipse:eclipse at the command line in the carplant directory.

The sources: carplant.zip

During the session a question came up about multiple <aop:config> blocks inside one application contexts. The guy in the audience wasn't sure if two or more blocks of AOP configuration showed the expected result (advising two or more times). I don't have the guys email address, so I wanted to clarify this here a little bit. Consider the following code. The doIt() will be advised. The actual advice (for simplicity) is kept in the same class, just as the main method bootstrapping the ApplicationContext.

public class Logger {

  public void doIt() {

  }

  public void log() {
    System.out.println("Log!");
  }

  public static void main(String args[]) {
    ApplicationContext context =
      new ClassPathXmlApplicationContext(
        new String[] {"com/carplant/context1.xml", "com/carplant/context2.xml"});

    Logger logger = (Logger)context.getBean("logger");

    logger.doIt();
  }
}

Configuration 1: one simple AOP config block

The file context2.xml is empty in this case, whereas context1.xml contains the following code:

<bean id="logger" class="Logger"/>

<aop:config>
        <aop:pointcut id="doItOperation" expression="execution(* doIt(..))"/>
        <aop:aspect ref="logger">
                <aop:before pointcut-ref="doItOperation" method="log"/>
        </aop:aspect>
</aop:config>

As expected, upon calling the doIt() method we'll only get one line of output from the logger (it's only advised once).

Configuration 2: two AOP config blocks in two different files

context2.xml now is identical to context1.xml (in the example above) with the only difference that in context2.xml we don't have bean called logger. When running this scenario, we'll see two Log! output entries. The doIt() method is advised twice.

Configuration 3: two AOP config blocks in the same configuration file

context2.xml is empty again. context1.xml on the other hand now contains two <aop:config> blocks. The only difference between the two is the pointcut identifier (this is an XML ID, so should be unique in the XML file).

<bean id="logger" class="Logger"/>

<aop:config>
        <aop:pointcut id="doItOperation" expression="execution(* doIt(..))"/>
        <aop:aspect ref="logger">
                <aop:before pointcut-ref="doItOperation" method="log"/>
        </aop:aspect>
</aop:config>

<aop:config>
        <aop:pointcut id="doItOperation2" expression="execution(* doIt(..))"/>
        <aop:aspect ref="logger">
                <aop:before pointcut-ref="doItOperation2" method="log"/>
        </aop:aspect>
</aop:config>

Running this will also show that the bean will be advised twice.

Note that I'm using a 2.1 milestone release here.

Spring: Interface21 Team Blog

ASM version incompatibilities, using Spring @Autowired with Hibernate

Alef Arendsen

I was working on Spring 2.1 stuff this week with Joris. We were preparing a sample using all three ways of doing dependency injection. The sample does not only highlight dependency injection, but also features a back-end based on Hibernate.

Several features in Spring 2.1 require the ASM byte code manipulation framework. Hibernate also uses ASM, through CGLIB. There is a binary incompatibility between ASM 1.5.3 and 2.2.3. The former is used by Hibernate, the latter is used by Spring in various scenarios; specifically in some of the AOP functionality and the new @Autowired features.

Solution no. 1

The first solution is to explicitly replace the CGLIB jar for Hibernate with a nodep version (one is available from the Spring distribution) which contains a re-packaged version of ASM version 1.5.3. With Maven, this requires you to put in a few exclusions alongside your Hibernate dependency and to explicitly put in the ASM 2.2.3 dependency in your pom.

<dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate</artifactId>
        <version>3.2.1.ga</version>
        <exclusions>
                <exclusion>
                        <groupId>asm</groupId>
                        <artifactId>asm</artifactId>
                </exclusion>
                <exclusion>
                        <groupId>asm</groupId>
                        <artifactId>asm-attrs</artifactId>
                </exclusion>               
        </exclusions>
</dependency>
<dependency>
        <groupId>asm</groupId>
        <artifactId>asm</artifactId>
        <version>2.2.3</version>                       
</dependency>

Solution no. 2

I haven't tried this, but according to the Hibernate JIRA you can change the byte code provider for Hibernate to Javassist, as commented by Max Rydahl Andersen in the bug report.

Spring: Interface21 Team Blog

Spring Web Flow Bean Scopes and JSF

Ben Hale

I've recently finished up an interesting issue in Spring Web Flow. This issue (SWF-163) dealt with adding Spring 2.0 bean scoping support for Spring Web Flow's internal scopes. The implementation isn't really that interesting (the Scope interface is pretty easy to implement after all), but I wanted to mention exactly how you would use something like this in your application.

Spring 2.0 Scoping

In Spring 1.x, we had the idea of singleton and prototype bean scopes, but the notation was fixed and not especially descriptive with singleton="[true | false]". So in Spring 2.0, this notation was removed from the XSD style of configuration and now you see a notation that is more clear with scope="[singleton | prototype | …]". Spring itself adds three more bean scopes; request, session, and globalSession which are related to web applications.

With the latest snapshots of Spring Web Flow 1.1, we now see bean scopes for the three major Web Flow scopes, flash, flow, and conversation.

<bean id="sale" class="org.springframework.webflow.samples.sellitem.Sale" scope="flash"/>
<bean id="sale" class="org.springframework.webflow.samples.sellitem.Sale" scope="flow"/>
<bean id="sale" class="org.springframework.webflow.samples.sellitem.Sale" scope="conversation"/>

To utilize these bean scopes you'll need to leverage the a new 1.1 version of the configuration (included in the Web Flow jar) and add a single element to your bean definition.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:flow="http://www.springframework.org/schema/webflow-config"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://www.springframework.org/schema/webflow-config
            http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.1.xsd"
>

        <flow:enable-scopes/>

        <bean id="sale" class="org.springframework.webflow.samples.sellitem.Sale" scope="conversation"/>

</beans>

The <enable-scopes/> tag only needs to exist once in a given application context and will allow you to use any of the three scopes contributed by Spring Web Flow.

Scoped Beans and JSF

Right now the most compelling use of these new scopes is in JSF. By using the scope notation in a standard Spring bean definition file instead of the <var/> notation in a flow definition, the experience for JSF users is much closer to standard JSF behavior. To add this ability to JSF you register the standard Spring JSF DelegatingVariableResolver. The other definitions (FlowNavigationHandler, and FlowPhaseListener) are standard for using JSF with Spring.

<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

<faces-config>
    <application>
        <navigation-handler>
            org.springframework.webflow.executor.jsf.FlowNavigationHandler
        </navigation-handler>
        <variable-resolver>
            org.springframework.web.jsf.DelegatingVariableResolver
        </variable-resolver>
    </application>

    <lifecycle>
        <phase-listener>
            org.springframework.webflow.executor.jsf.FlowPhaseListener
        </phase-listener>
    </lifecycle>
</faces-config>

The major change from the previous Web Flow enabled configuration is that now the variable resolver is the one from Spring and not Spring Web Flow. When a JSP page looks for a sale variable, JSF will delegate to Spring for bean resolution and the bean instance will be scoped according to the scope attribute on its definition.

Conclusion

The end result of this is that now JSF users can now use a syntax similar to the built-in style but in a container that is much more powerful.

If you'd like to use this new functionality, it will be coming shortly with the Spring Web Flow 1.1-m1 release, or you can get a preview by downloading the latest Spring Web Flow 1.1-m1 nightly snapshot.

Spring: Interface21 Team Blog

So what's the deal with Spring-OSGi?

Costin Leau

Welcome to my blog!
This is my first entry…ever. I manage to resist the urge of blogging but since so many people encouraged me to write about what I do at i21 I decided to give it a go. This and the fact that the Spring-OSGi had its first release yesterday evening (EET time zone).

I've been involved with Spring-OSGi since August last year and it has been quite a ride. It's one of the most challenging projects I have worked on and I'm glad to have it released, even as a milestone, to the public. Thanks a lot to everybody involved for making this happen, especially my team mates - Adrian, Andy and Hal!

In this entry, I'd like you give you a glimpse at what Spring 1.0 M1 provides at the moment; I'll skip introducing OSGi since there is plenty of excellent material available on the internet (see the links at the bottom).

The basic idea behind Spring-OSGi is to make it easy to build/write/deploy Spring applications in an OSGi environment. That is, to have the comprehensive POJO based programming model that Spring offers (IoC, AOP, service abstractions) working transparently in a dynamic execution environment which is focused on versioning and modularity.

One of the biggest challenges when adopting OSGi is dealing with its dynamic nature. Services (which are are simple object instances) come and go and your application has to deal with that. The solution is not straight forward, depends from case to case and requires an application-wide scope just like exception handling and transaction do. Classloading restrictions, enforced by the modularity mentioned, combined with AOP can cause a lot of grief and force the developer to create hacks, thus throwing out the window the benefits OSGi provides.
These are just a few examples of the things we are addressing in Spring-OSGi which in the end, should allow a smooth adoption path to OSGi.

Let's take a look at some of the features you'll find in 1.0 M1:

1. OSGi Application Context

OSGi is based on bundles which are nothing more then jars with some dedicated manifest entries. They are modules, units that export and import class packages and/or services.
An application can be composed of one or multiple bundles. Spring-OSGi provides an application context which builds on top of a bundle and its lifecycle, giving you access to the OSGi context in which the application lives, an OSGi custom scope as well as an extra Aware interface. As the rest of its ilk, the interface provides the ability to do dependency lookup, something you should think twice before using as OSGi service dependency injection is fully supported.

2. Resource abstraction

Classloading is not what is used to be in OSGi - the classpath for example has a different meaning since it can be assembled from multiple bundles (which in turn, can be used in more then one classpath). Thus getClass().getResource() can have a different outcome as the environment in which are running has changed quite a lot. Here is an example of what you might get in case you are looking for a class:

Equinox: bundleentry://5/my/package/MyClass.class (can be also bundleresource://)
Knopflerfish: bundle://13/my/package/MyClass.class
Felix: bundle://18.0/0/my/package/MyClass.class

Relying on URL schemes is not portable thus one of the first things done in Spring OSGi was to encapsulate low-level access through the simple, yet effective Resource interface, so no matter what OSGi implementation you are using, you can find your files. Moreover, pattern style lookups such as myFolder/* are possible (in fact we are using /META-INF/spring/* to detect 'spring powered' bundles).

3. Dynamic service support

Suppose you have the following application context:

<!– service layer–>
<bean id="myService" class="ServiceClass">
    <property name="dao" ref="dao"/>
</bean>

<!– dao layer –>
<bean id="dao" class="poorPerformerDAO">
    <property name="dataSource" ref="someDataSource"/>
</bean>

Most of the application have several layers which are excellent candidates for OSGi bundles since one can simply put the DAO classes in one bundle (the dao bundle), the service layer in another (service bundle) so when the DAOs implementations are updated (for example poorPerformerDAO above is replaced with excellentPerformerDAO) or a different version of the application is being deploy, no application restarts are required: one of the best reasons to choose OSGi!

However, to take advantage of the OSGi capabilities, the objects have to become services - that is, they have to be registered with the OSGi platform before being 'consumed' while the consumer (client) has to look for them. It's an SOA-like approach which avoids tight coupling between modules so when a bundle is shut down, the services published by it disappear. Which means that one first has to use the OSGi APIs to do the registration and lookup but also has to deal with failure as services can come and go.

Spring-OSGi greatly helps in this area by allowing literally any type of object to be exported and imported in your application without any code change.

Service Bundle:

<!– service layer–>
<bean id="myService" class="ServiceClass">
    <property name="dao>
       <osgi:reference interface="
daoInterface"/>
    </property>
</bean></code>

Dao Bundle:

<!– dao layer –>
<bean id="dao" class="goodPerformerDAO">
    <property name="dataSource" ref="someDataSource"/>
</bean>

<osgi:service ref="dao"/>

With Spring-OSGi to accomodate to the OSGI environment, two lines of configurations have to be added:

  1. to instruct the framework what OSGi service to look for
  2. to export an existing bean as an OSGi service

Obviously the same can be done for the dataSource dependency - externalize it into an OSGi bundle and just replace the straight refwith an osgi:reference. No new APIs to deal with, no exceptions to try/catch/finally for and especially built-in lookup behavior.
Spring-OSGi can be instructed so that the application context does not start unless a service implementating daoInterface is found - that is, the dao dependency can be satisfied. Moreover, at runtime if the service goes away, Spring-OSGi will automatically look for a new implementation based on your configuration (number of retries and timeout): if a call is invoked on 'dao' bean exactly when the owning bundle is updated (for example to upgrade goodPerformerDAO to excellentPerformerDAO) instead of getting a nasty, apparently inexplicable exception, one will get an imperceptible delay caused by new service lookup. As always, the behavior is fully configured.

To some degree the exporter/importer functionality resembles Spring remoting with the big difference that there is no remoting involved - everything is running in the same VM and there is no serialization involved what so ever.

4. Integration testing

Testing is important (even crucial) especially when migrating an application to a new environment, as a lot of things taken for granted can simply fail: we experienced this ourselves quite early on in development. This has been a big issue since testing was anything but easy or automated when talking about OSGi since the execution environment (the OSGi platform or container if you'd like) has to be started (no standardized API) and setup (install the bundles your test depends on). However the tricky part is that the test itself has to be OSGified - placed along side a manifest which declares the dependencies, into a bundle which has to be installed and started into the OSGi platform.

Meet AbstractOsgiTests & co:

public class SimpleIntegrationTests extends AbstractConfigurableBundleCreatorTests
{

  public void testInstalledBundles() {
    // get access to the OSGi bundle context
     Bundle[] bundles = getBundleContext().getBundles();

     getBundleContext().installBundle(someBundleLocation);
     assertEquals(bundles.length()+1, getBundleContext().getBundles().length());
  }

  // specify the bundles to install 
  protected String[] getBundles() {
        return new String[] {
                "org.springframework.osgi, commons-collections.osgi, 3.2-SNAPSHOT",
                "org.springframework.osgi, org.springframework.osgi.test.simple.service,1.0-SNAPSHOT"};
    }
}

AbstractOsgiTests builds on top of JUnit so you can write and run OSGi integration tests directly from your IDE. The entire setup is handled by the testing infrastructure so you don't have to: no need to write a MANIFEST.MF for your test, to do any packaging or deployment - everything is handled automatically. And it's fast, extremely fast! In fact, less then 10% percent of the startup time is spent inside Spring-OSGi code - the rest is used by the OSGi platform itself. Most of our integration tests are fully executed in 1-3 seconds each. Equinox, Knopflerfish and Felix are all supported.

Well, I think that's enough for a first entry… I'll write more about Spring-OSGi features in future entries. I hope I've made you curios enough to take 1.0 M1 for a spin (please note that it's the first milestone and it has some 'rough edges').

Thanks for reading!
Costin

OSGi Alliance which has some nice intros and whitepapers
Wikipedia
EclipseCon OSGi track
Spring-OSGi specification
Javapolis 2006 presentation on Spring-OSGi (by yours truly)
Last, but not least, good ol' Google.

Spring: Interface21 Team Blog