Announcement Announcement Module
Collapse

Spring Dynamic Modules forum decommissioned in favor of Eclipse Gemini Blueprint

With the official first release of Eclipse Gemini Blueprint shipped, the migration of the Spring Dynamic Modules code base to the Eclipse Foundation, as part of the Gemini project, has been completed.

As such, this forum has been decommissioned in favour of the Eclipse Gemini forums.
See more
See less
Problem when using update from osgi console (equinox) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem when using update from osgi console (equinox)

    I have a service registered in project A that is referenced in project B. All is done with spring osgi namespaces. When i start both projects the dependencies work fine.
    But if i update project A in osgi console, project B can't find and inject the service.. After some time spring dm throws a timeout exception..

    There is something i need to do so project B can find services updates??

    Thanx

  • #2
    To ilustrate, i create this 2 test projects:

    Bundle 12 registers the service and bundle 5 has a reference to it.

    osgi> bundle 12
    Code:
    osgi.test1_1.0.0 [12]
      Id=12, Status=ACTIVE      Data Root=/media/files/development/eclipse-workspaces/osgi-workspace/.metadata/.plugins/org.eclipse.pde.core/Jata/org.eclipse.osgi/bundles/12/data
      Registered Services
        {osgi.test1.Printer}={org.springframework.osgi.bean.name=printer, Bundle-SymbolicName=osgi.test1, Bundle-Version=1.0.0, service.id=29}
        {org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext, org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext, org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, org.springframework.beans.factory.DisposableBean}={org.springframework.context.service.name=osgi.test1, Bundle-SymbolicName=osgi.test1, Bundle-Version=1.0.0, service.id=30}
      Services in use:
        {org.xml.sax.EntityResolver}={service.id=28}
        {org.springframework.beans.factory.xml.NamespaceHandlerResolver}={service.id=27}
      Exported packages
        osgi.test1; version="1.0.0"[exported]
      Imported packages
        org.osgi.framework; version="1.5.0"<org.eclipse.osgi_3.5.0.v20090520 [0]>
      No fragment bundles
      Named class space
        osgi.test1; bundle-version="1.0.0"[provided]
      No required bundles
    osgi> bundle 5
    Code:
    osgi.test.2_1.0.0 [5]
      Id=5, Status=ACTIVE      Data Root=/media/files/development/eclipse-workspaces/osgi-workspace/.metadata/.plugins/org.eclipse.pde.core/Jata/org.eclipse.osgi/bundles/5/data
      Registered Services
        {org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext, org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext, org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, org.springframework.beans.factory.DisposableBean}={org.springframework.context.service.name=osgi.test.2, Bundle-SymbolicName=osgi.test.2, Bundle-Version=1.0.0, service.id=31}
      Services in use:
        {org.xml.sax.EntityResolver}={service.id=28}
        {org.springframework.beans.factory.xml.NamespaceHandlerResolver}={service.id=27}
        {osgi.test1.Printer}={org.springframework.osgi.bean.name=printer, Bundle-SymbolicName=osgi.test1, Bundle-Version=1.0.0, service.id=29}
      No exported packages
      Imported packages
        osgi.test1; version="1.0.0"<osgi.test1_1.0.0 [12]>
      No fragment bundles
      Named class space
        osgi.test.2; bundle-version="1.0.0"[provided]
      No required bundles
    If i update bundle 12, the service Printer isn't referenced in bundle 5:

    osgi> update 12

    osgi> bundle 12
    Code:
    osgi.test1_1.0.0 [12]
      Id=12, Status=ACTIVE      Data Root=/media/files/development/eclipse-workspaces/osgi-workspace/.metadata/.plugins/org.eclipse.pde.core/Jata/org.eclipse.osgi/bundles/12/data
      Registered Services
        {osgi.test1.Printer}={org.springframework.osgi.bean.name=printer, Bundle-SymbolicName=osgi.test1, Bundle-Version=1.0.0, service.id=32}
        {org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext, org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext, org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, org.springframework.beans.factory.DisposableBean}={org.springframework.context.service.name=osgi.test1, Bundle-SymbolicName=osgi.test1, Bundle-Version=1.0.0, service.id=33}
      Services in use:
        {org.xml.sax.EntityResolver}={service.id=28}
        {org.springframework.beans.factory.xml.NamespaceHandlerResolver}={service.id=27}
      Exported packages
        osgi.test1; version="1.0.0"[exported]
      Imported packages
        org.osgi.framework; version="1.5.0"<org.eclipse.osgi_3.5.0.v20090520 [0]>
      No fragment bundles
      Named class space
        osgi.test1; bundle-version="1.0.0"[provided]
      No required bundles
    osgi> bundle 5
    Code:
    osgi.test.2_1.0.0 [5]
      Id=5, Status=ACTIVE      Data Root=/media/files/development/eclipse-workspaces/osgi-workspace/.metadata/.plugins/org.eclipse.pde.core/Jata/org.eclipse.osgi/bundles/5/data
      Registered Services
        {org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext, org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext, org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, org.springframework.beans.factory.DisposableBean}={org.springframework.context.service.name=osgi.test.2, Bundle-SymbolicName=osgi.test.2, Bundle-Version=1.0.0, service.id=31}
      Services in use:
        {org.xml.sax.EntityResolver}={service.id=28}
        {org.springframework.beans.factory.xml.NamespaceHandlerResolver}={service.id=27}
      No exported packages
      Imported packages
        osgi.test1; version="1.0.0"<osgi.test1_1.0.0 [12]>
      No fragment bundles
      Named class space
        osgi.test.2; bundle-version="1.0.0"[provided]
      No required bundles
    My environment is:
    spring-osgi 1.2.0
    spring-framework 2.5.6.SEC01
    org.eclipse.osgi 3.5.0.v20090520

    Comment


    • #3
      Another thing.. When i stop bundle 5, which has a reference for service Printer, throws a error. Maybe because it's waiting for the service. And after if i try to start the bundle again, throw a exception.

      Is this may be a classloader problem??

      osgi> stop 5
      Code:
      25/06/09 01:27:53 DEBUG [Timer-1] org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor - Closing appCtx for OsgiBundleXmlApplicationContext(bundle=osgi.test.2, config=osgibundle:/META-INF/spring/*.xml)
      25/06/09 01:27:53 DEBUG [Timer-1] org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor - Shutting down normally appCtx OsgiBundleXmlApplicationContext(bundle=osgi.test.2, config=osgibundle:/META-INF/spring/*.xml)
      25/06/09 01:27:53 INFO  [Timer-1] org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext - Application Context service already unpublished
      25/06/09 01:27:53 INFO  [Timer-1] org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext - Closing org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@40bb2bc3: display name [OsgiBundleXmlApplicationContext(bundle=osgi.test.2, config=osgibundle:/META-INF/spring/*.xml)]; startup date [Thu Jun 25 01:27:37 BRT 2009]; root of context hierarchy
      25/06/09 01:28:03 ERROR [OSGi Console] org.springframework.osgi.extender.internal.util.concurrent.RunnableTimedExecution - Closing runnable for context OsgiBundleXmlApplicationContext(bundle=osgi.test.2, config=osgibundle:/META-INF/spring/*.xml) did not finish in 10000ms; consider taking a snapshot and then shutdown the VM in case the thread still hangs
      25/06/09 01:28:03 DEBUG [OSGi Console] org.springframework.osgi.extender.internal.support.NamespacePlugins - Removing handler Osgi_test_2 (osgi.test.2)
      osgi> start 5
      Code:
      ...
      25/06/09 01:30:18 DEBUG [SpringOsgiExtenderThread-10] org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean - Service reference [{osgi.test1.Printer}={org.springframework.osgi.bean.name=printer, Bundle-SymbolicName=osgi.test1, Bundle-Version=1.0.0, service.id=29}] was unregistered and unbound from the service proxy
      25/06/09 01:30:18 DEBUG [SpringOsgiExtenderThread-10] org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext - Post refresh error
      org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'osgi.test2.TestPrinter#0' defined in URL [bundleentry://16/META-INF/spring/osgi-test2-context.xml]: Invocation of init method failed; nested exception is org.springframework.aop.AopInvocationException: AOP configuration seems to be invalid: tried calling method [public abstract void osgi.test1.Printer.print()] on target [osgi.test1.PrinterImpl@21bbd3e2]; nested exception is java.lang.IllegalArgumentException: object is not an instance of declaring class
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
      	at java.security.AccessController.doPrivileged(Native Method)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
      	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
      	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
      	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
      	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:69)
      	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:355)
      	at org.springframework.osgi.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
      	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:320)
      	at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:136)
      	at java.lang.Thread.run(Thread.java:619)
      Caused by: org.springframework.aop.AopInvocationException: AOP configuration seems to be invalid: tried calling method [public abstract void osgi.test1.Printer.print()] on target [osgi.test1.PrinterImpl@21bbd3e2]; nested exception is java.lang.IllegalArgumentException: object is not an instance of declaring class
      	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:315)
      	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:171)
      	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:171)
      	at org.springframework.osgi.service.util.internal.aop.ServiceTCCLInterceptor.invokeUnprivileged(ServiceTCCLInterceptor.java:56)
      	at org.springframework.osgi.service.util.internal.aop.ServiceTCCLInterceptor.invoke(ServiceTCCLInterceptor.java:39)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
      	at org.springframework.osgi.service.importer.support.LocalBundleContextAdvice.invoke(LocalBundleContextAdvice.java:59)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
      	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:171)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
      	at $Proxy7.print(Unknown Source)
      	at osgi.test2.TestPrinter.start(TestPrinter.java:15)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1414)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1375)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
      	... 17 more
      Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	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)
      	... 41 more

      Comment


      • #4
        You need to separate the static parts of your setup from the dynamic one. From your setup it sounds like bundle A provides some classes and services which are used by bundle B. When you update bundle A, then you load a new set of classes and services - bundle B still refers to the old ones.
        You have to either refresh B (to pick up the new versions) or extract the interfaces into a separate bundle C.
        This way B can import the classes in C and look for the services deployed by A. When you refresh A, the new services will still use the classes in C which B sees so they will be picked up.

        Comment


        • #5
          Hi Costin, thanks for your answer.

          I managed to solve this problem today. Import what you export :P

          Reference:
          http://www.osgi.org/blog/2007/04/imp...importing.html

          Thanks again.
          Lucas

          Comment


          • #6
            I've got the same problem. Bundle B uses bundle A via some service. Jar file of bundle A is the same - no changes made. After updating A in console, B stops seeing services in A. Bundle A binary-wise is the same all the time though. Only after refreshing bundle B (in console) services are visible again.
            Interesting thing, when I just stop A and then start it again services coming back to B nicely.
            Last edited by mccat; Jun 25th, 2009, 03:32 PM.

            Comment


            • #7
              Exactly what i had.

              I solved with something like this:

              Bundle A (register service)

              Export-Package: org.example;version="1.0.0"
              Import-Package: org.example;version="1.0.0"

              Bundle B (reference service)

              Import-Package: org.example;version="1.0.0"

              Comment


              • #8
                Right - you can also do it like this. The key point is that you need a static (non changing bundle). It's something easy to forget that despite the class definition, just refreshing a bundle means creating a new version of the class.
                The VM defines a class by its byte code definition and loading class loader not by the class hash. Unfortunately, classes do not provide a 'version' attribute so it's not always clear what's the case until you start looking at the defining classloaders.

                Comment


                • #9
                  Hello again, "importing what exporting" paradigm not working - I've got exception:
                  Code:
                  Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) previously initiat
                  ed loading for a different type with name "x/xx/MyBean"
                  Probably, cause is the same - mixing dynamic and static part.

                  Costins' suggestion with external static bundle with interfaces is working great.

                  Maybe , this is a good tip to place it in documentation?
                  Last edited by mccat; Jun 29th, 2009, 01:48 AM.

                  Comment


                  • #10
                    It seems like it still should work...

                    Originally posted by Costin Leau View Post
                    You need to separate the static parts of your setup from the dynamic one. From your setup it sounds like bundle A provides some classes and services which are used by bundle B. When you update bundle A, then you load a new set of classes and services - bundle B still refers to the old ones.
                    You have to either refresh B (to pick up the new versions) or extract the interfaces into a separate bundle C.
                    This way B can import the classes in C and look for the services deployed by A. When you refresh A, the new services will still use the classes in C which B sees so they will be picked up.
                    So, I understand what you're saying and agree that it is a good idea to separate, but I don't understand why it is necessary. Why can't a bundle A (containing both interface and implementation classes) be updated and bound to a dependent bundle dynamically?

                    When you update, you said above that a new set of classes and services are created while the dependent bundle still refers to the old one; why can't these references be broken (using a proxy or something else) and updated to the new ones when the bundle is started?

                    Comment


                    • #11
                      Because updating a bundle means updating providing a new version for its contract. Even if the class is binary identical, from the OSGi point of view, you have deployed a new version.
                      The existing bundles still refer (and use) the old version and thus will simply ignore the new one unless they are being updated at which point, they'll pick up the most recent version.
                      By extracting the interface, you prevent the stable/common API from being updated and thus you prevent any updates of the contract. Only the implementation changes while the contract remains the same.

                      Comment


                      • #12
                        Problem resolved, but reason still not clear

                        I also had similar problem (see http://forum.springsource.org/showth...684#post252684). In my case, service bundle A exported both interface and service, and client bundle B imported interface package and had mandatory reference to service.

                        When I stop B, stop A, start B, start A, everything works fine - B finds imported service.

                        When I update A (in osgi console) then update B, B can't find service and blocked until timeout expires.
                        BTW, importing interface package in service bundle A makes this scenario working.

                        After I separated service interface into bundle C, both scenarios work fine.

                        Everything looks OK now, but it's still not clear why the 'update A then update B' scenario does not work if bundle A has both interface and service (implementation). After service bundle A is updated and new instances of the classes are created, client bundle B is updated, as well, so it should be able to pick up new instances of the interface class and the service. Any idea?

                        Comment


                        • #13
                          Additional case

                          If I change service reference in client bundle B from mandatory (cardinality="1..1") to optional (cardinality="0..1"), the 'update A then update B' scenario works different (w/o importing own interface in service bundle A):
                          client bundle B gets reference to the service (logs '[Order Client]: setting Order Service'), but the service call fails. With mandatory service reference the client bundle B did not get access to the service at all (does not log appropriate 'setting' message).

                          Again, importing its own interface package in service bundle A makes this scenario working with both mandatory and optional service reference.
                          Does this mean that updating service bundle A that imports its own interface package works different than updating A that does not import its own interface package? What is the difference?
                          Another non-clear point: why updating client B with mandatory service reference works different than updating client with optional service reference? In both cases the service bundle A has been already updated and its service (new instance) is already registered.

                          Comment


                          • #14
                            Comparison with OSGi DS

                            In order to understand better the role of importing its own interface package in the service bundle A (if interface is not separated in a bundle C), I created similar client B-DS and service A-DS bundles by using OSGi DS.

                            If service bundle A-DS does not import its own interface package, the 'update A-DS then update B-DS' scenario does not work, indepedent of the type of service reference (mandatory or optional). If service bundle A-DS imports its own interface package, this scenario works automatically, i.e. client bundle B-DS is automatically restarted after service bundle A-DS is updated, and service call works as exptected.

                            Costin, thanks again for useful hints.

                            -- Lev
                            http://grakol.com/wordpress/

                            Comment


                            • #15
                              Importing the classes contained by the same bundle, provides wiring information to the OSGi platform which can make better decisions when refreshing a bundle.
                              As for mandatory vs optional dependencies, the first is resolved at startup while the latter on demand which in some cases, can postpone class loading.
                              Note also that when interacting with the OSGi platform, if a console is used, you might be using macro commands. For example refresh does the package admin refresh while update, only updates one bundle.
                              The two seem similar but in fact, they are different - the OSGi spec talks more on how updates can occur inside the OSGi framework.

                              Comment

                              Working...
                              X