15

我正在尝试从 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;
}

现在,在使用eclipse bridge的 Tomcat 上,我不知道如何检索 Equinox 环境的正确上下文。当我尝试使用 Equinox 在 Tomcat 上运行它时,我得到了 NoClassDefFound 异常。我将不胜感激有关如何解决此问题的任何建议。

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

4

4 回答 4

2

I have done this before using the EclipseStarter stuff with the bridge, and it was a lot of work to get the classpath stuff right which is the key. You also have to call EclipseStarter using reflection. It looks like they have standardized this since then so you don't need to use the EclipseStarter.

The key here (as briefly mentioned in the Felix article is that you have to have a shared classpath between your Tomcat environment and your OSGi environment. If you look in that article at the section starting with "Using Services Provided by Bundles", it seems to suggest what you want.

You will need to have an interface to what you are calling in your Tomcat (parent) classpath, and then you need to start the framework such that it uses your parent classpath first (which is likely not their launcher stuff works), and you need to exclude the bundle that provides the interface from the OSGi bundles. I accomplished this by making a separate OSGi bundle (the API bundle) that just had the interfaces, so when I wanted to use this setup in a context where my code was called from outside OSGi I would not provide that API bundle.

于 2011-12-28T13:31:23.823 回答
2

当您嵌入这样的 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 也是标准化的)。

于 2012-02-25T16:32:33.783 回答
0

我通过覆盖 JasperClass 加载器克服了这个挑战,每个包作为它自己的类加载器 classdeffnotfound 发生的事情是因为正在使用 tomcat 加载器。网上资源比较多。

于 2012-01-23T21:41:11.610 回答
0

很抱歉,我不会直接回答您的问题...从我的角度来看,您没有采取好的方法,您有任何有价值的理由使用现有的 Tomcat 7 实例吗?我会使用更以 OSGi 为中心的方法,并使用标准 Http 服务来发布您的 Web 应用程序......在这种情况下,两个组件都与标准 OSGi 捆绑包处于同一级别,因此两个组件之间的通信非常容易(使用 EventAdmin 服务的直接方法调用或异步消息) HTH 我的 2 美分 Jerome PS:这种方法为您提供了更多的灵活性,它可以与 Equinox 或您想要的任何其他 OSgi shell 一起使用(felix、knopflerfish ..)

于 2012-01-24T13:54:16.430 回答