Servicemix - 具有嵌入式依赖项的 OSGi 类加载问题

发布于 2024-12-06 20:09:18 字数 1437 浏览 1 评论 0原文

我正在开发包含多个 OSGi 包的项目,部署在 ServiceMix 上(FuseESB 编译,v. 4.3.1)。问题是,其中一个捆绑包连接到 WebLogic 上的 EJB,因此它嵌入了 weblogic.jar。

该解决方案有效,但需要一些技巧。该捆绑包通过 OSGi 导出 Spring 服务。该服务被导入到另一个捆绑包中,该捆绑包是系统的入口点。当从这个包中调用服务时,weblogic 类是不可见的。工作技巧是将 Spring 服务包装在以下方面,临时切换类加载器:

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

    try {
        Thread.currentThread().setContextClassLoader(pjp.getTarget().getClass().getClassLoader());
        output = pjp.proceed();
    } finally {
        Thread.currentThread().setContextClassLoader(clOld);
    }
    return output;
}

据我所知,该服务是使用入口包中的类加载器调用的,而不是使用嵌入 weblogic 的包中的类加载器调用的,并且对于该类加载器,嵌入的依赖类是不可见。在类似的情况下,导出的 Spring 服务可以使用其捆绑包中的私有导入和私有包,但对于嵌入的 jar 则并非如此。

我的问题是:嵌入 jar 是否非常具体,只有当调用源自嵌入包(或使用类加载器切换技巧)时,该嵌入类才可见,或者嵌入包时需要指定更多内容,我已经忘记了做什么?

我正在使用 maven-bundle-plugin

<前><代码> <插件>org.apache.felix;maven-bundle-plugin; <配置> <说明> <捆绑名称>${pom.artifactId}${pom.groupId}.${pom.artifactId}; <嵌入依赖性> weblogic;范围=*,

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鹤舞 2024-12-13 20:09:18

我之前在使用Spring remoting时也遇到过类似的问题。 Spring 喜欢使用线程上下文类加载器动态加载类,这在 OSGi 中并不总是表现良好。

然而,正确工作的负担不属于调用者,它属于有问题的包。我手头没有代码(那是几年前的事了),但您只需向 Spring 远程处理类提供类加载器(我假设您正在使用 Spring 远程处理)即可正确处理类加载。

例如,如果包使用 SimpleRemoteStatelesSessionProxyFactory,它应该调用 setBeanClassLoader() 方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文