PDA

View Full Version : java.lang.LinkageError when embedding an OSGi container within a Spring-application


abuijze
May 22nd, 2008, 05:00 AM
Hi,

I have been playing around with Spring DM for a while now, and with success. Well, until now that is. We have embedded Felix inside an existing (spring-wired) application. Application packages, such as org.springframework.* are exported towards the OSGi container. Normal bundles start up just fine and are able to access the packages and services provided by the application.

However, when trying to load a Spring-DM compatible OSGi bundle, the extender throws a LinkageError. I had to deal with a few other classloading issues first, but they could be solved by explicitly "Import-Package"-ing some org.springframework packages inside the Spring-DM compatible bundle.

My bundle itself does absolutely nothing special. There is jsust a single bean definition with an init method that says "Hello world!". That's it.

Here is my stacktrace:

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 "org/aopalliance/aop/Advice"
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at $Proxy39.<clinit>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInsta nce0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInsta nce(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newI nstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Construc tor.java:513)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.jav a:588)
at org.springframework.aop.framework.JdkDynamicAopPro xy.getProxy(JdkDynamicAopProxy.java:117)
at org.springframework.aop.framework.ProxyFactory.get Proxy(ProxyFactory.java:110)
at org.springframework.osgi.context.support.TrackingU til.getService(TrackingUtil.java:127)
at org.springframework.osgi.context.support.OsgiBundl eXmlApplicationContext.lookupNamespaceHandlerResol ver(OsgiBundleXmlApplicationContext.java:260)
at org.springframework.osgi.context.support.OsgiBundl eXmlApplicationContext.createNamespaceHandlerResol ver(OsgiBundleXmlApplicationContext.java:214)
at org.springframework.osgi.context.support.OsgiBundl eXmlApplicationContext.loadBeanDefinitions(OsgiBun dleXmlApplicationContext.java:129)
at org.springframework.context.support.AbstractRefres hableApplicationContext.refreshBeanFactory(Abstrac tRefreshableApplicationContext.java:123)
at org.springframework.context.support.AbstractApplic ationContext.obtainFreshBeanFactory(AbstractApplic ationContext.java:423)
at org.springframework.osgi.context.support.AbstractD elegatedExecutionApplicationContext.startRefresh(A bstractDelegatedExecutionApplicationContext.java:2 06)
at org.springframework.osgi.extender.internal.depende ncies.startup.DependencyWaiterApplicationContextEx ecutor.stageOne(DependencyWaiterApplicationContext Executor.java:218)
at org.springframework.osgi.extender.internal.depende ncies.startup.DependencyWaiterApplicationContextEx ecutor.refresh(DependencyWaiterApplicationContextE xecutor.java:169)
at org.springframework.osgi.context.support.AbstractD elegatedExecutionApplicationContext.refresh(Abstra ctDelegatedExecutionApplicationContext.java:131)
at org.springframework.osgi.extender.internal.activat or.ContextLoaderListener$2.run(ContextLoaderListen er.java:674)


Does anyone know why this LinkageError occurs and how it can be solved?

Perhaps this is a special usecase that isn't supported by Spring-DM, but we'd surely like to be able to wire our beans using spring inside the OSGi bundles.

Thanks in advance for your help!

----
Just for being complete: I have also tried starting the Equinox container instead of the Felix one. The exception is almost identical:

osgi> [2008-05-22 11:26:16,562] ERROR org.springframework.osgi.extender.internal.depende ncies.startup.DependencyWaiterApplicationContextEx ecutor: - Unable to create application context for [org.joiningtracks.his-plugin-sample], unsatisfied dependencies: none
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 "org/aopalliance/aop/Advice"
...

Costin Leau
May 22nd, 2008, 06:19 AM
The Linkage error appears when dependencies of classes that are to be defined have changed in an incompatible manner. From the stacktrace that you provided it seems that some classes (probably Spring-DM) are shared between the war and the bundles inside the nested OSGi platform.
Seems that the one of Spring-DM internal classes: (ChainedClassLoader) is first loaded by aop alliance bundle but then on proxy creation, again from a different class loaded by a different, incompatible class loader.
I might be off so try removing boot delegation from your OSGi platform and limit the visibility of your classes in/out of the OSGi realm.

abuijze
May 22nd, 2008, 08:56 AM
Thanks Costin, for your quick response.

I've been playing around with the dependencies, and finally got it working. The problem was that one of my jars accidentally included spring.jar inside. That's probably what caused the different classes being loaded.

After removing the spring.jar file from the bundle, the context was properly initialized.

Even with all org.springframework.* packages exported by the system bundle, it works like a charm, both in Equinox and Felix.

Thanks, again, for pointing me in the right direction!