在 NetBeans IDE 中使用 CDI 将 OSGi 包作为服务注入

本文档介绍了 NetBeans IDE 中对开放服务网关协议 (OSGi) 的集成支持如何简化创建 OSGi 包并在项目中使用该包的流程。在本教程中,将首先通过 Maven OSGi 包原型创建两个简单的 OSGi 包,然后将这些包部署到 GlassFish Server Open Source Edition 3.1 中。

创建基本的 OSGi 包后,将创建 Web 客户端应用程序,并使用 CDI 将这些包作为服务注入。然后,将 Web 应用程序作为包部署到服务器。本教程接着将介绍如何使用 OSGi 管理控制台处理 OSGi 包。

在企业应用程序中使用 OSGi 包可以为更新各个包提供更大的模块性和灵活性。GlassFish Server 中对 OSGi 的便捷支持可以轻松将包合并到应用程序中。

本教程基于 TOTD #154:GlassFish 3.1 中的动态 OSGi 服务 - 使用 CDI 和 @OSGiService 博客帖子和其他博客条目(可在 Arun Gupta 的博客上找到)。请确保访问此博客,并查看许多其他有关使用 OSGi 的优秀博客。

此外,以下资源中包含各种有关在混合应用程序中使用 OSGi 和 CDI 的信息。

教程练习

此页上的内容适用于 NetBeans IDE 7.2、7.3、7.4 和 8.0

要学习本教程,您需要具备以下软件和资源。

软件或资源 要求的版本
NetBeans IDE 7.2、7.3、7.4、8.0、Java EE 版本
Java 开发工具包 (JDK) 版本 7 或 8
GlassFish Server Open Source Edition 3.1.x 或 4.x

先决条件

本文档假定您具备以下技术的一些基本知识或编程经验:

  • Java 编程
  • NetBeans IDE
  • Maven 框架

在开始本教程之前,您可以先阅读下面这些文档。

创建父 POM 项目

在本节中,将为您要在本教程中创建的 OSGi 包创建父 POM 项目。此外,还将编辑项目 POM (pom.xml),以添加要作为依赖关系被子项目继承的依赖关系管理元素。

  1. 从主菜单中选择 "New Project"(新建项目)(Ctrl-Shift-N 组合键;在 Mac 中为 ⌘-Shift-N 组合键)。
  2. 从 "Maven" 类别中选择 "POM Project"(POM 项目)。
    新建项目向导的屏幕快照
  3. 键入 MavenOSGiCDIProject 作为项目名称。单击 "Finish"(完成)。

    单击 "Finish"(完成),此时 IDE 将创建 POM 项目并在 "Projects"(项目)窗口中打开该项目。

  4. 在 "Projects"(项目)窗口中展开 "Project Files"(项目文件)节点,然后双击 pom.xml 在编辑器中打开该文件。

    项目的基本 POM 应类似于以下内容。

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.mycompany</groupId>
        <artifactId>MavenOSGiCDIProject</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>pom</packaging>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    </project>
            
  5. 修改父 pom.xml 以添加下列元素。保存所做的更改。
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.mycompany</groupId>
        <artifactId>MavenOSGiCDIProject</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>pom</packaging>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.osgi</groupId>
                    <artifactId>org.osgi.core</artifactId>
                    <version>4.2.0</version>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>
            

在本练习中,您显式指定了要在项目中使用的工件和工件版本。通过使用依赖关系管理并在父 POM 中指定工件,可以使子项目中的 POM 更为简单,并确保依赖关系版本在项目中的一致性。

有关使用依赖关系管理的详细信息,请参见依赖关系机制简介

创建 OSGi 包项目

新建项目向导中的 "Maven" 类别包含用于创建 OSGi 包项目的“OSGi 包”原型。创建 OSGi 包项目时,构建的 POM 声明 org.osgi.core JAR 作为附属项,并指定 maven-bundle-plugin 用于构建项目。

创建 MavenHelloServiceApi 接口包

