This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

Load time weaving with OSGi is a problem area. When a class is weaved as it's loaded, new dependencies may be introduced which won't be imported in the bundle's manifest. This will lead to ClassNotFoundExceptions at runtime. There is some work being done on load time weaving and OSGi by the Equinox aspects project.

My recommendation at this time is to avoid the use of load-time weaving and, instead, to use compile-time weaving along with a tool like Bundlor to generate the bundle's manifest after compile-time weaving has taken place. This will ensure that any dependencies that are introduced by the weaving are imported in the bundle's manifest.

Comment

Is it possible to publish a Service from one bundle and use it in another bundle -- attempting LTW on it -- and publishing it again with a higher rank? StackOverFlowError is encountered when a ServiceInterface call is made on a bean that is weaved!!!

Comment

I can see that bundle 1 is both publishing and consuming the HelloService, but I can't see how bundle 2 is accessing this service. Apologies if I've missed something. Can you please let us know how bundle 2 is consuming and then republishing the service.

Also, it would be useful to see some more of the stacktrace. From the snippet you've posted it's not clear how the overflow is occurring as I can't see any obvious repetition in the stack, e.g. isMethodOnIntroducedInterface is only being called once.

BundleConsumer - consumes the weaved service (by mentioning the filter with bean name in osgi service)

This works fine. But the drawback with this approach is that aspect and the consumer are tightly bound. Then I tried to modify my sample on the same lines as you mentioned to use ranking , so that we can use get away with the dependency(filter name). But no luck , I too got the same exception

Code:

Exception in thread "timerFactory" java.lang.StackOverflowError
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.getService
(BundleContextImpl.java:658)
at org.springframework.osgi.service.importer.support.internal.support.Se
rviceWrapper.getService(ServiceWrapper.java:99)
at org.springframework.osgi.service.importer.support.internal.aop.Servic
eDynamicInterceptor$ServiceLookUpCallback.doWithRetry(ServiceDynamicInterceptor.
java:107)
at org.springframework.osgi.service.importer.support.internal.support.Re
tryTemplate.execute(RetryTemplate.java:83)
at org.springframework.osgi.service.importer.support.internal.aop.Servic
eDynamicInterceptor.lookupService(ServiceDynamicInterceptor.java:430)
at org.springframework.osgi.service.importer.support.internal.aop.Servic
eDynamicInterceptor.getTarget(ServiceDynamicInterceptor.java:415)
at org.springframework.osgi.service.importer.support.internal.aop.Servic
eInvoker.invoke(ServiceInvoker.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doP
roceed(DelegatingIntroductionInterceptor.java:131)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.inv
oke(DelegatingIntroductionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.osgi.service.importer.support.LocalBundleContextA
dvice.invoke(LocalBundleContextAdvice.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doP
roceed(DelegatingIntroductionInterceptor.java:131)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.inv
oke(DelegatingIntroductionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
cAopProxy.java:202)
at $Proxy117.dumy(Unknown Source)
at sun.reflect.GeneratedMethodAccessor58.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflecti
on(AopUtils.java:307)
at org.springframework.osgi.service.importer.support.internal.aop.Servic
eInvoker.doInvoke(ServiceInvoker.java:58)
at org.springframework.osgi.service.importer.support.internal.aop.Servic
eInvoker.invoke(ServiceInvoker.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doP
roceed(DelegatingIntroductionInterceptor.java:131)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.inv
oke(DelegatingIntroductionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.osgi.service.importer.support.LocalBundleContextA
dvice.invoke(LocalBundleContextAdvice.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doP
roceed(DelegatingIntroductionInterceptor.java:131)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.inv
oke(DelegatingIntroductionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
cAopProxy.java:202)
at $Proxy117.dumy(Unknown Source)
at sun.reflect.GeneratedMethodAccessor58.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflecti
on(AopUtils.java:307)
at org.springframework.osgi.service.importer.support.internal.aop.Servic
eInvoker.doInvoke(ServiceInvoker.java:58)
at org.springframework.osgi.service.importer.support.internal.aop.Servic
eInvoker.invoke(ServiceInvoker.java:62)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doP
roceed(DelegatingIntroductionInterceptor.java:131)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.inv
oke(DelegatingIntroductionInterceptor.java:119)

Comment

The problem is that when you are specifying a ranking for a service you are, somewhat, changing the importance of exported services in an OSGi environment.

Let's consider your sample. In BundleXAspect you are importing one service that is differentiated by interface then you are exporting the proxied service that has the same discriminator - the interface. But, upon re-export you are exporting a service that has a higher discriminator and which will make BundleXAspect to consider this service, as well, as an imported service.

BundleXAspect will get to use its own exported service and then re-export it. Let's consider a concrete example:
- service exported by BundleX is S
- BundleXAspect imports S
- AOP makes a proxy from S and it generates P1
- P1 is exported with rank 20 (for example) which is greater than 0 (the default)
- BundleXAspect re-imports P1 because it has a greater ranking
- AOP transforms P1 in P2 and it's exported; but BundleXAspect will not use P2 because it already has a "good" service (P1 - the same rank as P2)
- when the exported service (P2) is called by BundleConsumer, P2 will call P1 because this is the proxied target. P1 is, in fact, a Spring DM proxy to a service from service registry and because it's a dynamic one, when called, will invoke the best service available at the moment in the registry which is P2. And now the cycle begins.

Comment

How about always weaving your service with an aspect that looks for a particular kind of service in the service registry and, if it finds one, it calls the appropriate method(s) on the service? Basically you'd move all of the actual logic out of your aspect and into this service and the aspect would simply delegate to it.

Comment

aused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'sticky' of bean class [org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean]: Bean property 'sticky' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:877)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:722)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:78)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:60)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1332)
... 21 common frames omitted

Comment

aused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'sticky' of bean class [org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean]: Bean property 'sticky' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:877)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:722)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:78)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:60)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1332)
... 21 common frames omitted