Bundlor 入门

工程 | Ben Hale | March 20, 2009 | ...

正如 Rob 的文章 所指出的,过去几个月里,我们对人们如何管理自己的 OSGi 应用程序有了不少了解。

我们发现,一些开发者希望自己管理 bundle manifests,但需要一些帮助来自动化细节,例如跨各种导入指定包版本。另一些开发者则希望根据项目内容和构建文件中指定的依赖关系生成 manifests。此外,这两类开发者都需要使用没有必要 OSGi 元数据(使其能够在 OSGi 服务平台中使用)的现有库。

Bundlor 为所有这些情况提供了解决方案,并且是我们内部长期以来用于管理发布到 SpringSource Enterprise Bundle Repository 的 bundles 的工具。Bundlor 自动化检测依赖关系并在 JAR 创建后生成 OSGi manifest 指令。它接收一个 JAR 和一个包含标准 OSGi manifest header 超集的模板作为输入。然后它分析 JAR 中包含的源代码和支持文件,将模板应用于结果,并生成一个 manifest。

模板机制

Bundlor 模板机制使用标准的 Java manifest 格式,并包含标准 OSGi manifest header 的超集。下表列出了所有 Bundlor 特定的 manifest 模板 header 及其用法。
Header 描述
Excluded-Exports 一个逗号分隔的包列表,不得添加到 manifest 的Export-Packageheader 中。
Excluded-Imports 默认情况下,Bundlor 会为它确定由 jar 中的代码或特殊文件引用的每个包添加导入。此 header 允许指定一个逗号分隔的包列表,Bundlor 不会为其生成导入。
Export-Template 默认情况下,Bundlor 将所有导出的包版本设为指定的Bundle-Version。此 header 允许单独导出的包以不同的版本导出。例如:Export-Template com.foo.*;version="1.5"这将导致任何Export-Package的条目,对于com.foo或其子包,版本为1.5.
Ignored-Existing-Headers 对于要生成 manifest 的 JAR 已包含 OSGi 兼容 manifest 的情况,此 header 可用于列出原始 manifest 中 Bundlor 应忽略的 header。
Import-Template 此 header 用于增强 Bundlor 通过字节码和特殊文件分析生成的包导入。通常,这用于指定导入版本,并在某些情况下将其标记为可选。header 的值采用逗号分隔的包名和属性列表形式。
支持在包名末尾使用通配符 '*' 来匹配多个包。例如:Import-Template: com.foo;version=[1.0,2.0);resolution:=optional,com.bar.*;version="[1.5,1.6)"这将导致为com.foo包生成的任何导入,版本范围为 [1.0, 2.0)(包含 1.0,不包含 2.0),并被视为可选;而对于任何导入com.bar或其子包,版本范围为 [1.5, 1.6)(包含 1.5,不包含 1.6)。

以下是一个来自 Spring Binding bundle 的 Bundlor manifest 模板示例,展示了通配符和显式Import-Package语句的用法。

Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.springframework.binding
Bundle-Name: Spring Binding
Bundle-Vendor: SpringSource
Import-Package:
 ognl;version="[2.6.9, 3.0.0)";resolution:=optional,
 org.jboss.el;version="[2.0.0, 3.0.0)";resolution:=optional
Import-Template:
 org.springframework.*;version="[2.5.4.A, 3.0.0)",
 org.apache.commons.logging;version="[1.1.1, 2.0.0)",
 javax.el;version="[2.1.0, 3.0.0)";resolution:=optional

检测标准

给定一个 JAR 文件,Bundlor 可以从多种来源检测候选项导入。有关可检测内容的完整列表和示例,请参阅用户指南

Bundlor 扫描以下类型:

  • Java 类
    • 声明类型的超类类型
    • 声明类型的已实现接口类型
    • 声明类型的注解类型
    • 声明的字段类型
    • 声明的字段值类型
    • 声明的方法参数类型
    • 声明的方法返回类型
    • 声明的方法异常类型
    • 声明的方法注解类型
    • 对字段所属类型的引用
    • 对字段类型的引用
    • 声明的局部变量类型
    • 对声明方法的类型的引用
    • 对方法返回类型的引用
    • 对方法参数类型的引用
    • 数组类型的分配
    • 声明的参数注解类型
    • 捕获的异常类型
    • 实例化类型
    • 强制转换目标类型
    • Instanceof 类型
    • 声明的常量类型
  • Spring 上下文配置文件
    • 指定的类名,未来将通过 Spring schema 的知识进行改进
  • JPA
    • providerclass标签,来自persistence.xml文件
  • Hibernate 映射文件
    • //class/@name
    • //id/@type
    • //generator/@class
    • //composite-id/@class
    • //discriminator/@type
    • //property/@type
    • //many-to-one/@class
    • //one-to-one/@class
    • //one-to-many/@class
    • //many-to-many/@class
    • //version/@type
    • //component/@class
    • //dynamic-component/@class
    • //subclass/@name
    • //joined-subclass/@name
    • //union-subclass/@name
    • //import/@class
  • 属性文件
    • 定义为属性值的类

获取 Bundlor

Bundlor 可从Bundlor 页面下载 zip 文件。它也可以作为 Ivy 和 Maven artifact 在 SpringSource Enterprise Bundle Repository 中获取。此外,还提供了详细的用户指南

使用 Bundlor

Bundlor 有四种不同的形式:
  • Apache Maven 插件
  • Apache ANT Task
  • 命令行应用程序
  • Eclipse 插件(更多信息请参阅单独的博客)
以下说明仅描述了 Bundlor 在每种环境中的简单用法。有关 Bundlor 语法的完整信息,请参阅用户指南

Maven

Maven 插件允许在 Maven 项目内部运行 Bundlor。使用此任务,可以将 JAR 转换为 bundle,或者将 manifest 输出到文件系统。

将 SpringSource Enterprise Bundle Repository 添加到pom.xml文件。

<pluginRepositories>
  <pluginRepository>
    <id>com.springsource.repository.bundles.milestone</id>
    <name>SpringSource Enterprise Bundle Repository</name>
    <url>http://repository.springsource.com/maven/bundles/milestone</url>
  </pluginRepository>
...
</pluginRepositories>

添加bundlor插件到pom.xml文件

<build>
  <plugins>
    <plugin>
      <groupId>com.springsource.bundlor</groupId>
      <artifactId>com.springsource.bundlor.maven</artifactId>
      <version>1.0.0.M2</version>
      <executions>
        <execution>
          <id>bundlor</id>
          <goals>
            <goal>transform</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  ...
  </plugins>
...
</build>

最后,使用 package 命令构建 bundle。

mvn install package

ANT

ANT 任务允许在任何基于 ANT 的构建系统内部运行 Bundlor。使用此任务,可以将 JAR 转换为 bundle。

要在 ANT 内部运行 Bundlor,首先需要定义一个bundlornamespace。

<project name="bundlor-sample-ant"
    xmlns:bundlor="antlib:com.springsource.bundlor.ant">

然后将 bundlor 任务导入到构建中。

<target name="bundlor.init">
  <taskdef resource="com/springsource/bundlor/ant/antlib.xml"
      uri="antlib:com.springsource.bundlor.ant">
    <classpath id="bundlor.classpath">
      <fileset dir="${bundlor.home}/dist"/>
      <fileset dir="${bundlor.home}/lib"/>
    </classpath>
  </taskdef>
</target>

最后,使用bundlor任务。

<bundlor:bundlor
    bundlePath="${basedir}/org.springframework.integration.jar"
    outputPath="${basedir}/target/org.springframework.integration.jar"
    bundleVersion="1.0.2.BUILD-${timestamp}"
    manifestTemplatePath="${basedir}/template.mf"/>

命令行

命令行界面是使用 manifest 模板快速显示 Bundlor 生成的 bundle 的 OSGi manifest 或实际转换 bundle 的一种方式。

要在命令行运行 Bundlor,请将目录更改到$BUNDLOR_HOME/bin目录,并运行bundlor.shbundlor.bat.

% ./bundlor.sh transform \
--bundle ./org.springframework.integration.jar \
--manifest ./template.mf \
--outputfile ./target/org.springframework.integration.jar

Transformed bundle written to ./target/org.springframework.integration.jar
%

Bundlor 的未来

Bundlor 是一个新产品,有很大的成长空间。Bundlor 现在使用 Scrum 进行规划,我们希望这能让社区更清晰地了解开发过程。当前的 sprint 和发布 backlog 可以在Bundlor JIRA 上找到。Bundlor 未来的方向由我们的用户决定,因此请花时间对现有问题进行投票,并为 backlog 中目前未涵盖的内容创建新问题。

订阅 Spring 新闻通讯

订阅 Spring 新闻通讯,保持联系

订阅

保持领先

VMware 提供培训和认证,助您加速进步。

了解更多

获取支持

Tanzu Spring 通过一项简单的订阅,为 OpenJDK™、Spring 和 Apache Tomcat® 提供支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看全部