如何在eclipse中基于maven创建osgi的bundle

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在eclipse中基于maven创建osgi的bundle相关的知识,希望对你有一定的参考价值。

一、环境准备
1、下载并解压eclipse

2、下载安装jdk,并配置环境变量
打开系统属性面板(桌面上右键单击“我的电脑”→“属性”),点击高级系统设置,再点击环境变量,在系统变量中新建一个变量,变量名:JAVA_HOME,变量值:C:\Program Files\Java\jdk1.6.0_10——确定。然后编辑path变量,在最前面添加%JAVA_HOME%\bin;即可。
注意:C:\Program Files\Java\jdk1.6.0_10为jdk的具体安装路径。

验证jdk安装及环境变量的配置:
开始——运行中输入cmd进入dos界面
C:\Users\您的电脑用户名>echo %JAVA_HOME%
C:\Users\您的电脑用户名>java –version
信息正确即可。

3、下载maven安装文件,并配置环境变量
下载:网址http://maven.apache.org/download.html,下载apache-maven-3.0-bin.zip。

本地安装: 将安装文件解压到你指定的目录中,如:D:\bin,那么Maven安装目录就是D:\bin\apache-maven-3.0

设置环境变量:
将Maven安装配置到操作系统环境中。
打开系统属性面板(桌面上右键单击“我的电脑”→“属性”),点击高级系统设置,再点击环境变量,在系统变量中新建一个变量,变量名为M2_HOME,变量值为Maven的安装目录D:\bin\apache-maven-3.0。点击确定,接着在系统变量中找到一个名为Path的变量,在变量值的末尾加上%M2_HOME%\bin;,注意多个值之间需要有分号隔开,然后点击确定。至此,环境变量设置完成,

运行如下命令检查Maven的安装情况:
C:\Users\Juven Xu>echo %M2_HOME%
C:\Users\Juven Xu>mvn -v

4、在eclipse中安装maven插件。
如果IDE不是eclipse而是STS,则本步可以跳过,因为STS中已经继承了maven插件。
maven插件的安装是通过eclipse的Help菜单下的Install New Software,然后在打开的窗口中点击Work with右边的“Add”按钮,在弹出的"Add Repository"窗口中再输入Name(m2eclipse),Location中输入maven插件的网址:http://m2eclipse.sonatype.org/sites/m2e
在eclipse中安装maven的附加插件,步骤与上面相同
网址:http://m2eclipse.sonatype.org/sites/m2e-extras

5、安装PAX Cursor插件。该插件装完后在eclipse中run configuration中,选择osgi Framework后会出现Pax Runner页面,在该页面中选择要运行的osgi bundle的pom文件来执行run osgi bundle。
网址:http://www.ops4j.org/pax/eclipse/update/

二、建maven bundle,并将其转化成osgi bundle运行。(以一个简单的helloworld为例)
1、新建项目父bundle。
a) 在eclipe中new——Project——Maven——Maven Project——Next

勾选Create a simple project——next

在New Maven Project窗口中输入父bundle对应的gav(即Group Id、Artifact Id、Version)以及Packaging(注意父bundle一定要选pom,子bundle可以选maven plugin)
点击Finish。
b) 新建项目子bundle。
步骤与新建父bundle相同,不同的是New Maven Project中的各项配置值不同。
Group Id相同,这样父与子才能在同一个group中。
Artifact Id不同(父和任何一个子bundle的该值都必须唯一,因此不同)
Version相同
Packaging不同(子bundle的Packaging可以是maven plugin或jar、war等。建完之后会在pom文件中统一修改为bundle以将maven bundle转化为osgi bundle)
c) 在父bundle的pom文件中配置子bundle
打开父bundle的pom.xml文件,在project对之间,最好在父bundle的pav等配置之下添加所有子bundle与父bundle的相对路径。如
<modules>
<module>../projectname.intf.manageintf</module>
< /modules>
其中projectname.intf.manageintf也是子bundle的Artifact Id

父bundle的整个pom.xml文件如下:
<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>
<groupId>com.companyname.projectname</groupId>
<artifactId>projectname</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>ProjectName</name>

<modules>
<module>../projectname.intf.manageintf</module>
</modules>

< /project>
d) 将子bundle由maven bundle转化成osgi bundle
�0�1 在子bundle的pom.xml文件中添加依赖
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.osgi.core</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
�0�1 在子bundle的pom.xml文件中配置Group Id为org.apache.felix,Artifact Id为maven-bundle-plugin的plugin,并制定bundle的Bundle-Activator。同时修改子bundle的packaging值为bundle。

子bundle的整个pom.xml文件如下:
<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>
<parent>
<artifactId>projectname</artifactId>
<groupId>com.companyname.projectname</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.companyname.projectname</groupId>
<artifactId>projectname.intf.manageintf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>ProjectName Intf ManageIntf</name>

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Activator>com.companyname.projectname.intf.manageintf.activator.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.osgi.core</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
< /project>
注意:pom的build属性中 <extensions>true</extensions>千万不能落!!!
否则eclipse会报错:Project build error:Unknown package:bundle

�0�1 新建Activator类
按照子bundl epom文件指定的Bundle-Activator建立对应的包和Activator类。如本例中应该在子bundle的src/main/jave路径下,新建一个包名为com.companyname.projectname.intf.manageintf.activator的类Activator.java。
该类必须实现BundleActivator接口,该接口所在包名为org.osgi.framework.BundleActivator,接口中有两个方法,分别用于启动和停止该bundle时调用。
public void start(BundleContext arg0) throws Exception;
public void stop(BundleContext arg0) throws Exception;

Activator类具体如下:
package com.companyname.projectname.intf.manageintf.activator;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator

@Override
public void start(BundleContext arg0) throws Exception
System.out.println("start projectname.intf.manageintf bundle!");


@Override
public void stop(BundleContext arg0) throws Exception
System.out.println("stop projectname.intf.manageintf bundle!");



e) Maven install
eclipse——run Configurations——Maven Building——右键new——修改name为projectname_install,在Main页中Base directory下点击“Browse Workspace”,选择父bunde的Artifact Id,如本例为projectname,点击ok。然后在Goals中输入clean install,其本质就是执行maven clean命令和maven install命令。
如果eclipse没有配置java vm的最大内存,那么需要在JRE页面中的VM arguments中输入-Xmx1000m,以免出现堆栈溢出错误。值1000可根据个人电脑内存大小进行配置。
回到Main页面,点击Apply将该配置保存。然后点击Run,就可以执行以上命令将父bundle中配置的所有子bundle都统一执行clean和install命令了。
执行结果如果显示所有bundle都SUCCESS即正确。
[INFO] Reactor Summary:
[INFO]
[INFO] ProjectName ....................................... SUCCESS [0.251s]
[INFO] ProjectName Intf ManageIntf ....................... SUCCESS [2.560s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.826s
[INFO] Finished at: Sun Apr 15 10:13:10 CST 2012
[INFO] Final Memory: 5M/10M
注意:!!!!
第一次执行过程中可能出错,无法找到父bundle等的错误。解决办法为:
1、 先将父bundle的pom文件中的子bundle去掉,即注释
<modules>
<module>../projectname.intf.manageintf</module>
</modules>
然后右键父bundle,选择run as——Maven install,父bundle install成功后
再右键子bundle,选择run as——Maven install,子bundle install成功后
再将父bundle中被注释掉的子bundle信息
<modules>
<module>../projectname.intf.manageintf</module>
</modules>
取消注释,然后在run configurations中执行之前的projectname_install,如果显示父bundle和各个子bundle都install成功,即install成功。
f) osgi bundle run
eclipse——run Configurations——Osgi Framework——右键new——修改name为osgi_run,在Pax Runner页中点击Add Pom,在打开的窗口中选择本地父bundle的路径下pom.xml文件。然后依次选择各个子bundle的pom文件
在Bundle页中取消所有Bundles的选择,在Framwork中选择Equinox 3.5.0 via Pax Runner,点击Apply,保存该run配置,然后点击Run运行osgi bundle
运行后eclipse的Console中显示
在Console中输入ss回车,即可看到所有bundle的运行情况,如
如果要停某个bundle,只需要输入stop bundle对应的id即可。如本例中停子模块的bundle,则只要输入stop 1即可,要启动已停止的bundle则输入start bundle对应的id即可。
同理可以动态卸载和安装bundle
卸载为uninstall bundle对应的id
安装为install file:///要安装的bundle对应的target文件夹下的jar包的完整本地路径,如本例中安装子bundle即为
installfile:///D:\configCode\configurationmanagement\projectname.intf.manageintf\target\projectname.intf.manageintf-0.0.1-SNAPSHOT.jar
新安装的bundle并没有自动启动,需要start 对应的bundle id才行,如本例
至此,maven bundle转化成osig bundle讲解结束!
其他osgi相关的高级配置和spring dm等的使用参加其他文档。
参考技术A 前言:我相信做基于OSGI框架开发的朋友,对于OSGI的基本单元Bundle应该并不陌生,平时的开发中,做得最多事情就是bundle的开发和打包了,打包其实属于蛮重要的一个过程,为什么说他重要呢,其实打包的过程就是一个理清bundle依赖关系的过程

在集成 Maven、Tycho 和 Eclipse 时处理非 OSGi 依赖项

【中文标题】在集成 Maven、Tycho 和 Eclipse 时处理非 OSGi 依赖项【英文标题】:Handling non-OSGi dependencies when integrating Maven, Tycho and Eclipse 【发布时间】:2014-04-14 04:55:49 【问题描述】:

我有一堆基于 Eclipse 的插件,我一直在迁移到 Maven/Tycho。这些插件中的大多数都依赖于我现在通过 Maven 管理的独立库,而不是与.jar 文件混在一起。

我当前设置中最繁琐的部分是由于 Tycho 明显无法处理仅 Maven(即非 OSGi)工件。我目前的设置是这样的:

    在每个 Eclipse 插件的pom.xml 中,我在initialize 阶段向maven-dependency-plugin 发出unpack 目标。这会将我指定的工件解压缩到单独的 target/dependencies 目录中。

    target/dependencies目录作为输出目录添加到build.properties中,以便Tycho在编译时可以将其添加到classpath中:

    source.. = src/main/java/
    output.. = target/classes/
    output.. = target/dependencies/
    

    target/dependencies 目录被添加到META-INF/MANIFEST.MF 中的Bundle-ClassPath 库中。

这些设置允许compile Maven 指令编译插件。从 VCS 导入项目并手动将 target/dependencies 目录指定为 Eclipse 中的类文件夹允许所述 IDE 也编译插件。

不幸的是,这是一个相当麻烦的解决方案,原因如下:

配置maven-dependency-plugin 需要列出所有应解压的工件。一个可以使用unpack-dependencies而不是unpack,但这也会解压所有OSGi依赖项——在每个项目目录中解压一半的Eclipse并不是我的乐趣......

在 Eclipse 中添加 class 文件夹需要运行一次 Maven initialize,以便创建 target/dependencies 目录。

纯 Maven 项目与其在 Eclipse 中依赖的 Tycho 项目之间没有源代码连接。对于从 Maven 项目传播到 Tycho 项目的更改,例如Eclipse 可能会显示一个潜在的编译问题,必须先 mvn install Maven 项目,然后在 Tycho 项目中运行 mvn clean initialize 以删除先前解压缩的依赖项并拉入当前集合。然后你必须刷新 Eclipse 项目并希望 Eclipse 做正确的事情。

同样,从 Tycho 项目中查看依赖项的源代码不会显示主要源文件,而是显示 target/dependencies 中可用的任何内容 - 很可能只是 .class文件。

我认为必须有一个更合理的方法来解决这个问题 - 可以让 Eclipse 和 Maven 项目更紧密地集成。

那么,我错过了什么?此用例的推荐设置是什么?有更好的选择吗?最好是不需要设置一堆 Nexus 和/或 p2 存储库的东西?

【问题讨论】:

【参考方案1】:

您可以尝试带有 Embed-Dependency 的 maven-bundle-plugin。