在本练习中,将使用新建项目向导创建一个 OSGi 包项目,该项目将提供一个由其他包实现的简单接口。创建了包和接口后,将修改 POM 以更新对您在父 POM 项目中指定的 org.osgi.core 工件的依赖关系。

  1. 选择 "File"(文件)> "New Project"(新建项目)以打开新建项目向导。
  2. 从 "Maven" 类别中选择 "OSGi Bundle"(OSGi 包)。单击 "Next"(下一步)。
    新建项目向导的屏幕快照
  3. 键入 MavenHelloServiceApi 作为项目名称。
  4. 单击 "Browse"(浏览),并选择 MavenOSGiCDIProject POM 项目作为位置。单击 "Finish"(完成)。

    单击 "Finish"(完成),此时 IDE 将创建包项目并在 "Projects"(项目)窗口中打开该项目。如果在编辑器中打开 MavenHelloServiceApi 项目的 pom.xml,则可以看到 packaging 元素指定了 bundle 并且构建包时将使用 maven-bundle-plugin

    <project>
        <modelVersion>4.0.0</modelVersion>
        <parent>
        <artifactId>MavenOSGiCDIProject</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
        </parent>
    
        <groupId>com.mycompany</groupId>
        <artifactId>MavenHelloServiceApi</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>bundle</packaging>
        <name>MavenHelloServiceApi OSGi Bundle</name>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.osgi</groupId>
                <artifactId>org.osgi.core</artifactId>
                <version>4.3.0</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>maven-bundle-plugin</artifactId>
                    <version>2.3.7</version>
                    <extensions>true</extensions>
                    <configuration>
                        <instructions>
                            <Bundle-Activator>com.mycompany.mavenhelloserviceimpl.Activator</Bundle-Activator>
                            <Export-Package />
                        </instructions>
                    </configuration>
                </plugin>
    
                ...
            </plugins>
        </build>
    
        ...
    <project>

    此外,您还可以看到,使用 Maven OSGi 包原型创建 OSGi 包项目时,IDE 在默认情况下将 org.osgi.core 工件添加为依赖关系。

  5. 在 "Projects"(项目)窗口中右键单击 "MavenHelloServiceApi" 项目节点,然后选择 "Properties"(属性)。
  6. 在 "Project Properties"(项目属性)对话框中选择 "Sources"(源)类别。
  7. Source/Binary Format(源代码/二进制格式)设置为 "1.6",并确认 Encoding(编码)是 "UTF-8"。单击 "OK"(确定)。
  8. 在 "Projects"(项目)窗口中右键单击 "Source Packages"(源包)节点,然后选择 "New"(新建)> "Java Interface"(Java 接口)。
  9. 键入 Hello 作为类名。
  10. 在 "Package"(包)中选择 com.mycompany.mavenhelloserviceapi。单击 "Finish"(完成)。
  11. 将以下 sayHello 方法添加到接口中(以粗体显示),然后保存所做的更改。
    public interface Hello {
        String sayHello(String name);
    }
  12. 在 "Projects"(项目)窗口中右键单击项目节点,并选择 "Build"(构建)。

    构建项目后,如果打开 "Files"(文件)窗口,并展开项目节点,则可以看到在 target 文件夹中创建了 MavenHelloServiceApi-1.0-SNAPSHOT.jar

    "Files"(文件)窗口中项目的屏幕快照

    构建项目时,maven-bundle-plugin 将处理 MANIFEST.MF 文件的构建。如果打开已编译的 JAR 中的 MANIFEST.MF 文件,将看到此插件已生成一个清单标题,此标题声明了导出包。对于 OSGi,要公开并可供其他包使用的所有包都必须列在 MANIFEST.MFExport-Package 元素中。

  13. 确认 MANIFEST.MF 包含 Export-Package 元素(以下示例中粗体显示的元素)。
    Manifest-Version: 1.0
    Bnd-LastModified: 1395049732676
    Build-Jdk: 1.7.0_45
    Built-By: nb
    Bundle-Activator: com.mycompany.mavenhelloserviceapi.Activator
    Bundle-ManifestVersion: 2
    Bundle-Name: MavenHelloServiceApi OSGi Bundle
    Bundle-SymbolicName: com.mycompany.MavenHelloServiceApi
    Bundle-Version: 1.0.0.SNAPSHOT
    Created-By: Apache Maven Bundle Plugin
    Export-Package: com.mycompany.mavenhelloserviceapi;uses:="org.osgi.frame
     work";version="1.0.0.SNAPSHOT"
    Import-Package: org.osgi.framework;version="[1.6,2)"
    Tool: Bnd-1.50.0

    OSGi 容器将读取 Export-Package 清单标题以确定可以从包外部访问此包中的类。在此示例中,com.mycompany.mavenhelloserviceapi 包中的类是公开的。

    注:如果 MANIFEST.MF 不包含 Export-Package 元素,则您需要在 "Project Properties"(项目属性)窗口中启用插件的默认插件行为,并重新构建项目。在 "Project Properties"(项目属性)窗口中,选择 "Export Packages"(导出包)类别,然后选择 Default maven-bundle-plugin behavior(默认 maven-bundle-plugin 行为)选项。可以使用 "Project Properties"(项目属性)窗口的 "Export Packages"(导出包)面板显式指定应公开的包,或直接在 pom.xml 中指定包。

