Tuesday, April 13, 2010

Useful OSGi(Spring DM) utilities

Using OsgiServiceProxyFactoryBean to create proxy(equivalent to osgi:ref)

I had usecase where i could not use osgi:ref or osgi:list to reference a service ,because when the proxy is created it
creates on the generic interface given, which that particular bundle can see.

To get away with this usecase , we created proxies using API's.


OsgiServiceProxyFactoryBean proxy = new OsgiServiceProxyFactoryBean();
proxy.setInterfaces(new Class[] {cls});


There is a distinction between the OSGi bundle state and the state of the BundleInstallArtifact. The latter is displayed by the shell "bundle" commands.

BundleInstallArtifact only transitions to ACTIVE when any Spring DM application context has been published in the service registry. The OSGi bundle may
transition to ACTIVE earlier than this as it does not take into account publication of any Spring DM application context.

The transition to ACTIVE state starts either when the bundle is started or, in the case of lazy activation, after the bundle has been started and then
the first class is loaded from the bundle.


Bundle-Version: 10.0.0

Export-Package: com.test

There is no relationship between the bundle and the package version. It's fairly often that a bundle version increases while the bundle package doesn't
(for example the new bundle provides only extra resources or extra packages).

Exported packages by default are versioned at 0.0.0


When I hit a bundles list command on the dm shell it shows as follows

DM Shell output

43 com.springsource.osgi.webcontainer.core 1.0.0.M1 ACTIVE
44 S com.springsource.osgi.webcontainer.tomcat 1.0.0.M1 ACTIVE
45 S com.springsource.server.web.core 2.0.0.RELEASE ACTIVE
46 com.springsource.server.web.dm 2.0.0.RELEASE ACTIVE
47 com.springsource.server.web.tomcat 2.0.0.RELEASE ACTIVE
48 com.springsource.javax.annotation 1.0.0 ACTIVE

S means "Spring powered", i.e. with Spring (DM) XML files.

Useful Spring Utilities(API's)

1. Default behaviour of Spring is that , when same names beans are loaded in a single applicationContext , the first bean will
be overridden by the latter.

We had usecase where we required to get an error when multiple beans had the same name.

I have to extend ClassPathXmlApplicationContext and overide this method as it was protected.

public void setAllowBeanDefinitionOverriding(
boolean allowBeanDefinitionOverriding) {

ctx.afterPropertiesSet(); //will initialize the context

2. To get teh number of beans initialized by the application Context.


3. To get the resouces read by created ApplicationContext based ona regular Expression.
[This is very handy in an integratde environment to exactlt know the resources ]

I had to extend ClassPathXmlApplicationContext as this method was protected.

protected Resource[] getConfigResources() {
// TODO Auto-generated method stub
return super.getConfigResources();

Resource[] resources = ((ResourcePatternResolver) ctx).getResources("classpath*:/META-INF/spring/conf*.xml");

where ctx is the initialized applicationContext.

4. If we need multiple definitons for <context:property-placeholder/>

Only one context:property-placeholder (the last one defined in the configuration files) will prevail.
You can define two separate PropertyPlaceholderConfigurers and work, only if the second one has a different placeholderPrefix and placeholderSuffix.

< bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
< property name="location" value="classpath:/com/foo/2.properties" / >
< property name="placeholderPrefix" value="#[" / >
< property name="placeholdersuffix" value="]" / >
< / bean >

< bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
< property name="location" value="classpath:/1.properties" / >
< / bean >

Normal way of replacing is ${property1} and with new prefix and suffix #[]

Difference between Classpath:* & Classpath*: in Spring

The difference between these two is the way the resources are found when a regular expression is given for match.

classpath*: -> This special prefix specifies that all classpath resources that match the given name must be obtained
(internally, this essentially happens via a ClassLoader.getResources(...) call), and then merged to form the final application context definition.

Ex classpath*:app*.xml && classpath:app*.xml is

With spring xmls, app1.xml and app2.xml and beans in app2.xml referring to app1.xml

- classpath:app*.xml will give errors if app1.xml and app2.xml are in two different classpath folders(It tries to find a matching app1 or app2 in classpath , and when
found doesnt continue to search further with other classpath locations.)

- classpath*:app*.xml will never give errors(searches for all classpath folders)

classpath* will search all classpath folder whereas classpath: will concentrate on one resource.

This also works for location attribute of PropertyPlaceHolderConfig

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath*:jdbc.properties"></property>

But important thing to be noted here is that property name is locations and not location.

One more difference with classpath*:config.xml and classpath:*config.xml

is that

classpath:*config.xml - if file(matching *config) isnt present it shows error in console

classpath*:*config.xml just ignores teh error if no file is present in the classpath.

classpath*: basically refers to a list of resources and a list can be empty.
classpath: simply points to a certain resource and if this is empty (where one would have expected it to exist) it would generate an error.


Note that "classpath*:" when combined with Ant-style patterns will only work reliably with at
least one root directory(IMPORTANT) before the pattern starts, unless the actual target files
reside in the file system.This means that a pattern like "classpath*:*.xml" will not retrieve
files from the root of jar files but classpath*:META-INF/* will search as expected.

Free Domain Names @ .co.nr!