首页 文章

OSGI HttpService无法正确初始化/注入

提问于
浏览
1

我想在我的OSGI项目中为我的servlet使用声明性服务功能 . 详细说明:用户可以在主应用程序上手动安装模块,选择一些* .jar文件,主应用程序已经嵌入了OSGI服务器,当OSGI模块被激活时,它应该注册一些请求例如这样:

protected void startup() {
  MyServlet servlet = new MyServlet();
  if (httpService != null)  {
    httpService.registerServlet("/req", servlet, null, null); **//OK!**
  }
}

不幸的是,我无法初始化httpService实例,这就是问题所在 . 这是servlet模块代码列表的问题:

@Component(name="app", immediate=true)
@Service(value=App.class)
public class App {                
        @Reference(name = "httpService", referenceInterface = HttpService.class, bind = "bindHttpService", unbind = "unbindHttpService")
        private HttpService httpService;

        @Activate
        protected void startup() {                    
            MyServlet servlet = new MyServlet();
            if (httpService != null)    {
                httpService.registerServlet("/req", servlet, null, null);
                //OK!
            } else {
                //Not OK! 
            }
        }

        protected void bindHttpService(HttpService httpService) {               
            this.httpService = httpService;
        }

        protected void unbindHttpService(HttpService httpService) {         
            this.httpService = null;
        }
        // some more code.........              
}

Maven bundle plugin设置pom.xml代码

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>app</Bundle-SymbolicName>
            <Embed-Dependency>!org.osgi.core</Embed-Dependency>
            <Embed-Transitive>true</Embed-Transitive>                                               
            <Import-Package>                        
             <![CDATA[ 
               org.osgi*,
               com.mynamespace                        
            ]]>                     
            </Import-Package>                       
        </instructions>
    </configuration>
</plugin>

以下是主应用程序中嵌入式OSGI服务器的简化代码:

public static void main(String[] args) 
{
    FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();
    Map<String, String> config = new HashMap<String, String>();
    config.put(Constants.FRAMEWORK_STORAGE_CLEAN, "onFirstInit");
    config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "javax.microedition.io");
    Framework framework = frameworkFactory.newFramework(config);
    framework.start();
    BundleContext context = framework.getBundleContext();
    List<Bundle> installedBundles = new LinkedList<Bundle>();
    // install prerequisites
    installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.util_1.0.500.v20130404-1337.jar"));
    installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.osgi.services_3.4.0.v20131120-1328.jar"));
    installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.ds_1.4.200.v20131126-2331.jar"));
    //install servlet module
    installedBundles.add(context.installBundle("file:///MY_PATH\\app.jar"));
    for (Bundle bundle : installedBundles) {
        bundle.start();
    }
}

