Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Aspectj Load time weaving support in Dm 2.0

  1. #1
    Join Date
    Nov 2008
    Location
    London,UK
    Posts
    299

    Default Aspectj Load time weaving support in Dm 2.0

    I wanted to know if AspectJ Load time time weaving is supported in Dm 2.0 ?

  2. #2
    Join Date
    Oct 2008
    Posts
    493

    Default

    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.
    Andy Wilkinson
    SpringSource

  3. #3
    Join Date
    Nov 2008
    Location
    London,UK
    Posts
    299

    Default

    Thanks Andy. As per your suggestion i will try the other two approaches

    Compile time weaving and spring Aop. I assume these two should work fine and let you know in case of any issues.

  4. #4
    Join Date
    Nov 2009
    Posts
    3

    Default

    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!!!

    e.g.
    Code:
    Bundle1
    -------
    	<bean id="helloService" class="com.test.svc.impl.HelloServiceImpl" />
    
    	<osgi:service ref="helloService" interface="com.test.svc.HelloService" ranking="5" />
    
    	<osgi:reference id="helloSvc" interface="com.test.svc.HelloService" cardinality="0..1" timeout="100" />
    	
    	<bean id="testHello" class="com.test.svc.impl.TestHello" init-method="init" destroy-method="destroy">
    		<property name="helloService" ref="helloSvc" />
    	</bean>
    
    
    public class HelloServiceImpl implements HelloService {
    	private static int cnt = 1;
    	
    	public String sayHello() {
    		String msg = "*** HelloServiceImpl...sayHello() called *** cnt=" + (cnt++);
    		System.out.println(msg);
    		return msg;
    	}
    }
    
    public class TestHello {
    	private boolean forever = true;
    	private HelloService helloService;
    	
    	public void setHelloService(HelloService helloService)	{
    		this.helloService = helloService;
    	}
    	
    	public void init()	{
    		new Thread(new Runnable(){
    			public void run()	{
    				while (forever)	{
    					try {
    						System.out.println("*** Calling sayHello()..." + new Date());
    						helloService.sayHello();
    					} catch (ServiceUnavailableException e)	{
    						System.out.println("*** HelloService is unavailable...");
    					}
    					try {
    						Thread.sleep(10000);
    					} catch (InterruptedException ie) {
    						// ignore
    					}
    				}
    			}
    		}).start();
    	}
    	public void destroy()	{
    		forever = false;
    	}
    }
    
    Bundle2 with Aspect
    -------------------
    	<bean id="helloAdvice" class="com.pg.aspect.HelloAdvice" />
    	
    	<context:component-scan base-package="com.pg.aspect" />
    	<context:load-time-weaver aspectj-weaving="on" />
    
    @Aspect
    public class HelloAdvice {
        @Pointcut("execution(* com.test.svc.HelloService.sayHello(..))")
        public void aspectjLoadTimeWeavingHello() {
        }
    
        @Around("aspectjLoadTimeWeavingHello()")
        public Object adviceHello(ProceedingJoinPoint pjp) throws Throwable {
    		System.out.println("*** Inside HelloAdvice called....");
    		try {
    			String ret = (String) pjp.proceed();			
    			System.out.println("*** Inside HelloAdvice done..." + ret);
    			return ret;
    		} catch (Throwable e) {
    			e.printStackTrace();
    		}
    		return "";
        }
    }
    
    As the service in the Bundle2 with Aspect is higher in rank it is expected to replace the Service in TestHello but instead it throws StackOverFlowError when a ServiceInterface (sayHello) is invoked!
    
    *** Calling sayHello()...Tue Dec 08 18:23:24 EST 2009
    Exception in thread "Thread-32" java.lang.StackOverflowError
            at org.springframework.aop.support.IntroductionInfoSupport.isMethodOnIntroducedInterface(IntroductionInfoSupport.java:93)
            at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:102)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            at org.springframework.osgi.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:59)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
            at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
            at $Proxy151.sayHello(Unknown Source)
            at sun.reflect.GeneratedMethodAccessor63.invoke(Unknown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:597)
            at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
            at org.springframework.osgi.service.importer.support.internal.aop.ServiceInvoker.doInvoke(ServiceInvoker.java:58)
            at org.springframework.osgi.service.importer.support.internal.aop.ServiceInvoker.invoke(ServiceInvoker.java:62)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
            at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            at org.springframework.osgi.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:59)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
            at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
            at $Proxy151.sayHello(Unknown Source)
            at sun.reflect.GeneratedMethodAccessor63.invoke(Unknown Source)

  5. #5
    Join Date
    Oct 2008
    Posts
    493

    Default

    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.
    Andy Wilkinson
    SpringSource

  6. #6
    Join Date
    Nov 2009
    Posts
    3

    Default

    oops i missed some of the code snippet in Bundle2 with Aspect - consuming the service and republishing it with higher rank. Also added the errlog.zip attachment with StackOverflowError.

    Code:
    	<osgi:reference id="helloService1" interface="com.test.svc.HelloService" />
    	
    	<osgi:service ref="helloService1" interface="com.test.svc.HelloService" ranking="8" />
    Thanks for quick reply.

    -Harshad.
    Attached Files Attached Files

  7. #7
    Join Date
    Nov 2008
    Location
    London,UK
    Posts
    299

    Default

    I tried a similar usecase but with small changes

    I tried the following use case

    BundleX - exposes service

    BundleXAspect - accepts the service and weaves aspect around it.

    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)

  8. #8
    Join Date
    Mar 2007
    Posts
    515

    Default Spring DM dynamic proxies

    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.

  9. #9
    Join Date
    Nov 2008
    Location
    London,UK
    Posts
    299

    Default

    Thanks Andrie. Beautiful Explanation :-)

    So how can i get my use case working ?

    My use case : Adding aspect bundle during runtime and changing the behaviour of the service ? [without impacting service provider and service consumer ]

  10. #10
    Join Date
    Oct 2008
    Posts
    493

    Default

    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.
    Andy Wilkinson
    SpringSource

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •