在 Tomcat 中使用 Java Web 应用程序中的 OSGi 捆绑包

2022-09-03 16:04:53

我正在尝试从Java Web应用程序中调用OSGi捆绑包的方法。两者都应该在Tomcat 7上运行。

我已经编写了一个普通的Java应用程序,它从OSGi捆绑包调用方法,如此站点上所述:http://drupal.osgibook.org/node/37

为了获取Equinox环境的上下文,我从应用程序中启动了它,并从内部安装了捆绑包。此外,上下文用于检索正在运行的捆绑包的服务引用并获取其服务。

EquinoxRunner 类的 runEquinox 方法:

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

public BundleContext runEquinox([...]) throws Exception {
    [...]

    BundleContext bundleContext = EclipseStarter.startup(new String[]{"-console"}, null);
    bundleContext.installBundle("file:C:/.../plugins/myosgiclass.interface_1.0.0.201108301327.jar");
    Bundle bundleTranslationImpl =  bundleContext.installBundle("file:C:/.../plugins/myosgiclass.impl_1.0.0.201108301327.jar");
    bundleTranslationImpl.start();

    [...]
    return bundleContext;
}

和 ServiceRunner 类的 invokeMethod:

import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

[...]

public Object invokeMethod(BundleContext bundleContext, Object value, [...]){
    ServiceReference serviceReference = bundleContext.getServiceReference(MyOSGiClass.class.getName());
    Object result = null;
    if (serviceReference != null) {
        MyOSGiClass myOSGiClass = (MyOSGiClass) bundleContext.getService(serviceReference);
        if (myOSGiClass != null) result = myOSGiClass.method(value);
        bundleContext.ungetService(serviceReference);
    }
    return result;
}

现在,在Tomcat上使用日食桥,我不知道如何检索Equinox环境的正确上下文。当我尝试在Tomcat和Equinox上运行它时,我得到了NoClassDefFound Exceptions。如果有任何关于如何解决这个问题的建议,我将不胜感激。

提前非常感谢。干杯,尼克


答案 1

当您嵌入这样的 OSGi 框架,然后想要从外部环境访问 OSGi 服务时,您需要确保 OSGi 内部和外部的服务接口相同

因此,配置 OSGi 容器以将服务接口的包从 Tomcat 导出到 OSGi。若要实现此目的,请使用“FRAMEWORK_SYSTEMPACKAGES_EXTRA”属性配置 OSGi 框架。

有关 http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html#ApacheFelixFrameworkLaunchingandEmbedding-hostservices 的更多信息(即使它是针对Apache Felix的,嵌入API也是标准化的)。


答案 2

在将这些东西与桥一起使用之前,我已经这样做了,并且要使类路径的东西正确,这是关键。您还必须使用反射进行调用。从那时起,他们似乎已经对此进行了标准化,因此您不需要使用.EclipseStarterEclipseStarterEclipseStarter

这里的关键(正如Felix文章中简要提到的)是,您必须在Tomcat环境和OSGi环境之间有一个共享的类路径。如果您在那篇文章中以“使用捆绑包提供的服务”开头的部分,它似乎暗示了您想要什么。

您需要有一个指向您在 Tomcat(父)类路径中调用的内容的接口,然后您需要启动框架,使其首先使用您的父类路径(这很可能不是它们的启动器内容的工作原理),并且您需要从 OSGi 捆绑包中排除提供接口的捆绑软件。我通过制作一个单独的OSGi捆绑包(API捆绑包)来实现这一点,该捆绑包只有接口,因此,当我想在从OSGi外部调用我的代码的上下文中使用此设置时,我不会提供该API捆绑包。


推荐