创建 MavenHelloServiceImpl 实现包

在本练习中,您将在 POM 项目中创建 MavenHelloServiceImpl。

  1. 选择 "File"(文件)> "New Project"(新建项目)以打开新建项目向导。
  2. 从 "Maven" 类别中选择 "OSGi Bundle"(OSGi 包)。单击 "Next"(下一步)。
  3. 键入 MavenHelloServiceImpl 作为项目名称。
  4. 单击 "Browse"(浏览),并选择 MavenOSGiCDIProject POM 项目作为位置(如果未选择)。单击 "Finish"(完成)。
  5. 右键单击 "Projects"(项目)窗口中的项目节点,然后选择 "Properties"(属性)。
  6. 在 "Project Properties"(项目属性)对话框中选择 "Sources"(源)类别。
  7. Source/Binary Format(源代码/二进制格式)设置为 "1.6",并确认 Encoding(编码)是 "UTF-8"。单击 "OK"(确定)。
  8. 在 "Projects"(项目)窗口中右键单击 "Source Packages"(源包)节点,然后选择 "New"(新建)> "Java Class"(Java 类)。
  9. 键入 HelloImpl 作为类名。
  10. 选择 com.mycompany.mavenhelloserviceimpl 作为包。单击 "Finish"(完成)。
  11. 键入以下内容(以粗体显示),并保存所做的更改。
    public class HelloImpl implements Hello {
        
        public String sayHello(String name) {
            return "Hello " + name;
        }
    }

    实现 Hello 时,IDE 将显示一个错误,您需要将 MavenHelloServiceApi 项目添加为依赖关系才能解决该错误。

  12. 在 "Projects"(项目)窗口中右键单击 MavenHelloServiceImpl 的 "Dependencies"(依赖关系)节点,然后选择 "Add Dependency"(添加依赖关系)。
  13. 在 "Add Library"(添加库)对话框中,单击 "Open Projects"(打开的项目)标签。
  14. 选择 "MavenHelloServiceApi OSGi Bundle"(MavenHelloServiceApi OSGi 包)。单击 "ADD"(添加)。
    "Add Library"(添加库)对话框的屏幕快照
  15. 右键单击在编辑器中打开的 HelloImpl.java 类,然后选择 "Fix Imports"(修复导入)(Alt-Shift-I 组合键;在 Mac 上为 ⌘-Shift-I 组合键),以添加 com.mycompany.mavenhelloserviceapi.Hello 的 import 语句。保存所做的更改。
  16. 展开 com.mycompany.mavenhelloserviceimpl 包并双击 Activator.java,即可在编辑器中打开该文件。
    "Projects"(项目)窗口的屏幕快照

    IDE 在项目中自动创建了 Activator.java 包激活器类。包激活器用于管理包的生命周期。包激活器类在包的 MANIFEST.MF 中声明,并在容器启动该包时实例化。

    OSGi 包不需要包激活器类,但可以使用激活器类中的 start() 方法,例如,用于初始化包所需的服务或其他资源。在此练习中将向类中添加一些代码行,将消息打印到 "Output"(输出)窗口。这将更便于确定包启动和停止的时间。

  17. 修改包激活器类中的 start()stop() 方法,以添加下列行(以粗体显示)。
    public class Activator implements BundleActivator {
    
        public void start(BundleContext context) throws Exception {
            System.out.println("HelloActivator::start");
            context.registerService(Hello.class.getName(), new HelloImpl(), null);
            System.out.println("HelloActivator::registration of Hello service successful");
        }
    
        public void stop(BundleContext context) throws Exception {
            context.ungetService(context.getServiceReference(Hello.class.getName()));
            System.out.println("HelloActivator stopped");
        }
    }

    可以看到包激活器类导入了 org.osgi.framework.BundleActivatororg.osgi.framework.BundleContext。默认情况下,生成的类包含两个方法:start()stop()。OSGi 框架调用 start()stop() 方法来启动和停止包提供的功能。启动包时,包提供的服务组件会在 OSGi 服务注册表中进行注册。注册包之后,其他包可以使用注册表进行查找,然后通过包上下文使用活动服务。

    如果查看项目的 POM,则可以在 maven-bundle-plugin 的配置元素下方看到用于指定包激活器的 <Bundle-Activator> 元素。

    <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>2.3.7</version>
        <extensions>true</extensions>
          <configuration>
                <instructions>
                      <Bundle-Activator>com.mycompany.mavenhelloserviceimpl.Activator</Bundle-Activator>
                </instructions>
          </configuration>
    </plugin>

    在构建包时,该插件将在 JAR 的包清单文件中构建清单标题,并指定包激活器类。部署包时,OSGi 运行时在清单文件中查找 Bundle-Activator 标题。

  18. Activator.java 中修复 import 语句,以导入 com.mycompany.mavenhelloserviceapi.Hello。保存所做的更改。
  19. 展开 "Dependencies"(依赖关系)节点,然后确认 org.osgi.core 工件作为依赖关系列出。

    注:通过右键单击该工件并选择 "Remove Dependency"(移除依赖关系),移除 "Dependencies"(依赖关系)节点下列出的该工件的所有早期版本。唯一的依赖关系应是 MavenHelloServiceApi 项目和 org.osgi.core 工件。

    "Projects"(项目)窗口的屏幕快照

构建和部署 OSGi 包

在本练习中,将构建 OSGi 包,并将这些包部署到 GlassFish。

  1. 在 "Projects"(项目)窗口中,右键单击 "MavenOSGiCDIProject" 节点,然后选择 "Clean and Build"(清理并构建)。

    构建项目时,IDE 将在每个项目的 target 文件夹中创建 JAR 文件,还将在本地资源库中安装快照 JAR。在 "Files"(文件)窗口中,可以展开两个包项目中任一个的 target 文件夹,以查看两个 JAR 档案(MavenHelloServiceApi-1.0-SNAPSHOT.jarMavenHelloServiceImpl-1.0-SNAPSHOT.jar)。

  2. 启动 GlassFish Server(如果尚未启动)。
  3. MavenHelloServiceApi-1.0-SNAPSHOT.jar 复制到 GlassFish 安装的 glassfish/domains/domain1/autodeploy/bundles/ 目录。

    此时 "Output"(输出)窗口的 GlassFish Server 日志中应显示类似于以下内容的输出。

    INFO: Started bundle: file:/glassfish-4.0/glassfish/domains/domain1/autodeploy/bundles/MavenHelloServiceApi-1.0-SNAPSHOT.jar
    

    在 "Services"(服务)窗口中右键单击 "GlassFish Server" 节点,然后选择 "View Domain Server Log"(查看域服务器日志)(如果 "Output"(输出)窗口中不显示服务器日志)。

  4. 重复执行相关步骤,将 MavenHelloServiceImpl-1.0-SNAPSHOT.jar 复制到 autodeploy/bundles 目录。

现在,GlassFish Server 日志中应显示类似于以下内容的输出。

INFO: HelloActivator::start
INFO: HelloActivator::registration of Hello service successful
INFO: Started bundle: file:/glassfish-4.0/glassfish/domains/domain1/autodeploy/bundles/MavenHelloServiceImpl-1.0-SNAPSHOT.jar
INFO: Started bundle: file:/glassfish-4.0/glassfish/domains/domain1/autodeploy/bundles/MavenHelloServiceImpl-1.0-SNAPSHOT.jar
        

或者,也可以从 GlassFish OSGi 管理控制台安装包。有关详细信息,请参见安装和使用 OSGi 管理控制台部分。

创建 Web 客户端应用程序

此部分演示如何创建访问 OSGi 包提供的服务的 Java EE Web 客户端。将在 Web 应用程序中创建一个简单 Servlet,然后注入声明的服务。创建项目前,将向父 POM 项目中添加一些依赖关系管理元素。

在父 POM 项目中配置依赖关系

在本练习中,将指定父 POM 项目中的依赖关系元素。此外,还将添加项目要使用的工件的资源库。

  1. 在 "Projects"(项目)窗口中展开 MavenOSGiCDIProject 项目的 "Project Files"(项目文件)节点,然后双击 pom.xml 在编辑器中打开该文件。
  2. 修改父 pom.xml 以添加下列依赖关系管理元素(以粗体显示)。保存所做的更改。
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.mycompany</groupId>
        <artifactId>MavenOSGiCDIProject</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>pom</packaging>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        ...    
                
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.osgi</groupId>
                    <artifactId>org.osgi.core</artifactId>
                    <version>4.3.0</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>org.osgi</groupId>
                    <artifactId>org.osgi.compendium</artifactId>
                    <version>4.2.0</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>org.glassfish</groupId>
                    <artifactId>osgi-cdi-api</artifactId>
                    <version>3.1-b41</version>
                    <type>jar</type>
                    <scope>provided</scope>
                </dependency>
              
            </dependencies>
        </dependencyManagement>
    
        ...
    </project>
    
  3. 添加下列元素,将 GlassFish 资源库添加到 POM 中。保存所做的更改。
    <project>
    
        ...
    
        </dependencyManagement>
    
        <repositories>
            <!-- glassfish nexus repo for glassfish dependencies -->
            <repository>
                <id>glassfish-repo-archive</id>
                <name>Nexus repository collection for Glassfish</name>
                <url>http://maven.glassfish.org/content/groups/glassfish</url>
                <snapshots>
                    <updatePolicy>never</updatePolicy>
                </snapshots>
            </repository>
        </repositories>
        <modules>
            <module>MavenHelloServiceApi</module>
            <module>MavenHelloServiceImpl</module>
        </modules>
    </project>
                

将 GlassFish 资源库添加到 POM 后,如果在 "Services"(服务)窗口中查看 "Maven Repositories"(Maven 资源库)节点下的资源库列表,将会看到 IDE 为 GlassFish 资源库自动添加了一个节点。默认情况下,IDE 会为本地 Maven 资源库显示一个节点。在打开的项目指定资源库时,IDE 将在 "Maven Repositories"(Maven 资源库)节点下为该资源库自动添加一个节点。

"Maven Repositories"(Maven 资源库)窗口的屏幕快照

在本练习中,您添加了其他要在项目中使用的工件和工件版本。此外,您还添加了包含 osgi-cdi-api 工件的 GlassFish 资源库。

创建 MavenHelloWebClient Web 应用程序

首先,将创建常规的 Web 应用程序,然后修改项目将其作为 OSGi 包(Web 应用程序包 (WAB))。

  1. 从主菜单中选择 "File"(文件)> "New Project"(新建项目)。
  2. 从 "Maven" 类别中选择 "Web Application"(Web 应用程序)。单击 "Next"(下一步)。
  3. 键入 MavenHelloWebClient 作为项目名称。
  4. 单击 "Browse"(浏览),并选择 MavenOSGiCDIProject POM 项目作为位置(如果尚未选择)。单击 "Next"(下一步)。
  5. 选择 "GlassFish Server" 作为服务器,并选择 "Java EE 6 Web" 或 "Java EE 7 Web" 作为 Java EE 版本。单击 "Finish"(完成)。
  6. 右键单击项目节点,然后选择 "New"(新建)> "Servlet"。
  7. 键入 HelloServlet 作为类名。
  8. 选择 com.mycompany.mavenhellowebclient 作为包。单击 "Finish"(完成)。
  9. 删除 Servlet 中已由 IDE 生成的默认方法(processRequestdoGetdoPostgetServletInfo)。

    注:需要展开编辑器折叠才能删除 HttpServlet 方法。

  10. 键入以下将注入服务的代码(以粗体显示)。
    @WebServlet(name = "HelloServlet", urlPatterns = {"/HelloServlet"})
    public class HelloServlet extends HttpServlet {
    
        @Inject
        @OSGiService(dynamic=true)
        Hello hello;
    }
  11. 添加以下 doGet 方法。
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            PrintWriter out = response.getWriter();
            out.println(hello.sayHello("Duke"));
        }
  12. 右键单击项目节点,然后选择 "New"(新建)> "Other"(其他)。
  13. 在 "Contexts and Dependency Injection"(上下文和依赖关系注入)类别中选择 beans.xml。单击 "Next"(下一步)。
  14. 使用默认文件名 (beans)。单击 "Finish"(完成)。

    单击 "Finish"(完成),此时该向导将在 Web 应用程序中创建 beans.xml 文件。如果 beans.xml 是该应用程序的一部分,则系统将自动启用 CDI。

  15. 修改 beans.xml 文件以将 bean-discovery-mode 的默认值更改为 all
    bean-discovery-mode="all"

    保存更改并关闭文件。

    有关 bean-discovery-mode 值之间的差异的详细信息,请参见以下页:

  16. 在 "Projects"(项目)窗口中右键单击 "MavenHelloWebClient" 的 "Dependencies"(依赖关系)节点,然后选择 "Add Dependency"(添加依赖关系)。
  17. 选择 Provided 作为作用域。
  18. 在 "Add Library"(添加库)对话框中单击 "Open Projects"(打开的项目)标签,然后选择 MavenHelloServiceApi OSGi Bundle(MavenHelloServiceApi OSGi 包)。单击 "ADD"(添加)。
  19. 再次右键单击 "Dependencies"(依赖关系)节点,然后选择 "Add Dependency"(添加依赖关系)。
  20. 在 "Add Library"(添加库)对话框中单击 "Dependency Management"(依赖关系管理)标签,然后选择在父 POM 项目中指定的 osgi-cdi-api 工件。单击 "ADD"(添加)。
    "Add Library"(添加库)对话框的屏幕快照
  21. 在编辑器中右键单击 HelloServlet.java,然后选择 "Fix Imports"(修复导入)(Alt-Shift-I 组合键;在 Mac 上为 ⌘-Shift-I 组合键),以添加 com.mycompany.mavenhelloserviceapi.Hellojavax.inject.Injectorg.glassfish.osgicdi.OSGiService。保存所做的更改。

    注:如果 IDE 未自动添加 com.mycompany.mavenhelloserviceapi.Hello 的 import 语句,则可能需要手动进行添加。

  22. 右键单击 "MavenOSGiCDIProject",然后选择 "Clean and Build"(清理并构建)。

构建项目时,"Output"(输出)窗口中应显示类似于以下内容的输出。

Reactor Summary:

MavenOSGiCDIProject ............................... SUCCESS [0.798s]
MavenHelloServiceApi OSGi Bundle .................. SUCCESS [7.580s]
MavenHelloServiceImpl OSGi Bundle ................. SUCCESS [1.142s]
MavenHelloWebClient ............................... SUCCESS [8.072s]
------------------------------------------------------------------------
BUILD SUCCESS

注:如果在构建 MavenOSGiCDIProject 项目时未自动构建 Web 应用程序,则您需要手动构建 Web 应用程序。

在 "Files"(文件)窗口中,展开 Web 应用程序的项目节点,并确认在目标目录中创建了档案 MavenHelloWebClient-1.0-SNAPSHOT.war。如果展开 Web 客户端的 WAR 档案并检查 MANIFEST.MF,则会看到清单中包含类似于以下内容的行。

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: nb
Build-Jdk: 1.7.0_45

以 OSGi 包的形式构建 Web 应用程序

要使用 @OSGiService 并检索已注册的 OSGi 包,您需要将 Web 应用程序作为可访问 BundleContext 的包。要使 WAR 成为 OSGi 包(Web 应用程序包),可将 Web-ContextPath 元数据添加到 WAR 中的 MANIFEST.MF 要执行此操作,请在 maven-bundle-plugin 的说明中指定 <Web-ContextPath> 元素,该元素将包含在由插件生成的清单中。然后,修改 maven-war-plugin 配置,以指示插件将 maven-bundle-plugin 生成的清单添加到 WAR 档案中。

  1. 在 "Projects"(项目)窗口中,展开 "MavenHelloWebClient" 下方的 "Project Files"(项目文件)节点,然后双击 pom.xml 在编辑器中打开该文件。
  2. 添加以下条目,将 maven-bundle-plugin 添加到 POM 中。
    <build> 
        <plugins>
            <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                 <version>2.2.0</version>
                 <extensions>true</extensions>
                 <configuration>
                     <supportedProjectTypes>
                         <supportedProjectType>ejb</supportedProjectType>
                         <supportedProjectType>war</supportedProjectType>
                         <supportedProjectType>bundle</supportedProjectType>
                         <supportedProjectType>jar</supportedProjectType>
                     </supportedProjectTypes>
                     <instructions>
                         <!-- Specify elements to add to MANIFEST.MF -->
                         <Web-ContextPath>/mavenhellowebclient</Web-ContextPath>
                         <!-- By default, nothing is exported -->
                         <Export-Package>!*.impl.*, *</Export-Package>
                     </instructions>
                 </configuration>
                 <executions>
                     <execution>
                         <id>bundle-manifest</id>
                         <phase>process-classes</phase>
                         <goals>
                             <goal>manifest</goal>
                         </goals>
                     </execution>
                     <execution>
                         <id>bundle-install</id>
                         <phase>install</phase>
                         <goals>
                             <goal>install</goal>
                         </goals>
                     </execution>
                 </executions>
             </plugin>
                
  3. 修改 maven-war-plugin 的配置元素,将包信息添加到 MANIFEST.MF 中。保存所做的更改。
     <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-war-plugin</artifactId>
         <version>2.3</version>
         <configuration>
             <archive>
                 <!-- add bundle plugin generated manifest to the war -->
                 <manifestFile>
                     ${project.build.outputDirectory}/META-INF/MANIFEST.MF
                 </manifestFile>
                 <!-- For some reason, adding Bundle-ClassPath in maven-bundle-plugin
                 confuses that plugin and it generates wrong Import-Package, etc.
                 So, we generate it here.-->
                 <manifestEntries>
                     <Bundle-ClassPath>WEB-INF/classes/</Bundle-ClassPath>
                 </manifestEntries>
             </archive>
             <failOnMissingWebXml>false</failOnMissingWebXml>
         </configuration>
     </plugin>
  4. 在 "Projects"(项目)窗口中,右键单击 "MavenHelloWebClient" 项目节点,然后选择 "Clean and Build"(清理并构建)。

如果您现在展开 WAR 档案,并在编辑器中打开 MANIFEST.MF,则会看到 MANIFEST.MF 现在包含其他信息,包括您在 maven-bundle-plugin 配置和包名称条目中指定的 Web-ContextPath: /mavenhellowebclient 条目。

Manifest-Version: 1.0
Export-Package: com.mycompany.mavenhellowebclient;uses:="com.mycompany
 .mavenhelloserviceapi,javax.servlet,org.glassfish.osgicdi,javax.injec
 t,javax.servlet.annotation,javax.servlet.http";version="1.0.0.SNAPSHO
 T"
Bundle-ClassPath: WEB-INF/classes/
Built-By: nb
Tool: Bnd-1.50.0
Bundle-Name: MavenHelloWebClient
Created-By: Apache Maven Bundle Plugin
Web-ContextPath: /mavenhellowebclient
Build-Jdk: 1.7.0_45
Bundle-Version: 1.0.0.SNAPSHOT
Bnd-LastModified: 1395053424008
Bundle-ManifestVersion: 2
Import-Package: com.mycompany.mavenhelloserviceapi;version="[1.0,2)",j
 avax.inject,javax.servlet,javax.servlet.annotation,javax.servlet.http
 ,org.glassfish.osgicdi;version="[1.0,2)"
Bundle-SymbolicName: com.mycompany.MavenHelloWebClient
Archiver-Version: Plexus Archiver

