OSGI example based on idea+maven (2)

 

foreword

 

In the previous article, I used the idea development tool and integrated the equinox framework to show a simple OSGI multi - bundle demo . It is mentioned in the article that the use of the idea plug-in can realize the automatic generation of bundle metadata (the default method). In fact, in essence, the automatic OSGI plugin of idea uses the bnd tool by default .

 

The most direct difference between bundle jar and ordinary jar package is that bundle jar contains a metadata file MANIFEST.MF . In the process of developing OSGI modules, the most frequent work is to package the jar package developed by yourself into a bundle , or package some third-party jar packages into a bundle , that is, how to generate a metadata file MANIFEST.MF . The most straightforward way is to manually create this file and put it in the jar package.

 

But each time to manually create or modify the metadata file, and then stuff it into the jar package is a very tedious thing. So we need to use development tools. Currently, both Eclipse and Idea have similar plug-ins for generating metadata files, but these plug-ins essentially use the "bnd tool " . Let's first understand this tool.

 

bndtools _

 

The bnd tool was developed by OSGI technical director Peter Kriens . The bnd tool defines some metadata configuration items, which include the configuration items in the OSGI module layer, and also adds some of its own unique configuration items ( Include-Resource , Private-Package ). Note that the essential function of the configuration items defined in bnd is to generate the configuration items in the OSGI metadata configuration file, that is to say, the OSGI framework finally recognizes the metadata configuration file.

 

The bnd tool is essentially a jar package. For example, the version in my computer is bnd-0.0.384.jar . Of course, other versions can also be found online. Through this tool, you can encapsulate a common jar package (whether developed by yourself or a third party) into a bundle recognized by the OSGI framework .

 

For a simple example, now we need to make a third-party jar package: slf4j-api-1.6.5.jar (for printing logs) into a public bundle (in fact, the officially provided jar is already a file with metadata bundle jar , you can delete this file first for testing) . First, you need to create a *.bnd file, the bnd file created here is slf4j-api-1.6.5.bnd , and the content is:

Export-Package: *
Import-Package: org.slf4j.impl;version=1.6.0

Execute the following command:

java -jar bnd-0.0.384.jar build -classpath slf4j-api-1.6.5.jar -output out  slf4j-api-1.6.5.bnd

A slf4j-api-1.6.5.jar will be regenerated in the out directory . This jar has an additional metadata file MANIFEST.MF compared to the previous one. The contents are as follows:

Manifest-Version: 1.0
Export-Package: org.slf4j.helpers;uses:="org.slf4j.spi,org.slf4j",org.
 slf4j;uses:="org.slf4j.helpers,org.slf4j.impl,org.slf4j.spi",org.slf4
 j.spi;uses:="org.slf4j"
Bundle-SymbolicName: slf4j-api-1.6.5
Bundle-Name: slf4j-api-1.6.5
Bundle-Version: 0
Bundle-ManifestVersion: 2
Bnd-LastModified: 1517232511103
Import-Package: org.slf4j.impl;version="1.6.0"
Created-By: 1.8.0_65 (Oracle Corporation)
Tool: Bnd-0.0.384
 

 

In this way, a common jar package (or several) can be encapsulated into a bundle , but this command line method is still very cumbersome (for more information about bnd command parameters, please refer to here http://xjf975999.iteye.com /blog/1322057 ), it is also inconvenient to manage, and is rarely used in a formal environment. In the formal environment, more maven plugins are used for packaging, such as the maven-bundle-plugin plugin introduced next (essentially the packaging of the bnd tool, you don't need to write the command line yourself).

 

maven-bundle-plugin plugin

 

maven-bundle-plugin is a maven plug- in provided in the Apache Felix project. After introducing this plug-in in the pom.xml file of the project and doing some simple configuration, a bundle jar can be automatically generated by executing the maven packaging command . The following shows a simple example, the purpose is to encapsulate the third-party jar servlet-api-2.5.jar into an independent bundle . The complete pom.xml configuration is as follows:

<?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>
 
    <artifactId>servlet</artifactId>
    <groupId>com.sky.bundles</groupId>
    <version>1.0-SNAPSHOT</version>
   
    <packaging>bundle</packaging>
 
    <dependencies>
        <dependency>
            <groupId>org.eclipse.osgi</groupId>
            <artifactId>org.eclipse.osgi</artifactId>
            <version>3.7.1</version>
            <scope>provided</scope>
        </dependency>
 
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>javax.servlet</Bundle-SymbolicName>
                        <Bundle-Name>servlet</Bundle-Name>
                        <Bundle-Description>servlet bundle</Bundle-Description>
                        <Bundle-Vendor>gantianxing</Bundle-Vendor>
                        <Bundle-Version>1.0.0</Bundle-Version>
                        <Embed-Dependency>servlet-api;scope=runtime</Embed-Dependency>
                        <Bundle-Activator>com.sky.servlet.activator.ServletActivator</Bundle-Activator>
                        <Export-Package>javax.servlet.*</Export-Package>
                        <!--<Private-Package>xxxx</Private-Package>-->
                        <Import-Package>org.osgi.framework</Import-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
</project>
 

 

这里重点关注以下几点:

1<packaging>bundle</packaging> 指定最终结果是要生成一个bundle jar

2Export-Package指令,用于指定该bundle需要导出哪些包,可以使用通配符(*)和否定符(!)。这里配置的javax.servlet.*,最终会导出javax.servlet 、javax.servlet.http、javax.servlet.resources这三个包。默认是*,可以自动导出所有包

3、Import-Package指令,用于指定该bundle需要导入哪些包。默认是*,可以自动导入所有用到的包。

4Embed-Dependency,用于jar包合并,可以实现把多个第三方jar包合并成一个公共的bundle,这里只配置了一个jarservlet-api,它会自动识别到dependency中相应的jar包。

5Bundle-Activator,指定自定义的激活器,这个不是必须的。

 

其他配置项跟模块层中介绍的配置项都是一样的,不用一一解读。另外如果不配置configuration节点,所有配置项都是采用默认值。更多关于maven-bundle-plugin插件的介绍可以直接查看官网:http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html

 

可以看到这个pom.xml的配置与普通的配置方式只有些许差别,然后直接运行maven 打包命令,就可以生成bundle jar了。我这里使用的是idea开发工具,运行maven package target目录下会有一个新的jar包生成 servlet-1.0-SNAPSHOT.jar,其内容跟servlet-api-2.5.jar基本相同,只是新增了一个激活器和元数据文件MANIFEST.MF:

Manifest-Version: 1.0
Bnd-LastModified: 1517295026912
Build-Jdk: 1.8.0_65
Built-By: gantianxing
Bundle-Activator: com.sky.servlet.activator.ServletActivator
Bundle-Description: servlet bundle
Bundle-ManifestVersion: 2
Bundle-Name: servlet
Bundle-SymbolicName: javax.servlet
Bundle-Vendor: gantianxing
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Embed-Dependency: servlet-api;scope=runtime
Export-Package: javax.servlet;version="1.0.0",javax.servlet.http;uses:
 ="javax.servlet";version="1.0.0",javax.servlet.resources;version="1.0
 .0"
Import-Package: org.osgi.framework;version="[1.6,2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.5))"
Tool: Bnd-3.5.0.201709291849

 

 

通过这种方式可以把自己写的代码连同一些列的第三方jar包打成一个大的bundle jar,一次性的加载到OSGI框架中,其他bundle导入对应的包即可使用。

 

另外在idea开发工具中完成上述配置后,ctrl+shift+alt+s 可以看到这里自动创建了一个OSGI bundle,配置信息如下:



 

 

如果看过上一篇博客的朋友,应该注意到了 这些配置本来需要我们手动配置的,如果使用maven-bundle-plugin插件这里已经自动完成了。你也可以像上一篇博客中提到,可以把这个bundle放到idea集成的equinox框架中执行。

 

总结

 

前一篇博客中讲到使用idea开发工具的插件可以用于生成元数据配置文件,本次使用maven-bundle-plugin插件生成元数据配置文件。最终我们发现其实两者是想通的,相比而言使用maven-bundle-plugin插件会更方便些,直接跟maven打包命令集成。

 

但他们本质上都是基于bnd工具实现的(其它的元数据生成工具或者插件,基本都是基于bnd实现的),有时候我们也可能需要直接使用bnd命令来制作一个bundle jar。在日常开发中,如果使用的maven来构建项目,还是建议使用maven-bundle-plugin插件。

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326314210&siteId=291194637