5.3. 在捆绑包中打包 Web 服务

5.3.1. 概述

本节介绍如何为 Apache CXF 应用程序修改现有 Maven 项目,以便项目生成适合在红帽 Fuse OSGi 容器中部署的 OSGi 捆绑包。要转换 Maven 项目,您需要修改项目的 POM 文件和项目的蓝图文件(位于 META-INF/spring中)。

5.3.2. 修改 POM 文件以生成捆绑包

要配置 Maven POM 文件来生成捆绑包,您需要进行两种更改:更改 POM 的软件包类型到 捆绑包 ;并将 Maven 捆绑插件添加到您的 POM。详情请查看 第 5.1 节 “生成捆绑包项目”

5.3.3. 必需的导入软件包

要让您的应用程序使用 Apache CXF 组件,您需要将其软件包导入到应用程序的捆绑包中。由于 Apache CXF 中的依赖关系的复杂特性,您无法依赖 Maven 捆绑包插件或 bnd 工具,以自动决定所需的导入。您需要明确声明它们。

您需要将以下软件包导入到您的捆绑包中:

javax.jws
javax.wsdl
javax.xml.bind
javax.xml.bind.annotation
javax.xml.namespace
javax.xml.ws
org.apache.cxf.bus
org.apache.cxf.bus.spring
org.apache.cxf.bus.resource
org.apache.cxf.configuration.spring
org.apache.cxf.resource
org.apache.cxf.jaxws
org.springframework.beans.factory.config

5.3.4. Maven bundle 插件说明示例

例 5.1 “配置强制导入软件包” 展示如何在 POM 中配置 Maven 捆绑插件以导入必需的软件包。必需的导入软件包在 Import-Package 元素内以逗号分隔列表的形式出现。请注意通配符(1)的外观,即,作为列表的最后一个元素。通配符确保扫描当前捆绑包中的 Java 源文件,以发现需要导入哪些附加软件包。

例 5.1. 配置强制导入软件包

<project ... >
    ...
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        ...
                        <Import-Package>
                            javax.jws,
                            javax.wsdl,
                            javax.xml.bind,
                            javax.xml.bind.annotation,
                            javax.xml.namespace,
                            javax.xml.ws,
                            org.apache.cxf.bus,
                            org.apache.cxf.bus.spring,
                            org.apache.cxf.bus.resource,
                            org.apache.cxf.configuration.spring,
                            org.apache.cxf.resource,
                            org.apache.cxf.jaxws,
                            org.springframework.beans.factory.config,
                            *
                        </Import-Package>
                        ...
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
    ...
</project>

5.3.5. 添加代码生成插件

Web 服务项目通常需要生成代码。Apache CXF 为 JAX-WS 前端提供两个 Maven 插件,这使您可以将代码生成步骤集成到您的构建中。插件选择取决于您使用 Java 优先方法或 WSDL-first 方法开发您的服务,如下所示:

  • java -first 方法- 使用 cxf-java2ws-plugin 插件。
  • WSDL-first 方法- 使用 cxf-codegen-plugin 插件。

5.3.6. OSGi 配置属性

OSGi 配置管理服务定义了将配置设置传递给 OSGi 捆绑包的机制。您不必使用此服务进行配置,但它通常是配置捆绑包应用程序的最便捷方式。蓝图提供对 OSGi 配置的支持,可让您使用从 OSGi 配置管理员服务获取的值替换 Blueprint 文件中的变量。

有关如何使用 OSGi 配置属性的详情,请参考 第 5.3.7 节 “配置捆绑插件”第 9.6 节 “在功能中添加 OSGi 配置”

5.3.7. 配置捆绑插件

概述

捆绑包插件需要很少的信息才能正常工作。所有所需属性都使用默认设置来生成有效的 OSGi 捆绑包。

虽然您可以使用默认值创建有效的捆绑包,但您可能需要修改某些值。您可以在插件的 instructions 元素中指定大多数属性。

配置属性

一些常用的配置属性有:

设置捆绑包的符号链接

默认情况下,Bundle 插件将 Bundle-SymbolicName 属性的值设置为 groupId + "." + artifactId,其例外情况如下:

  • 如果 groupId 只有一个部分(无点),则返回第一个带有类的软件包名称。

    例如,如果组 Id 是 commons-logging:commons-logging,则捆绑包的符号链接是 org.apache.commons.logging

  • 如果 artifactId 等于 groupId 的最后部分,则使用 groupId

    例如,如果 POM 指定组 ID 和工件 ID 作为 org.apache.maven:maven,则捆绑包的符号链接名为 org.apache.maven

  • 如果 artifactIdgroupId 的最后部分开始,该部分会被删除。

    例如,如果 POM 指定组 ID 和工件 ID 作为 org.apache.maven:maven-core,则捆绑包的符号链接名为 org.apache.maven.core

要为捆绑包符号名称指定您自己的值,在插件的 instructions 元素中添加 Bundle-SymbolicName 子,如 例 5.2 “设置捆绑包的符号链接” 所示。

例 5.2. 设置捆绑包的符号链接

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
     ...
    </instructions>
  </configuration>
</plugin>

设置捆绑包的名称

默认情况下,捆绑包的名称设置为 ${project.name}

要为捆绑包名称指定您自己的值,在插件的 instructions 元素中添加 Bundle-Name 子部分,如 例 5.3 “设置捆绑包的名称” 所示。

例 5.3. 设置捆绑包的名称

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-Name>JoeFred</Bundle-Name>
     ...
    </instructions>
  </configuration>
</plugin>

设置捆绑包的版本

默认情况下,捆绑包的版本设置为 ${project.version}。所有横线(-)替换为句点(.),数字最多可为四位数。例如,4.2-SNAPSHOT 变为 4.2.0.SNAPSHOT

要为捆绑包版本指定您自己的值,将 Bundle-Version 子添加到插件的 instructions 元素中,如 例 5.4 “设置捆绑包的版本” 所示。

例 5.4. 设置捆绑包的版本

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-Version>1.0.3.1</Bundle-Version>
     ...
    </instructions>
  </configuration>
</plugin>

指定导出的软件包

默认情况下,OSOS 清单的 Export-Package 列表由您的本地 Java 源代码中的所有软件包(在 src/main/java 下)填充(在 src/main/java下), 默认软件包. 以及包含 .impl.internal 的软件包。

重要

如果您在插件配置中使用 Private-Package 元素,且您没有指定要导出的软件包列表,则默认行为仅包含捆绑包中的 Private-Package 元素中列出的软件包。没有导出软件包。

默认行为可能会导致非常大的软件包,并导出应保持私有的软件包。要更改导出的软件包列表,您可以在插件的 instructions 元素中添加 Export-Package child。

Export-Package 元素指定要包含在捆绑包中的软件包列表,并要导出。可以使用 * 通配符符号指定软件包名称。例如,条目 com.fuse.demo.* 包含项目类路径上以 com.fuse.demo 开头的所有软件包。

您可以指定要排除的软件包,用 ! 前缀。例如,条目 !com.fuse.demo.private 排除软件包 com.fuse.demo.private

当排除软件包时,列表中的条目顺序非常重要。这个列表会根据开始的顺序处理,并忽略后续迭代条目。

例如,要包含以 com.fuse.demo 开头的所有软件包,除了软件包 com.fuse.demo.private 外,请使用以下内容列出软件包:

!com.fuse.demo.private,com.fuse.demo.*

但是,如果您使用 com.fuse.demo.*,!com.fuse.demo.private 列出软件包,那么捆绑包中包含 com.fuse.demo.private,因为它与第一个模式匹配。

指定私有软件包

如果要在导出捆绑包中指定要包含在捆绑包中的软件包列表,您可以在捆绑包插件配置中添加 Private-Package 指令。默认情况下,如果您没有指定 Private-Package 指令,则捆绑包中包含您本地 Java 源中的所有软件包。

重要

如果软件包与 Private-Package 元素和 Export-Package 元素中的条目匹配,则 Export-Package 元素将具有优先权。软件包会添加到捆绑包中并导出。

Private-Package 元素的工作方式与 导出-Package 元素类似,您会指定要包含在捆绑包中的软件包列表。bundle 插件使用列表来查找要包含在捆绑包中的项目的类路径上的所有类。这些软件包打包在捆绑包中,但不导出(除非它们也由 Export-Package 指令选择)。

例 5.5 “在捆绑包中包含私有软件包” 显示在捆绑包中包含私有软件包的配置

例 5.5. 在捆绑包中包含私有软件包

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Private-Package>org.apache.cxf.wsdlFirst.impl</Private-Package>
     ...
    </instructions>
  </configuration>
</plugin>

指定导入的软件包

默认情况下,Bundle 插件使用捆绑包内容引用的所有软件包列表填充 OSGi 清单的 Import-Package 属性。

虽然默认行为通常足以满足大多数项目,但您可能会发现您要导入不会自动添加到列表中的软件包的实例。默认行为也可以导致导入不需要的软件包。

要指定要由捆绑包导入的软件包列表,请将 Import-Package child 添加到插件的 instructions 元素中。软件包列表的语法与 Export-Package 元素和 Private-Package 元素的语法相同。

重要

使用 Import-Package 元素时,插件不会自动扫描捆绑包的内容,以确定是否存在所需的导入。要确保对捆绑包的内容进行了扫描,您必须在软件包列表中放置一个 * 作为最后一个条目。

例 5.6 “指定捆绑包导入的软件包” 显示指定捆绑包导入的软件包的配置

例 5.6. 指定捆绑包导入的软件包

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Import-Package>javax.jws, javax.wsdl, org.apache.cxf.bus, org.apache.cxf.bus.spring, org.apache.cxf.bus.resource, org.apache.cxf.configuration.spring, org.apache.cxf.resource, org.springframework.beans.factory.config, * </Import-Package>
     ...
   </instructions>
  </configuration>
</plugin>

更多信息

有关配置捆绑包插件的详情,请参考:

5.3.8. OSGI configAdmin 文件命名规则

PID 字符串(symbolic-name 语法)允许在 OSGI 规格中允许连字符。但是,连字符由 Apache Felix.fileinstallconfig:edit shell 命令解释,以区分"托管服务"和"托管服务工厂"。因此,建议您不要在 PID 字符串的其他位置使用连字符。

注意

配置文件名称与 PID 和 factory PID 相关。