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
Loader constraint violation in bundles with different versions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Loader constraint violation in bundles with different versions

    Hi All

    I have following simple bundles:

    1. Solution 1.0.0
    2. Pricing 1.0.0
    3. Udm 1.0.0
    4. Udm 1.1.0 (Same with the bundle number 3, only different version)

    Following dependencies:

    Solution 1.0.0 -> Pricing 1.0.0
    Solution 1.0.0 -> Udm 1.0.0
    Pricing 1.0.0 -> Udm 1.1.0

    Please see the JPG attachment ("solution pricing udm.jpg") to better understand the dependencies.

    Each bundle exports a simple service and each bundle uses those exported services within the dependencies definition above.

    In the development time everything works fine. But as soon as I start my Solution 1.0.0 bundle I get following error:

    Code:
    osgi> INFO : Starting [org.springframework.bundle.osgi.extender] bundle v.[1.1.2]
    
    ...
    
    [pricingService,udmService,solutionServiceOsgi,solutionService]; root of factory hierarchy
    ERROR: Post refresh error
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pricingService': FactoryBean threw exception on object creation; nested exception is java.lang.LinkageError: loader constraint violation: loader (instance of org/springframework/osgi/context/internal/classloader/ChainedClassLoader) previously initiated loading for a different type with name "osgi/udm/UdmService"
    	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.java:127)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116)
    	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:91)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1285)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:217)
    	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:425)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
    	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:288)
    	at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:145)
    	at java.lang.Thread.run(Thread.java:619)
    Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of org/springframework/osgi/context/internal/classloader/ChainedClassLoader) previously initiated loading for a different type with name "osgi/udm/UdmService"
    	at java.lang.Class.forName0(Native Method)
    	at java.lang.Class.forName(Class.java:169)
    	at $Proxy4.<clinit>(Unknown Source)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    	at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:588)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:117)
    	at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
    	at org.springframework.osgi.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:60)
    	at org.springframework.osgi.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:37)
    	at org.springframework.osgi.service.importer.support.AbstractServiceProxyCreator.createServiceProxy(AbstractServiceProxyCreator.java:107)
    	at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:185)
    	at org.springframework.osgi.service.importer.support.AbstractServiceImporterProxyFactoryBean.getObject(AbstractServiceImporterProxyFactoryBean.java:83)
    	at org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean.getObject(OsgiServiceProxyFactoryBean.java:141)
    	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.java:121)
    	... 12 more
    Exception in thread "SpringOsgiExtenderThread-8" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pricingService': FactoryBean threw exception on object creation; nested exception is java.lang.LinkageError: loader constraint violation: loader (instance of org/springframework/osgi/context/internal/classloader/ChainedClassLoader) previously initiated loading for a different type with name "osgi/udm/UdmService"
    	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.java:127)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116)
    	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:91)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1285)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:217)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    	at 
    
    ...
    The complete stack trace can be found in the attachment file: "error-springdm-versions.txt".

    If I change the dependency of following:

    Pricing 1.0.0 -> Udm 1.1.0

    to

    Pricing 1.0.0 -> Udm 1.0.0 (just using one version of the Udm bundle)

    everything works just fine.

    So my question is:
    Is there something I have to do to be able to use one bundle with different versions like Udm 1.0.0 and Udm 1.1.0? I already have an identical example - but without Spring dm, just pure OSGi - and that works just fine.

    Thanks a lot!
    Lofi.

  • #2
    After looking around a bit further I found following things:

    1. I get better error messages if I use "Import-Package" instead of "Require-Bundle":

    Code:
    ERROR: Post refresh error
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'solutionServiceOsgi': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'solutionService' defined in URL [bundleentry://29/META-INF/spring/solutionservice.xml]: Cannot resolve reference to bean 'pricingService' while setting bean property 'pricingService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pricingService': FactoryBean threw exception on object creation; nested exception is java.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method "$Proxy4.setUdmService(Losgi/udm/UdmService;)V" the class loader (instance of org/springframework/osgi/context/internal/classloader/ChainedClassLoader) of the current class, $Proxy4, and the class loader (instance of org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader) for interface osgi/pricing/PricingService have different Class objects for the type osgi/udm/UdmService used in the signature
    2. From the messages above it is clear that the UdmService which has two different versions produces the error:

    Solution 1.0.0 -> Pricing 1.0.0 -> Udm 1.1.0
    Solution 1.0.0 -> Udm 1.0.0

    The Pricing 1.0.0 bundle tries to use (to inject) Udm 1.1.0 bundle and at the same time the Solution 1.0.0 tries to use Udm 1.0.0.

    Any ideas to get rid of this problem?

    Thanks,
    Lofi.

    Comment


    • #3
      Adding "uses" directive in Pricing 1.0.0 and Solution 1.0.0 like below:

      Pricing 1.0.0:

      Code:
      Manifest-Version: 1.0
      Bundle-ManifestVersion: 2
      Bundle-Name: Pricing
      Bundle-SymbolicName: osgi.pricing
      Bundle-Version: 1.0.0
      Export-Package: osgi.pricing;version="1.0.0";uses:="osgi.udm"
      Import-Package: osgi.udm;version="1.1.0"
      Solution 1.0.0:

      Code:
      Manifest-Version: 1.0
      Bundle-ManifestVersion: 2
      Bundle-Name: Solution
      Bundle-SymbolicName: osgi.solution
      Bundle-Version: 1.0.0
      Export-Package: osgi.solution;version="1.0.0";uses:="osgi.udm, osgi.pricing"
      Import-Package: osgi.pricing;version="1.0.0", osgi.udm;version="[1.0.0,1.0.0]"
      removes the exception: "loader constraint violation".

      But the bundle Solution 1.0.0 is not beeing activated.

      Running the "diag" tool shows this error:

      Code:
      osgi> diag 32
      initial@reference:file:../../osgi.solution/ [32]
        Package uses conflict: Import-Package: osgi.pricing; version="1.0.0"
      So quite the same error as before.

      It's a pitty that this BLOG about "uses" directive: http://blog.springsource.com/2008/10...ses-directive/

      only shows us how to use the same bundle version.

      My question:
      Is there any examples of using different bundle versions with transitive dependencies like my example above (solution 1.0.0, pricing 1.0.0, dm 1.0.0, dm 1.1.0)? IMHO this is the real power of OSGi... not only using the same version for the bundles...

      Thanks,
      Lofi.

      Comment


      • #4
        Its now SpringSource

        Don't expect serious questions to be answered here. Remember its not the Interface21 that came out with Spring,.. its SpringSource. Its more committed towards conducting Seminars, business sessions, making Application Servers, devising liicensing policies etc etc,,.. not anything serious that does not churn money.

        Comment


        • #5
          Don't expect serious questions to be answered here. Remember its not the Interface21 that came out with Spring,.. its SpringSource. Its more committed towards conducting Seminars, business sessions, making Application Servers, devising liicensing policies etc etc,,.. not anything serious that does not churn money.
          It's a pitty actually, since my problem is quite straight forward... Until now I still cannot find a solution of my problem...

          Cheers
          Lofi.

          Comment


          • #6
            Lofi, I've raised an issue here (http://jira.springframework.org/browse/OSGI-694). By the looks of the stracktrace, it seems to be a proxy creation problem. I will try to reproduce it and report back.

            By the way, thanks for the nice post, stracktraces and images - if only all reports were like this...

            Cheers,

            Comment


            • #7
              Thomas, I don't know what you're expectations are but this is a public forum - anyone can post, whenever they chose to, on whatever they wish, if they want to.

              I for example, chose this Sunday, to reply to a batch of questions that were unanswered while I was on holidays, instead of doing something else. Some might do the same, some might not.

              These being said, to not hijack the thread, Thomas, this is the Spring DM forum, let's keep it this way, please. Help others, download the sources, reproduce errors, offer suggestions, links. Be constructive, get involved not the other way around.

              Thanks!

              Comment


              • #8
                Originally posted by Costin Leau View Post
                Lofi, I've raised an issue here (http://jira.springframework.org/browse/OSGI-694). By the looks of the stracktrace, it seems to be a proxy creation problem. I will try to reproduce it and report back.

                By the way, thanks for the nice post, stracktraces and images - if only all reports were like this...

                Cheers,
                Hi Costin,

                thanks for your reply. If you want I can upload my example somewhere... Anyway I want to upload the whole example after finishing it... I'm doing this example to show that by using Spring DM we can have better and less code than using pure OSGi . It is a part of my tutorial: http://lofidewanto.blogspot.com/2008...evelopers.html

                Thanks a lot!
                Lofi.

                Comment


                • #9
                  Hi Costin

                  I uploaded an example to this problem:
                  http://lofidewanto.googlepages.com/springdm-example.zip

                  Just unzip the file and you'll find the examples as I described in the discussion forum above. I also included the Eclipse Target Platform and you'll find both modules over there: udm-1.0.0.jar and udm-1.1.0.jar.

                  Hope to get an answer to this problem soon

                  Thanks,
                  Lofi.

                  Comment


                  • #10
                    Lofi, I've downloaded the sample and tried to run it but the Eclipse target platform configuration seems incorrect. However, I've looked at the udm-1.0.x.jars and the problem seems to be that you are embedding the interface with the implementation. Since you redeploy them, both classes (the interface + implementation) have a new version and thus cannot be used by the consumer bundle unless it is redeployed as well since it is still wired to the old version.
                    You can go around this by extracting the interface (the common contract) to a different bundle and then just redeploy the implementation bundles. This way the consumer keeps its wiring intact as do the implementators.

                    In the archive that you mentioned, what are the jars that need to be deployer as I would like to reproduce the error. Additionally, can you please try the 1.1.3 and see if this occurs on it as well?

                    Thanks,

                    Comment


                    • #11
                      Hi Costin,

                      thanks a lot for your fast answer!

                      You need to do following to be able to run my example:

                      1. Import the whole projects as a new workspace. Just use springdm-example as your Eclipse workspace.

                      2. Define the target platform from the included target platform: Window -> Preferences -> Target Platform and choose the directory of:
                      springdm-example\Spring-DM-Target-Platform\target

                      3. Close the osgi.udm project because it should be taken from the target platform: udm-1.0.0.jar and udm-1.1.0.jar

                      4. After these three steps you will see that everything is okay. All the red marks should be gone now.

                      5. Run the osgi.solution -> osgi.solution.launch. This should give you the exception as I wrote before in this forum, because of the dependencies to udm-1.x.x.jar. See the diagram in the beginning of this forum.

                      IMHO it should be ok to include the interfaces of udm-1.x.x in both bundles:
                      - The interface can change in every version.
                      - This same example works fine in a pure OSGi technique. I have tested the same example in pure OSGi style with Activator, ServiceRegistry, ... and it works just fine.

                      I can try to run my example in spring-dm 1.1.3 and I let you know the result...

                      Just ask again if you have a problem to run the example... I will write an article about spring-dm very soon and would not like having to write that spring-dm does not work with bundles in different versions, as this should be one of the main advantages using OSGi

                      Again, thanks a lot for your help...
                      Lofi.

                      Comment


                      • #12
                        I've followed your steps and after some setting adjustments I've managed to reproduce the error. On first looks it seems to be caused by a missing uses clauses that indicates the dependency between classes.
                        As you pointed out, the dependency between the classes is:
                        Solution 1.0.0 -> Pricing 1.0.0 -> Udm 1.1.0
                        Solution 1.0.0 -> Udm 1.0.0

                        Since the Pricing -> Udm dependency is public (it's available on the interface signature) it becomes a transitive dependency to solution which needs to be wired/pinned to both Udm 1.0.0 (due to the direct dependency) and Udm 1.1.0 (through Pricing).
                        The linkage error appears since proxies needs to copy the entire interface and thus are greedy in terms of class loading. If you look at the error, you'll notice that the problem becomes Udm which appears on both Pricing and Solution at the same time so a new version of the class breaks the bundle class space consistency.
                        I'll take a look to see whether there is something we can do from Spring DM side though the class consistency is enforced by OSGi and w/o the proper directives (uses), OSGi cannot do that.
                        An alternative for your application would be to remove the transitive dependency (Udm) from the Pricing interface - there is no need to have that on the interface.

                        Regarding the standard OSGi usage, I'd be interested in seeing that example. My guess would be that the setter is not used (and thus the class loading is not triggered).

                        Comment


                        • #13
                          Looking at the past posts, as you pointed out by adding the uses directive the bundle doesn't get activated since the OSGi platform detects the versioning conflict and thus cannot guarantee the class space consistency.
                          By removing the constraint, the class incompatibility is left in the open and through the uses of proxies (in this case JDKs which are quite lightweight in terms of class loading) Spring DM triggers it.

                          Comment


                          • #14
                            Hi Costin

                            Sorry for the late answer. It was carneval time here in Cologne, Germany ;-)

                            You can download the pure OSGi example just here:
                            http://lofidewanto.googlepages.com/v...gi-example.zip

                            The steps to run the application are just the same as before: import whole projects, define the target platform, close the udm project and launch the solution project. You will see that the whole bundles will be activated and started correctly. The interfaces and also the implementation classes are identical with the SpringDM example. Only we need to have activators for each bundle.

                            An alternative for your application would be to remove the transitive dependency (Udm) from the Pricing interface - there is no need to have that on the interface.
                            Sorry I cannot follow you on this... I only exported the pricing package from the pricing bundle. I also need to have the udm injected into the pricing interface since I'm using the udm bundle in my implementation (see PricingServiceImpl.java). Could you please explain more about this alternative?

                            Thanks a lot!
                            Lofi.

                            Comment


                            • #15
                              It took so long to reply since I've had issues with the project that you sent (the platform didn't contain the proper jars but jetty and javax.servlet). Anyway, I started the bundles on just the Equinox platform outside Eclipse.
                              The problem that I described can be exhibited by just adding a System out inside the Solution activator as follows:

                              Code:
                              // existing code
                              PricingService pricingService = (PricingService) context
                                       .getService(pricingServiceReference);
                              // inserted line
                              System.out.println(pricingService.getUdmService().toString());
                              // existing code
                              solutionService.setPricingService(pricingService);
                              The exception is similar to what you get with Spring DM:

                              osgi> Start: UDM Version 1.0.0
                              Start: UDM Version 1.1.0
                              Start: PRICING Version 1.0.0
                              Start: PRICING for: UDM Version 1.1.0
                              Start: SOLUTION Version 1.0.0


                              osgi> ss

                              Framework is launched.

                              id State Bundle
                              0 ACTIVE org.eclipse.osgi_3.3.1.R33x_v20070828
                              1 RESOLVED net.sf.cglib_2.1.3
                              2 RESOLVED jcl104.over.slf4j_1.4.3
                              3 RESOLVED slf4j.api_1.4.3
                              4 RESOLVED slf4j.jdk14_1.4.3
                              5 ACTIVE osgi.udm_1.0.0
                              6 ACTIVE osgi.udm_1.1.0
                              7 ACTIVE osgi.pricing_1.0.0
                              8 RESOLVED osgi.solution_1.0.0

                              osgi> start 8
                              Start: SOLUTION Version 1.0.0
                              org.osgi.framework.BundleException: Exception in osgi.solution.Activator.start()
                              of bundle osgi.solution.
                              at org.eclipse.osgi.framework.internal.core.BundleCon textImpl.startActiv
                              ator(BundleContextImpl.java:1018)
                              at org.eclipse.osgi.framework.internal.core.BundleCon textImpl.start(Bund
                              leContextImpl.java:974)
                              at org.eclipse.osgi.framework.internal.core.BundleHos t.startWorker(Bundl
                              eHost.java:346)
                              at org.eclipse.osgi.framework.internal.core.AbstractB undle.start(Abstrac
                              tBundle.java:260)
                              at org.eclipse.osgi.framework.internal.core.AbstractB undle.start(Abstrac
                              tBundle.java:252)
                              at org.eclipse.osgi.framework.internal.core.Framework CommandProvider._st
                              art(FrameworkCommandProvider.java:260)
                              at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
                              at sun.reflect.NativeMethodAccessorImpl.invoke(Unknow n Source)
                              at sun.reflect.DelegatingMethodAccessorImpl.invoke(Un known Source)
                              at java.lang.reflect.Method.invoke(Unknown Source)
                              at org.eclipse.osgi.framework.internal.core.Framework CommandInterpreter.
                              execute(FrameworkCommandInterpreter.java:150)
                              at org.eclipse.osgi.framework.internal.core.Framework Console.docommand(F
                              rameworkConsole.java:291)
                              at org.eclipse.osgi.framework.internal.core.Framework Console.console(Fra
                              meworkConsole.java:276)
                              at org.eclipse.osgi.framework.internal.core.Framework Console.run(Framewo
                              rkConsole.java:218)
                              at java.lang.Thread.run(Unknown Source)
                              Caused by: java.lang.NoSuchMethodError: osgi.solution.SolutionService.setUdmServ
                              ice(Losgi/udm/UdmServiceV
                              at osgi.solution.Activator.start(Activator.java:29)
                              at org.eclipse.osgi.framework.internal.core.BundleCon textImpl$2.run(Bund
                              leContextImpl.java:999)
                              at java.security.AccessController.doPrivileged(Native Method)
                              at org.eclipse.osgi.framework.internal.core.BundleCon textImpl.startActiv
                              ator(BundleContextImpl.java:993)
                              ... 14 more
                              Nested Exception:
                              java.lang.NoSuchMethodError: osgi.solution.SolutionService.setUdmService(Losgi/u
                              dm/UdmServiceV
                              Could you please explain more about this alternative?
                              The problem is that you are exposing a transitive dependecy (that causes the versioning issue) inside the solution bundle which means that Udm 1.0.0 and Udm 1.1.0 are going to clash.
                              A workaround is to remove the setter/getter for Udm from the Pricing interface and just leave the pricing contract in there and leave each bundle to do its own configuration.
                              That is,
                              Code:
                              public interface PricingService {
                              
                                  public String getPrice();
                              
                                  public void setUdmService(UdmService udmService);
                              
                                  public UdmService getUdmService();
                              }
                              becomes

                              Code:
                              public interface PricingService {
                              
                                  public String getPrice();
                              
                              }
                              Again you can configure the implementation directly inside the Pricing activator and just publish the object through the Pricing interface.

                              Lastly, note that this is not a Spring DM or OSGi problem per se - it's a generic versioning problem : you are forcing two versions of the same class inside the same space. As I've pointed out if you are using the uses clause, the bundle can't start due to this conflict. By removing the uses clause, you are not telling the platform about the bundle constrains so the bundle does start but the problem still remains as shown above.

                              Comment

                              Working...
                              X