登录
  • 欢迎访问悠扬的技术博客,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站😉

玩转OSGI-ApacheFelix(三)MAVEN

Apache Felix 悠扬 797次浏览 已收录

玩转OSGI-ApacheFelix(三)MAVEN玩转OSGI-ApacheFelix(三)MAVEN

1.前言

      本章内容接第二篇 玩转OSGI-ApacheFelix(二)IDEA,注意介绍如何使用maven插件进行项目打包配置,后面内容可能会进行更新,根据目前掌握资料进行第一步记录汇总。

2.maven插件介绍

     你可能会用到以下插件来实现你的需求,但是最重要的莫过于maven-bundle-plugin,这个插件用于OSGI配置打包,生成manifest文件,也就是配置元数据,进行打包配置描述,其他插件在java开发中应该或多或少都接触过,本章内容主要对maven-bundle-plugin进行说明

  1. maven-dependency-plugin
  2. maven-jar-plugin
  3. maven-bundle-plugin
  4. maven-assembly-plugin
  5. spring-boot-maven-plugin

3.maven-bundle-plugin

        接第二章内容中的felix-client内容,给出一个示例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">
    <parent>
        <artifactId>felix-demo</artifactId>
        <groupId>com.nxhz.felix</groupId>
        <version>1.0.4</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>felix-client</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.nxhz.felix</groupId>
            <artifactId>felix-server</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <outputDirectory>${project.build.directory}/libs/</outputDirectory>
                    <overWriteReleases>false</overWriteReleases>
                    <overWriteSnapshots>false</overWriteSnapshots>
                    <overWriteIfNewer>true</overWriteIfNewer>
                    <excludes>**/*.zip</excludes>
                    <includes>**/*.jar</includes>
                    <includeScope>compile</includeScope>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.2</version>
                <configuration>
                    <excludes>classes/*.properties</excludes>
                    <archive>
                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>3.5.0</version>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <id>bundle-manifest</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>manifest</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <unpackBundle>false</unpackBundle>
                    <supportedProjectTypes>
                        <supportedProjectType>jar</supportedProjectType>
                        <supportedProjectType>bundle</supportedProjectType>
                        <supportedProjectType>war</supportedProjectType>
                    </supportedProjectTypes>
                    <instructions>
                        <Bundle-Name>${project.artifactId}</Bundle-Name>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-ClassPath>.,classes,{maven-dependencies}</Bundle-ClassPath>
                        <Bundle-Vendor>Morpheus</Bundle-Vendor>
                        <Export-Package>!*</Export-Package>
                        <Embed-Directory>libs</Embed-Directory>
                        <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
                        <Embed-Transitive>true</Embed-Transitive>
                       <!-- <Import-Library>org.springframework.spring;version="[5.0, 5.2.8.RELEASE)"</Import-Library>-->
                        <Export-Package>com.nxhz.felix</Export-Package>
                        <Import-Package>
                            org.osgi.framework,com.nxhz.felix.server;version="${project.version}"
                        </Import-Package>
                        <Bundle-Activator>
                            com.nxhz.felix.client.ClientBundleActivator
                        </Bundle-Activator>
                       <!-- <Web-ContextPath>/client</Web-ContextPath>
                        <MaxDataStorageSize>104857600</MaxDataStorageSize>-->
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

     可能你看到的大部分资料或者博客都给出一个简单示例,整个人都有点懵,这玩意我弄过去配置上,为啥不能用,这里可能最主要的影响是OSGI包开发规则,不论插件怎么用,需要你先系统学习一下OSGI规范,根据规范进行插件配置,说白了,这个插件是根据OSGI规范进行配置,生成你需要的manifest文件打包到jar包中。下面介绍一下我搜集到插件相关的参数配置说明。

3.1 参数说明

属性 属性描述
Bundle-Activator Bundle 的 Activator 类名
Bundle-Category Bundle 的分类属性描述
Bundle-Classpath Bundle 的 Classpath
Bundle-Copyright Bundle 的版权
Bundle-Description Bundle 的描述信息
Bundle-DocURL Bundle 的文档 URL 地址
Bundle-Localization Bundle 的国际化文件
Bundle-ManifestVersion 定义 Bundle 所遵循的规范的版本, OSGI R3 对应的值为1, OSGI R4 对应的值为2
Bundle-Name Bundle的有意义的名称
Bundle-NativeCode Bundle 所引用的 Native Code 的地址
bundle-RequiredExecutionEnvironment Bundle 运行所需要的环境,如可指定为需要 OSGI R3、Java1.4、Java1.3 等
Bundle-SymbolicName Bundle 的唯一标识名,可采用类似 java package 名的机制来保证唯一性
Bundle-Version Bundle 的版本
Dynamiclmport-Package Bundle 动态引用的 package
Export-Package Bundle对外暴露的 package
Fragment-Host Fragment 类型 Bundle 所属的 Bundle 名
Import-Package Bundle 引用的 package
Require-Bundle Bundle 所需要引用的其他的 Bundle

3.2 Bundle-SymbolicName

Bundle-SymbolicName(符号名称) 是唯一必须指定的。通过 bundle 的符号名称和版本号可以在框架中惟一的确定一个 bundle。也就是说,如果一个 bundle 和另外一个 bundle 有着同样的符号名称和版本号,那么这两个 bundle 就是等价的。

Bundle-Name 是给用户读的,而 Bundle-Symbolicname 是给 OSGi 框架读的,让 OSGi 框架能够唯一标识一个 bundle。

示例:

Bundle-SymbolicName: com.edu.osgi.hellowrod

3.3 Bundle-Version

格式:主版本号(Major) + 副版本号(Minor) + 微版本号(Micro) + 限定符串(Qualifier)

bundle-version: 1.0.0.bate1
  • 默认值为:0.0.0
  • 主版本号、副版本号、微版本号必须是数字
  • 限定字符串可以为空,默认为空
  • 版本号是可以进行比较的,比较是根据主版本号、小版本号、微版本号的顺序进行比较。最后是字符串的限定符比较。eg:1.0.0.2016213 > 1.0.0

3.4 Export-Package

标准的 jar 文件默认公开一切内容,而 bundles 默认不公开任何内容 OSGi 通过 Export-Package 公开内容

  • 可以导出多个包,多个用逗号隔开
  • 可以给导出包增加任何属性,以区分导出包
  • 导出的包 version 默认为 0.0.0
    Export-Package: com.edu.api
    Export-Package: com.edu.api;version="1.0.0"
    Export-Package: com.edu.api,com.edu.util;version="1.0.0"
    
  • 当导出一个包的时候,默认导出该包的所有类、接口。可以设置过滤条件:include 包含;exclude 排除
    Export-Package: com.edu.api;include:="*Service"
    Export-Package: com.edu.api;exclude:="*Impl"
    

3.5 Import-Package

OSGi 要求 bundle 显示声明对外部代码的依赖:

  • 不能导入 java.*
  • 导入一个包,不会导入它的子包
  • 通过增加属性导入特定的包
    Import-Package: com.edu.api
    Import-Package: com.edu.api;version="1.0.0"
    
  • Import-Package 版本过滤:
    语法 含义
    [min,max) min<=x<max
    [min,max] min<=x<=max
    (min,max] min<x<=max
    (min,max) min<x<max
    min min<=x
    [1.0.0,1.0.0] 精确指定一个版本
    Import-Package: com.edu.api;version="[1.0.0,2.0.0)"
    Import-Package: com.edu.api;version="1.0.0"
    
  • Import-Package 属性过滤:

    Import-Package: com.edu.api;type=”apache”

    默认情况下 bundle2 虽然没有声明自定义属性 type,但在默认情况下这并不会产生匹配冲突。如果要改变这种情况,可以使用 mandatory 附加参数,强制要求必须存在扩展属性オ能成功匹配。

    # bundle1
    Import-Package: com.edu.api;type="1";mandatory:="type"
    # bundle2
    Export-Package: com.edu.api
    Export-Package: com.edu.api;type="1"
    

    注意: type 是属性;mandatory 是 OSGi 的指令,指令前必须加 “:”

  • Import-Package 可选导入:

    在大多数情况下,导入某个 Package,就说明当前这个 bundle 的正常运行是必须依赖导入的 Package 的。但还有另外一些场景导入某个 Package 是为了实现一些不影响 Bundle 正常运行的附加功能,比如 Apache thrift 里面会用到 httpclient。但是只是在特殊情況下才会用到,此时就不需要强行依赖 httpclient 了。

      # resolution 可选值 mandatory(默认) 和 optional
      Import-Package: com.edu.api;resolution:="optional"
    

3.6 DynamicImport-Package

定义需要动态导入的包。这部分定义没有在 bundle 解析过程中使用,而是在运行时动态解析并加载共享包。

动态导入和可选导入实现的功能有些类似,它们的共同特征是在 bundle 解析期间即使找不到要导入的依赖,也不会导致解析失败。它们的区别是,动态导入每次加载包中的类都会尝试去查找动态导入包,而可选导入包只有在 bundle 解析时才进行连接尝试

DynamicImport-Package: *
DynamicImport-Package: com.edu.*;type=1

不推荐使用,尽量用 Import-Package。

3.7 Bundle-Classpath

Bundle-Classpath 标记有默认值 “.”,它代表该 bundle 的根目录,或者说代表该 Bundle 的 JAR 文件

  • 可以设置多个,多个用逗号隔开
  • 一旦定义了 Bundle-Classpath 就需要显示加入 “.”
  • 按照声明的顺序搜索 bundle 类路径条目

Bundle-Classpath: .,lib/xxx.jar

一般用于非 bundle 包的引用,不推荐使用,违反了 bundle 的使用原则。

4.项目下载

点击下载项目


版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明玩转OSGI-ApacheFelix(三)MAVEN
喜欢 (0)
支付宝[]
分享 (0)
悠扬
关于作者:
10年以上工作经验:6年以上微服务架构设计搭建经验。 曾任岗位:项目经理、架构师。 擅长领域:大数据、数据库,架构设计,资源优化。 获得业绩: 1.实用新型发明专利1个,修改Apache Sharding源码设计实现分库分表程序增强方案。 2.开源项目一个:https://gitee.com/zsiyang/ruoyi-vue-atomikos (加入开源生态圈)。 3.个人技术博客地址:https://www.nxhz1688.com