dlkpochtaws
May 14th, 2008, 01:47 AM
We are using Spring v2.5+ Spring Dynamic Modules in OSGi container, Felix in our case.
Also we are planning to use Spring’s @Component scanning.
<context:component-scan base-package="org.package" />
But unfortunately it appears Spring DM does not support component-scanning. Because it assumes
ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX= "classpath*:"
can not be resolved in OSGi environment. I agree it can not be resolved for all possible cases.
But in our situation, we assume, components must be scanned only in current bundle.
So, we’ve created a small aspect:
/**
* Aspect help class scaner from spring-context to receive classes from bundle with
* bundle specific PatternResolver
* @author Ivan Martyushev
* 25.03.2008
*/
@Aspect
public class ClasspathPrefixForOsgiAspect {
private Logger logger = LoggerFactory.getLogger(ClasspathPrefixForOsgiAspe ct.class);
@Pointcut("execution(* " +
"org.springframework.osgi.context.support.AbstractO sgiBundleApplicationContext.getResources(String)) " +
"&& args(locationPattern)")
void execution_getResources(String locationPattern) {
}
@Around("execution_getResources(locationPattern)")
public Resource[] around_getResources(ProceedingJoinPoint methodExecution, String locationPattern) throws Throwable {
logger.debug("Current locationPattern = {}", locationPattern);
return (Resource[]) methodExecution.proceed(new Object[] {fixLocationPatternIfNeeded(locationPattern)});
}
String fixLocationPatternIfNeeded(String locationPattern) {
if ((locationPattern.startsWith(ResourcePatternResolv er.CLASSPATH_ALL_URL_PREFIX))) {
String result = OsgiBundleResource.BUNDLE_URL_PREFIX +
locationPattern.substring(ResourcePatternResolver. CLASSPATH_ALL_URL_PREFIX.length());
logger.debug("FixedLocationPattern = {}", result);
return result;
}
return locationPattern;
}
}
As we can see, this aspect catches calling to AbstractOsgiBundleApplicationContext.getResources( String) and converts resorcepaths with CLASSPATH_ALL_URL_PREFIX to resourcepaths from current bundle (BUNDLE_URL_PREFIX).
Of course, this solution is not suitable for all, but it is enough for some cases. It would be nice to have similar approach in Spring DM out of the box. In any case, by default it just generates an exception - not a user-friendly approach:-)
Also we are planning to use Spring’s @Component scanning.
<context:component-scan base-package="org.package" />
But unfortunately it appears Spring DM does not support component-scanning. Because it assumes
ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX= "classpath*:"
can not be resolved in OSGi environment. I agree it can not be resolved for all possible cases.
But in our situation, we assume, components must be scanned only in current bundle.
So, we’ve created a small aspect:
/**
* Aspect help class scaner from spring-context to receive classes from bundle with
* bundle specific PatternResolver
* @author Ivan Martyushev
* 25.03.2008
*/
@Aspect
public class ClasspathPrefixForOsgiAspect {
private Logger logger = LoggerFactory.getLogger(ClasspathPrefixForOsgiAspe ct.class);
@Pointcut("execution(* " +
"org.springframework.osgi.context.support.AbstractO sgiBundleApplicationContext.getResources(String)) " +
"&& args(locationPattern)")
void execution_getResources(String locationPattern) {
}
@Around("execution_getResources(locationPattern)")
public Resource[] around_getResources(ProceedingJoinPoint methodExecution, String locationPattern) throws Throwable {
logger.debug("Current locationPattern = {}", locationPattern);
return (Resource[]) methodExecution.proceed(new Object[] {fixLocationPatternIfNeeded(locationPattern)});
}
String fixLocationPatternIfNeeded(String locationPattern) {
if ((locationPattern.startsWith(ResourcePatternResolv er.CLASSPATH_ALL_URL_PREFIX))) {
String result = OsgiBundleResource.BUNDLE_URL_PREFIX +
locationPattern.substring(ResourcePatternResolver. CLASSPATH_ALL_URL_PREFIX.length());
logger.debug("FixedLocationPattern = {}", result);
return result;
}
return locationPattern;
}
}
As we can see, this aspect catches calling to AbstractOsgiBundleApplicationContext.getResources( String) and converts resorcepaths with CLASSPATH_ALL_URL_PREFIX to resourcepaths from current bundle (BUNDLE_URL_PREFIX).
Of course, this solution is not suitable for all, but it is enough for some cases. It would be nice to have similar approach in Spring DM out of the box. In any case, by default it just generates an exception - not a user-friendly approach:-)