Are there any good/best practices regarding the combination of Spring configuration and OSGi Blueprint (e.g. Gemini Blueprint)? Which XML files do you use? Where do you put them in your OSGi bundles (META-INF/spring
, OSGi-INF
)? Which of these practices will allow you to reuse your bundles in combination with a non-Gemini-implementation of Blueprint?
Background: We are in the process of switching from Spring/Spring DM to Spring/Blueprint. I am aware of Blueprint defining a <bean>
element. However we occasionally face the situation that the limited bean definition capabilities of the Blueprint specification do not meet all our needs. So it seems to be a good choice to use Spring configuration within our bundles and Blueprint for wiring bundles via OSGi services.
Which XML files do you use? Where do you put them in your OSGi bundles (META-INF/spring, OSGi-INF)? Which of these practices will allow you to reuse your bundles in combination with a non-Gemini-implementation of Blueprint?
Gemini Blueprint treats both of these directories equally, but OSGI-INF/blueprint/*.xml
is the only one specified in the generic OSGi Blueprint specification.
A suggested practice from the Gemini Blueprint documentation is:
[...] A suggested practice is to split the application context configuration into at least two files, named by convention modulename-context.xml and modulename-osgi-context.xml. The modulename-context.xml file contains regular bean definitions independent of any knowledge of OSGi. The modulename-osgi-context.xml file contains the bean definitions for importing and exporting OSGi services. It may (but is not required to) use the Gemini Blueprint OSGi schema as the top-level namespace instead of the Spring 'beans' namespace.
I tried this, and it works great. I use Gemini Blueprint for one of my projects which has the files META-INF/spring/context.xml
, which defines my beans and their relationships, and META-INF/spring/osgi-context.xml
, which defines which beans to expose as/import from OSGi services and how. context.xml
looks like
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="myOrdinarySpringBean" class="com.acme.impl.Foo"/>
</beans>
and is a regular ordinary Spring application context with no Blueprint/OSGi configuration at all. osgi-context.xml
looks like
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<service id="myOsgiService" ref="myOrdinarySpringBean" interface="com.acme.Foo"/>
</blueprint>
You could, of course, use the <beans>
namespace and root element here as well, but you'd have to define a xmlns:osgi
and prefix the service like so: <osgi:service .../>
for that to work. In my case I don't need the Gemini specific Blueprint stuff, so I'm happy with this generic Blueprint configuration. Likewise, I could use the <blueprint>
namespace in context.xml
as well, but this particular application is an old one being ported to OSGi, so I prefer to keep that configuration Spring specific for now.
Another application in turn has its own osgi-context.xml
like
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<reference id="myOrdinarySpringBeanImportedFromOsgi" interface="com.acme.Foo" availability="mandatory"/>
</blueprint>
and at this time doesn't, but could, have its own context.xml
like
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="myOrdinaryOtherSpringBean" class="com.acme.impl.Bar">
<property name="foo" ref="myOrdinarySpringBeanImportedFromOsgi"/>
</bean>
</beans>
and couldn't really care less whether myOrdinarySpringBeanImportedFromOsgi
is imported from an OSGi service or defined as a regular ordinary Spring bean in the same application context.
These META-INF/osgi-context.xml
configurations could trivially be moved to OSGI-INF/blueprint/
if I want to decouple yourself from the Gemini Blueprint implementation, but for the time being I prefer to keep the two halves in the same place to avoid making a mess of the directory structure.
Blueprint files should go under OSGI-INF/blueprint/ and are named *.xml (typically blueprint.xml). This location is per the OSGi 4.2 Blueprint spec and will work with Aries or Gemini.
Spring-DM files (as you probably know) go under META-INF/spring/ and are also named *.xml (typically beans.xml)
Both files should be able to peacefully co-exist. They'll only work, though, if you have support for each container installed.
Wiring should be done via the OSGi Service Registry.
As for migration, we have stayed on Spring-DM for capabilities that we couldn't do in Blueprint. Everything else has been migrated to Blueprint.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With