使用 gradle 显示第一个 OSGi 构建 - 从 ant 迁移到 Gradle

Posted

技术标签:

【中文标题】使用 gradle 显示第一个 OSGi 构建 - 从 ant 迁移到 Gradle【英文标题】:manifest first OSGi build with gradle - migrating from ant to Gradle 【发布时间】:2016-06-08 09:07:32 【问题描述】:

先有manifest吗 http://wiki.osgi.org/wiki/Tooling_Approaches OSGi 的 gradle 插件?或者用gradle怎么做?

OSGi 容器有一个很大的旧项目,其中许多项目在 MANIFEST.MF 中声明了复杂的关系。构建很长。 现在我们想简化事情并采用 Gradle。但首先不要破坏东西并保持 ant 和 gradle 并行构建一段时间。 但是我看到的是 gradle 建议在 build.gradle 中定义 MANIFEST。 https://docs.gradle.org/current/userguide/osgi_plugin.html 那会做很多复制工作。

更新有近 100 个模块,其中包含模块之间和嵌套 jar 的大量依赖关系信息。 MANIFEST.MF 的平均长度约为 50 行(从 20 到 300 行不等)。 如何捆绑嵌套 jar 是other question。 这个问题是关于使用现有的 MANIFEST.MF 文件。我看到的所有插件都使用bnd,这与manifest first 方法完全相反。

【问题讨论】:

如果您是手动编写清单,那么您可以将它们直接传递给 JAR 任务。我还缺少什么吗? 如何将现有的 MANIFEST.MF 文件传递​​给 jar 任务?我认为现在唯一的方法是将信息从 MANIFEST.MF 复制到 build.gradle jar 部分,这是一项巨大的猴子工作。在 gradle build 开始工作并被接受为主要交付方式之前,这些文件可能会发生变化。 JDK 不需要知道。 jar 命令允许将预定义的清单作为文件提供。快速检查 Gradle 文档,看起来 Jar 任务有一个您可以使用的 manifest 属性。类似Manifest.from(filename) 你卡在 Gradle 上了吗?为什么不使用 Maven。然后你可以使用标准的 maven 目标来创建 osgi 清单等。 因为 Gradle 更好:) ! 【参考方案1】:

Gradle 有一个 OsgiManifest 类,它是一个扩展的 jar 清单:

https://docs.gradle.org/current/javadoc/org/gradle/api/plugins/osgi/OsgiManifest.html

*** 上有一篇帖子显示了类似的用法:

How to add Import-Package instructions for runtime dependencies?

相关的 gradle 块如下所示:

apply plugin: 'java'
apply plugin: 'osgi'

jar 
    baseName = 'awesome'
    manifest 
        name = 'An Awesome Application'
        symbolicName = 'com.example.awesome'
        instruction 'Import-Package', 'org.springframework.orm', '*'
    

如果您有现有的清单并希望使用自己的自定义文件,您可以通过在 jar 闭包中设置清单文件位置来做到这一点:

jar 
    manifest 
        def manif = "$resourcesDir/MANIFEST.MF"
        if (new File(manif).exists()) 
            from file(manif)
        
        else
            name = 'overwrittenSpecialOsgiName'
            instruction 'Private-Package', 'org.mycomp.somepackage'
            instruction 'Bundle-Vendor', 'MyCompany'
            instruction 'Bundle-Description', 'Platform2: Metrics' 
        
    

可以在此处找到 Gradle 清单的文档: https://docs.gradle.org/current/javadoc/org/gradle/api/java/archives/Manifest.html

对于您的“其他问题”:

还有其他用于构建 OSGI 包的 Gradle 插件,在某些情况下,包括来自其他 OSGI 包的依赖项。

例如,Gradle Bundle Plugin,它使用 bnd 工具并允许您指定包含传递依赖,甚至排除不需要的依赖。 举个例子:

jar 
    manifest 
        attributes 'Implementation-Title': 'Bundle Quickstart',     // Will be added to manifest
                     'Import-Package': '*'  // Will be overwritten by the instuctions below
    


bundle 
    includeTransitiveDependencies = true

    instructions << [
        'Bundle-Activator': 'foo.bar.MyBundleActivator',
        'Import-Package': 'foo.*',
        '-sources': true
    ]

    instruction 'Export-Package', '*' // Specify an individual instruction
    instruction '-wab', ''

还有Gradle osgi-run plugin,默认包含传递依赖:

dependencies 
    // all your usual dependencies
    ...

    osgiRuntime( "your:dependency:1.0" ) 
        transitive = false // transitive dependencies not included in OSGi runtime
    

希望这足以让你继续前进。

【讨论】:

这已经是很好的答案(赞成),但它没有解决获取所有依赖项信息的问题,例如模块之间,以及我们拥有的嵌套 jars。 保罗,你最后的评论。这与解决您发布的“其他问题”有关吗?我正在努力清楚地了解您希望提供哪些额外建议。 一旦存在依赖信息,可以使用或不使用嵌套 jar 构建捆绑包,这是其他问题。至少要完成 gradle 构建,编译应该通过,即来自 MANIFEST.MF 文件的所有依赖项都应该对编译器可见。我不是 MANIFEST 中所有可能的依赖声明的专家,至少有包和捆绑依赖。 Paul,我已经为我找到的其他几个 osgi 插件的答案添加了更多信息。但是,我在想(如果我错了,请纠正我)你可能需要使用默认的 OSGI 插件,但是在将 50 多个 OSGI 模块作为依赖项本身添加之后(它们是否在一个公共库中?),那么你是说您需要在每个模块清单中找到信息,以将每个模块清单声明的依赖项显式添加到通用构建类路径中,以便您的构建成功。想法或澄清? 我正在自己研究,尝试通过 osgi 查询找到的所有插件。我还没有尝试过 osgi-run,Gradle Bundle Plugin 使用bnd,wuff 太可怕了,暂时没有更新。在使用新的构建工具开始更改之前,我首先需要从 ant build 中退出并获得相同的构建结果。【参考方案2】:

截至 2016 年 4 月,用于 OSGi 的 Maven 或 Gradle 构建工具中没有清单优先的方法。

虽然对于 Eclipse 插件(也是有效的 OSGi 包)有 maven/tycho 构建,这是 Eclipse Foundation 中的标准,但它对一般的 OSGi 项目并没有真正的帮助。

与Manifest-first相反的是Manifest generation,只有一个工具bnd,最初用于创建manifest,然后发展为完整的bundle jar builder,现在有BndTools Eclipse integration,看起来类似于Maven/Gradle集成管理依赖关系。

我建议将bnd 指令保留在外部标准bnd.bnd 文件中,而不是将其放在构建脚本中。 *.bnd 文件类似于通常的 Java .properties 文件,因此在 Eclipse IDE 中右键单击,打开方式 -> 其他 ... 选择 Properties File Editor 选中“将此编辑器用于..”并选中“将此编辑器用于所有“*.nbd”文件”

对于 Gradle

[Gradle OSGi Plugin] (standard, built-in)(https://docs.gradle.org/current/userguide/osgi_plugin.html) 只提供清单操作,所以GRADLE-1107 "OSGi instruction Include-Resource not working" 是 自 2010 年以来的未决问题 Gradle Bundle Plugin 允许您创建 OSGI 包。它与 Gradle OSGI 插件的主要区别在于,它使用 bnd 工具不仅生成清单,而且生成整个 jar。 osgi-run "Osgi-Run - 一个 Gradle 插件,让使用 OSGi 开发模块化应用程序完全无痛"

对于行家

maven-bundle-plugin 又名Apache Felix Maven Bundle Plugin (BND) 是“Maven first” approach bnd-maven-pluginannounce and 2 plugins comparison

所有基于 bnd 的工具现在都在 collected http://bnd.bndtools.org/chapters/700-tools.html 上

https://github.com/paulvi/OSGiBuildExamples中有一些例子

注意:链接http://wiki.osgi.org/wiki/Tooling_Approaches 已在“不幸的是,OSGi 社区 Wiki 被黑,目前不可用。 " 状态超过一周,而这个问题被打开了。

遗憾的是,@Richard 放弃得太早了,也没有收到一些感谢(因为提到了 maven)

【讨论】:

以上是关于使用 gradle 显示第一个 OSGi 构建 - 从 ant 迁移到 Gradle的主要内容,如果未能解决你的问题,请参考以下文章

Gradle + OSGi Liferay7 模块,包含传递依赖

OSGI.NET 学习笔记--架构篇

如何使用 Apache Karaf/OSGi 构建桌面应用程序?

如何管理 OSGi 构建依赖项?

Gradle教程第一章:1.1Gradle命令行使用

来自 Adobe 的用户体验专家 AEM 之:构建并部署 OSGi bundle