我受到Peter Fries博客(http://www.peterfriese.de/osgi-servlets-flexibility-by-simplicity/)的例子的启发,但是我无法初始化httpService实例 . App模块甚至可以在@Reference注释被删除或覆盖注释时启动,在其他情况下模块将不会被激活 .

我怀疑我的嵌入式OSGI没有一些必需的模块,但无法获得有关它的详细信息 - 日志控制台没有说什么 .

更新

感谢Balasz的暗示!
有我的错误:
0.当 <Embed-Dependency>!org.osgi.core</Embed-Dependency> 被声明时,httpService不能通过@Reference annotatoin自动绑定,所以 bind = "bindHttpService", unbind = "unbindHttpService" 是没用的 . 我删除了 <Embed-Dependency> 声明,它有助于绑定httpService,就像我想拥有它一样(通过bindHttpService) .

  • 在OSGI服务器上安装bundle之前应该指定jetty设置:

System.setProperty(“jetty.port”,“8080”); System.setProperty(“jetty.home.bundle”,“org.eclipse.jetty.osgi.boot”);

  • 在我的情况下,必须在嵌入式OSGI服务器上安装太多的jar

//强制捆绑安装了Bundle.add(context.installBundle(“file:/// MY_PATH \ org.eclipse.equinox.util_1.0.500.v20130404-1337.jar”)); installedBundles.add(context.installBundle( “文件:/// my_path的\ org.eclipse.equinox.ds_1.4.200.v20131126-2331.jar”)); installedBundles.add(context.installBundle( “文件:/// my_path的\ org.eclipse.osgi.services_3.4.0.v20131120-1328.jar”)); installedBundles.add(context.installBundle( “文件:/// my_path的\的javax.servlet-API-3.0.1.jar”));

// Container bundles
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.security_8.1.12.v20130726.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.servlet_8.1.12.v20130726.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.continuation_8.1.12.v20130726.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.server_8.1.12.v20130726.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.util_8.1.12.v20130726.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.io_8.1.12.v20130726.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.http_8.1.12.v20130726.jar"));

        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.http.servlet_1.1.400.v20130418-1354.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.http.jetty_3.0.200.v20131021-1843.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.http.servletbridge_1.0.300.v20130327-1442.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.servletbridge_1.3.0.v20130927-1541.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.common_3.6.200.v20130402-1505.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.registry_3.5.400.v20130717-1325.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.http.registry_1.1.300.v20130402-1529.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\org.osgi.service.obr-1.0.2.jar"));

        // Service bundles
        installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-httpservice-8.0.4.v20111024.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\ow2-httpservice-1.2-spec-1.0.0.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-osgi-boot-8.0.4.v20111024.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-deploy-8.0.4.v20111024.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-webapp-8.0.4.v20111024.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-security-8.0.4.v20111024.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-http-8.0.4.v20111024.jar"));
        installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-xml-8.0.4.v20111024.jar"));

        // Finally, required OSGI bundle
        installedBundles.add(context.installBundle("file:///MY_PATH\\app.jar"));

因此,通过这些更改,我有一个初始化的httpService对象,现在我想注册我的servlet实例

@Activate
protected void startup() {                    
   MyServlet servlet = new MyServlet();
   if (httpService != null) {
        System.out.println("Greetings! I just want to be sure that service isn't null!")
        //httpService.registerServlet("/req", servlet, null, null); // BAD PLACE
   } else {
        System.out.println("Something goes wrong")
   }
}

上面的代码片段将显示'Greetings'消息,但如果我尝试注册servlet并取消注释'BAD PLACE',则不会显示消息,也不会发生任何事情 . 也无法获得例外;看起来像'启动'方法被忽略了 . 有什么想法有什么不对吗?

2 回答

  • 1

    我没有看到你添加任何包含任何servlet容器(jetty或tomcat)的包 . 我也没有在列表中看到包含HttpService实现的包 .

    如果您需要一个有效的示例,请参阅"Jetty with HTTP service"部分下的依赖项here . 如果您通过传递方式导入这些依赖项及其依赖项,那么您将拥有一个带有HttpService的Jetty服务器 . 在示例中,依赖项被注释掉,因为它们仅在开发时使用 . 请注意,必须以定义以下系统属性的方式启动嵌入式servlet容器:

    jetty.port=8080
    jetty.home.bundle=org.eclipse.jetty.osgi.boot
    

    如果您使用Google,则可以找到Tomcat或Jetty的其他捆绑包 .

  • 0

    因此,已安装的软件包列表如下

    // without these bundles http service won't be initialized
    context.installBundle(libsDirectoryURL + "org.eclipse.equinox.util_1.0.500.v20130404-1337.jar");
    context.installBundle(libsDirectoryURL + "org.eclipse.equinox.ds_1.4.200.v20131126-2331.jar");          
    context.installBundle(libsDirectoryURL + "org.eclipse.osgi.services_3.4.0.v20131120-1328.jar");
    context.installBundle(libsDirectoryURL + "org.eclipse.equinox.http.servlet_1.1.400.v20130418-1354.jar");
    
    context.installBundle(libsDirectoryURL + "javax.servlet-api-3.0.1.jar");                                
    context.installBundle(libsDirectoryURL + "jetty-httpservice-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-server-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-osgi-boot-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-deploy-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-continuation-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-servlet-8.0.4.v20111024.jar"));
    context.installBundle(libsDirectoryURL + "jetty-webapp-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-server-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-security-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-http-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-io-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-util-8.0.4.v20111024.jar");
    context.installBundle(libsDirectoryURL + "jetty-xml-8.0.4.v20111024.jar");
    

    我想使用带有jetty 9.1.0的javax.servlet 3.1.0但是无法解决jetty-httpservice的问题,它依赖于org.eclipse.equinox.http.servlet(也许这个jar有一些版本适用于javax.servlet 3.1.0,但我没有找到它)

    我在bitbucket上发布了一个带有HttpService的嵌入式OSGI服务器的一些代码示例,也许有人发现它很有用:https://bitbucket.org/vbashur/diff/src/

相关问题