见http://wiki.eclipse.org/Tycho/How_Tos/Dependency_on_pom-first_artifacts

官方演示效果很好。但是,我仍然无法以这种方式使用我的 jar 文件。

【讨论】:

这是否让 Eclipse 将仅 Maven 依赖项的源代码与其在 Eclipse/Tycho 插件中的消费者代码“连接”起来?因为 that 是我设置中最烦人的部分;如果我破坏了一个界面,直到我 mvn clean initialize 所有相关的第谷项目时我才会注意到... @thkala 如果可行,我认为答案是肯定的。由于eclipse默认会首先在workspace中解析maven依赖。但是,目前我的 Eclipse 不能停止说“生命周期映射“org.sonatype.tycho.m2e.wrapperBundle”不可用。”在这个方法中。【参考方案2】:

似乎我们采用了类似的策略。但是,我使用的是 nexus 混合存储库(同时具有 maven 和 p2)。

    对于解包依赖项,我使用 maven-dependency-plugin 将它们放置在目标/依赖项中(见下文)。 1.1。复制依赖项无需解包即可完成所需的工作。 您的来源和输出与我的大致相同。 2.1。是的,mvn 必须初始化目标/依赖项 我只在 MANIFEST 中包含所需的 jar,因为 1 会检索到许多不必要的 jar。 3.1。我手动选择相关的罐子。 3.2。是的,如果非 Eclipse 管理(maven)项目发生变化(在您的工作区之外),那么您必须运行 mvn build 来更新它们。 3.3。完成这项工作的关键是: 3.3.1 将您的 maven 和 Eclipse 项目部署到(快照)存储库。我使用 http://www.sonatype.org/nexus/ 。因此,当您运行 maven 时,它会查看 nexus 存储库以获取 maven 和 Eclipse 项目的更新。 其他一些可能已经很明显的注释: 4.1。 pom.xml 文件应仅包含非 Eclipse jar 作为依赖项。 (tycho 插件处理所有 Eclipse 依赖项,这些依赖项应该可以在您的(nexus)存储库中找到。) 4.2。将依赖的 jars 添加到 Eclipse 中的运行时(通过编辑 plugin.xml 运行时)

Maven 插件:

        <plugin>
            <!-- Copy non-Ecipse plugins to target/dependency so that may be referenced 
                for runtime use. -->
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.1</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <excludeGroupIds>org.XXX</excludeGroupIds>
                    </configuration>
                </execution>
                <execution>
                    <id>classpath</id>
                    <goals>
                        <goal>build-classpath</goal>
                    </goals>
                    <configuration>
                        <fileSeparator>/</fileSeparator>
                        <prefix>target/dependency</prefix>
                        <outputFile>$project.build.directory/classPath.txt
                        </outputFile>
                    </configuration>
                </execution>
            </executions>
        </plugin>

示例 build.properties

bin.includes = META-INF/,
target/classes/,
plugin.xml,
target/dependency/mongo-java-driver-2.11.3.jar

示例清单(仅 jar 的一个子集):

Bundle-ClassPath: .,
target/classes/,
target/dependency/mongo-java-driver-2.11.3.jar

【讨论】:

【参考方案3】:

官方演示确实运行良好,并展示了嵌入非 OSGI 依赖项的方法,或者换句话说,为其他依赖项创建 OSGI 外观。

方法确实是手动复制依赖项,使它们成为 OSGI 清单的一部分并导出感兴趣的包。

然而,真正的问题是在 Eclipse 中执行依赖插件。

即使使用相应的 M2E 连接器也无法运行,因此会阻止发现和 PDE 类路径解析。

【讨论】:

以上是关于如何在eclipse中基于maven创建osgi的bundle的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Eclipse 了解 maven 存储库中的 OSGI 包(本地 &| 远程)

在 Eclipse 中编译和运行 OSGI 应用程序

如何使用 bndtools 通过 Scala 创建 OSGi 包?

在 Eclipse 中调试 FuseESB 应用程序

Eclipse OSGi 启动配置不显示我的包

在 OSGi 包中添加第三方 Maven 依赖项的最佳方法