开发者

Servicemix - OSGi classloading issues with embedded dependencies

I'm developing project with multiple OSGi bundles, deployed on ServiceMix (FuseESB compilation, v. 4.3.1). The issue is, one of this bundles is connecting to EJB on WebLogic, therefore it embeddes weblogic.jar.

The solution is working, however a trick was required. The bundle exports Spring service via OSGi. This service is imported in another bundle, which is entry point to the system. When from this bundle the service was called, the weblogic classes were invisible. The working trick is to wrap Spring service in following aspect, which temporarly switches classloader:

    public Object profileInventory(ProceedingJoinPoint pjp) throws Throwable {
    Object output = null;
    ClassLoader clOld = Thread.currentThread().getContextClassLoader();

    try {
        Thread.currentThread().setContextClassLoader(pjp.getTarget().getClass().getClassLoader());
        output开发者_JAVA百科 = pjp.proceed();
    } finally {
        Thread.currentThread().setContextClassLoader(clOld);
    }
    return output;
}

As I have understood, the service is called with classloader from entry bundle, not with the classloader from bundle that embedds weblogic, and for this classloader embedded dependency classes are not visible. In similar case, exported Spring service can use private imports and private packages from its bundle, but with embedded jars it is not so.

My question is: is the embedding jars something so specific, that this embedded classes will be visible only when the call originates from embedding bundle (or with classloader swich trick), or there is something more to specify when embedding bundle, something I have forgot to do?

I'm using maven-bundle-plugin

        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <configuration>
                <instructions>
                    <Bundle-Name>${pom.artifactId}</Bundle-Name>
                    <Bundle-SymbolicName>${pom.groupId}.${pom.artifactId}</Bundle-SymbolicName>
                    <Embed-Dependency>
                 weblogic;scope=*,
                    </Embed-Dependency>


I have encountered a similar problem when using Spring remoting before. Spring likes to dynamically load classes using the thread context classloader, which doesn't always fare well in OSGi.

The burden to work correctly doesn't belong in the caller though, it belongs in the offending bundle. I don't have the code on hand (it was a couple of years ago), but you need to simply provide the classloader to the Spring remoting classes (I am assuming you are using Spring remoting) to handle the classloading properly.

For example, if the bundle uses SimpleRemoteStatelesSessionProxyFactory, it should be calling the setBeanClassLoader() method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