有关如何以 OSGi 包的形式构建 Web 应用程序的详细信息,请参见以下页。

部署 Web 应用程序包

在本练习中,您需要将 Web 应用程序包复制到 GlassFish 安装中的 autodeploy/bundles 文件夹。

  1. 导航至包含 MavenHelloWebClient-1.0-SNAPSHOT.wartarget 目录。
  2. MavenHelloWebClient-1.0-SNAPSHOT.war 复制到 GlassFish 安装的 autodeploy/bundles 文件夹中。

将 WAR 档案复制到目录时,GlassFish Server 日志中将显示类似于以下内容的输出。

INFO: Started bundle: file:/glassfish-3.1.1/glassfish/domains/domain1/autodeploy/bundles/MavenHelloWebClient-1.0-SNAPSHOT.war
...
INFO: ---- Injection requested for framework service type interface com.mycompany.mavenhelloserviceapi.Hello and annotated with dynamic=true, serviceCriteria=
INFO: WEB0671: Loading application [com.mycompany.MavenHelloWebClient_1.0.0.SNAPSHOT] at [/mavenhellowebclient]
INFO: Registered ServletContext as a service with properties: {osgi.web.symbolicname=com.mycompany.MavenHelloWebClient, osgi.web.version=1.0.0.SNAPSHOT, osgi.web.contextpath=/mavenhellowebclient} 
        

现在,您可以通过单击以下链接 http://localhost:8080/mavenhellowebclient/HelloServlet 在浏览器中查看 Servlet。

安装和使用 OSGi 管理控制台

您可以使用 GlassFish OSGi 管理控制台来安装、启动和停止部署到服务器上的 OSGi 包。在本练习中,将启用 GlassFish OSGi 管理控制台,然后查看已注册的 OSGi 包列表。

执行以下步骤安装所需的 GlassFish 附件以启用 OSGi 控制台,并查看 GlassFish 域管理控制台中的已部署包。

  1. 在浏览器中打开 GlassFish 域管理控制台。

    在 "Services"(服务)窗口中,右键单击 "GlassFish Server" 节点,然后选择 "View Domain Admin Console"(查看域管理控制台)。

  2. 单击左侧导航栏中的 "Update Tool"(更新工具)。
  3. 从可用附件列表中选择 glassfish-osgi-gui

    单击 "Install"(安装),然后接受许可证。

    GlassFish 管理控制台中 "Update Tool"(更新工具)的屏幕快照
  4. 重新启动 GlassFish Server。

    重要说明:如果您运行的是 GlassFish Server 3.1.2.2,则需要修改位于 GLASSFISH-INSTALL/glassfish/config/ 目录中的 osgi.properties 文件,并将 org.osgi.framework.startlevel.beginning 属性的值设置为 "2" (org.osgi.framework.startlevel.beginning=2)。
    有关更多详细信息,请参见以下论坛帖子:
    无法在 Glassfish 3.1.2.2 版中启动 Web 控制台

  5. 再次打开管理控制台,然后在左侧的导航栏中单击 Server (Admin Server)(服务器(管理服务器))。
  6. 单击 "OSGi Console"(OSGi 控制台)标签,以查看已部署的 OSGi 包列表。
    "Add Library"(添加库)对话框的屏幕快照

    注:系统可能会提示您输入用户名和口令来查看 OSGi 包列表。如果您在 "OSGi Console"(OSGi 控制台)标签中看不到包列表,请确认未隐藏授权对话框。如果您在安装 IDE 时安装了 GlassFish 4 Server,则此服务器的默认用户名为 admin。默认情况下口令为空。

您可以向下滚动列表,以查看已注册的 OSGi 包的状态,并启动和停止各个包。如果按 ID 对列表进行排序(从高到低),则会看到已部署的三个包显示在该列表的顶部附近。



另请参见

有关使用 NetBeans IDE 和 Maven 开发 OSGi 包的更多信息,请参见以下资源:

要发送意见和建议、获得支持以及随时了解 NetBeans IDE Java EE 开发功能的最新开发情况,请加入 nbj2ee 邮件列表

get support for the NetBeans

Support


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo