2011-08-31 98 views
15

我试图从Java Web应用程序调用OSGi包的方法。两者都应该在Tomcat 7上运行。在Tomcat中使用来自Java Web应用程序的OSGi包

我已经编写了一个普通的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中:使用eclipse bridge现在

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环境的正确背景。当我尝试在Equinox的Tomcat上运行它时,我得到了NoClassDefFound异常。我将不胜感激关于如何解决这个问题的任何建议。

非常感谢。 Cheers,Nic

+0

我认为关键是要保持对启动OSgi框架的控制。我不太了解Equinox的确切工作方式,但我确定他们有类似于Felix所描述的内容,在这里:http://felix.apache.org/site/apache-felix-framework-launching-and -embedding.html –

+0

感谢您的评论。这也是我尝试的方法。虽然我需要在Tomcat服务器上运行我的项目,但上面描述的Bridge似乎是需要的 - 而且我无法手动启动。或者有什么方法可以绕过这个Bridge并使用手动启动的OSGi框架? – Nicolas

+0

我看不出如何使用Tomcat将您与特定的servlet桥接实现联系起来。你为什么不开始定制'org.eclipse.equinox.servletbridge'项目? –

回答

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也是标准化的)。

+0

最新的链接:http://felix.apache.org/documentation/subprojects/apache-felix-framework/apache-felix-framework-launching-and-embedding.html – FableBlaze

2

我在使用EclipseStarter这个东西之前就已经完成了这个工作,并且要做好很多工作来获得正确的类路径,这是关键。您还必须使用反射来呼叫EclipseStarter。看起来他们已经标准化了,所以你不需要使用EclipseStarter

这里的关键(在Felix article中简要提及的是,你必须在Tomcat环境和OSGi环境之间有一个共享类路径,如果你从“使用Bundles提供的服务”开始看这篇文章, ,它似乎暗示了你想要的东西

你将需要一个接口来调用你的Tomcat(父类)类路径,然后你需要启动该框架,以便它首先使用你的父类路径这可能不是他们的启动器东西的作品),并且你需要排除提供OSGi包的接口的包,我通过制作一个单独的OSGi包(API包)广告接口,所以当我想在从OSGi外部调用我的代码的上下文中使用此设置时,我不会提供该API包。

0

我克服了这个挑战,通过覆盖JasperClass Loader,每个bundle发生了什么,因为它自己的类加载器classdeffnotfound是因为正在使用tomcat加载器。网上有更多的资源。

0

对不起,我不会直接回答你的问题... 从我的角度来看,你不采取好的方法,你有没有任何宝贵的理由来使用现有的Tomcat 7实例? 我会使用更多的以OSGi为中心的方法,并使用标准Http服务来发布您的Web应用程序......在这种情况下,这两个组件与标准OSGi软件包处于同一级别,因此2个组件之间的通信是真的易(直接法invokation或使用的EventAdmin服务异步消息) HTH 我的2美分 杰罗姆 PS: 这种方法给你更多的灵活性,它可以与春分或任何其他OSGi使用外壳,你想要的(菲利克斯,knopflerfish。 。)