Maven + OSGi 包构建复杂化
Maven + OSGi bundle build complication
我目前正在开发一个基于 OSGi 的应用程序(使用 Felix)。在这个项目中,有依赖于其他包的包。过去我们使用 Ant 脚本来编译和构建所有东西,现在我们想把它 mavenize,但是这个任务一点也不简单。
这是我的文件夹结构:
+-shared
-- pom.xml
-- someProject
--- pom.xml
-- org.apache.felix
--- pom.xml
-- org.apache.activemq
--- pom.xml
-- org.apache.log4j
--- pom.xml
-- org.snake.yaml
--- pom.xml
-- ...
显然,根 POM 应该在这里构建所有内容,各个 POM 简单地描述了包。我在每个包中也有 MANIFEST.MF
个文件(不是自动生成的)。我必须说我们不想从公共存储库中获取内容,而是希望拥有我们自己的本地存储库。
现在,我不会使用任何像maven-bundle-plugin and I am trying to do this myself. However I get a lot of errors, which are mostly package does not exist
errors. Therefore I suspect I am doing something wrong. After looking around in the forum, I noticed that a lot of people have been using the maven-bundle-plugin这样的插件,所以我也开始考虑这样做。然而,官方网站只能帮助我到某个点,然后我就卡住了。
长话短说,我想要一个至少可以编译的功能性 pom.xml
。它也可能会自动生成 MANIFEST.MF
,这很好,但是,我不确定我应该如何进行。
到目前为止,我想出了这个 pom.xml
(someProject1
):
<?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>
<parent>
<groupId>shared</groupId>
<artifactId>shared.master</artifactId>
<relativePath>../pom.xml</relativePath>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>shared</groupId>
<artifactId>shared.cmd.felix</artifactId>
<name>shared.cmd.felix</name>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>shared</groupId>
<artifactId>org.apache.felix</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../org.apache.felix/felix.jar</systemPath>
</dependency>
<dependency>
<groupId>shared</groupId>
<artifactId>org.apache.log4j</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../org.apache.log4j/log4j-1.2.17.jar</systemPath>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Export-Package>shared.cmd.felix</Export-Package>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
和 org.apache.felix
的 pom.xml
:
<?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>
<parent>
<groupId>shared</groupId>
<artifactId>shared.master</artifactId>
<relativePath>../pom.xml</relativePath>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>shared</groupId>
<artifactId>org.apache.felix</artifactId>
<name>org.apache.felix</name>
<version>1.0.0</version>
</project>
我的 MANIFEST.MF
是:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Shared Felix Console Extension
Bundle-SymbolicName: shared.cmd.felix
Bundle-Version: 1.0.0
Fragment-Host: shared.mw;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ClassPath: .,
bundle/system/org.apache.felix.gogo.runtime-0.10.0.jar
Export-Package: shared.cmd.ext
Import-Package: shared,
shared.cmd,
shared.comp,
shared.mw,
shared.sched,
shared.service,
org.apache.felix.service.command,
org.apache.log4j,
org.osgi.framework
Require-Bundle: org.apache.felix;bundle-version="1.0.0",
org.apache.activemq
但是,我收到如下错误:
[ERROR] /shared/shared.cmd.felix/src/shared/cmd/ext/ListScheduledTasks.java:[11,40] package org.apache.felix.service.command does not exist
[ERROR] /shared/shared.cmd.felix/src/shared/cmd/ext/ListScheduledTasks.java:[15,19] cannot find symbol
现在,如果我想把它变成可以利用maven-bundle-plugin的状态,那怎么可能呢?我想出了这个,但不知道这是否符合我上面的那个:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>shared</groupId>
<artifactId>shared.cmd.felix</artifactId>
<packaging>bundle</packaging>
<name>shared.cmd.felix</name>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.felix</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.log4j</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${pom.groupId}</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>--WHAT TO PUT HERE?--</Export-Package>
<Private-Package>--WHAT TO PUT HERE?-</Private-Package>
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
<Bundle-Activator>--WHAT TO PUT HERE?-</Bundle-Activator>
<Export-Service>--WHAT TO PUT HERE?-</Export-Service>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
更重要的是,我需要在那里插入所有内容吗?我不能跳过其中的一些,例如 Export-Service
吗?我在上面输入的本地路径发生了什么,为什么插件没有这些?它会自动找到它们还是?
有人可以帮我解决这个问题吗?我将不胜感激任何贡献。
提前致谢。
手工完成所有的包导入和导出是非常困难的。即使您实现了它,代码也会非常脆弱,因为您必须适应所有重构。如果您还想手动执行 package uses 子句,那您就完蛋了。
我用过maven-bundle-plugin 和bnd-maven-plugin。两者都很好用。如果您的项目设计得很好,那么您根本不需要太多配置。
tasklist-ds example 展示了如何将其应用于完整的束树。
我配置了导入的 maven-bundle-plugin only in the parent pom. The actual config is done in bnd.bnd 个文件。
您可以先将它们留空。然后查看生成的包。然后您可以调整导入和导出,但尽量将这些特殊配置保持在最低限度。
假设您正在使用 bnd-maven-plugin
,您 根本不需要在 bnd.bnd
文件中添加依赖项。您只需以标准 Maven 方式将它们添加到 pom.xml
中。为此,请遵循任何标准 Maven 教程。
如果您从 Java 编译器收到关于未知包的错误,那么这只是意味着您错过了 pom.xml.
中的构建依赖项
考虑到您的出发点,我认为最简单的方法是将您的项目构建为普通 Java 项目...完全不用担心 OSGi!这将确保您拥有所需的所有编译时依赖项,如果遇到困难,您可以再次使用任何标准 Maven 教程。
一旦你有一个实际构建的普通 Java 项目,那么你可以添加 bnd-maven-plugin
以便将你的 JAR 变成包。
完全披露:我是 bnd-maven-plugin
.
的原作者
我目前正在开发一个基于 OSGi 的应用程序(使用 Felix)。在这个项目中,有依赖于其他包的包。过去我们使用 Ant 脚本来编译和构建所有东西,现在我们想把它 mavenize,但是这个任务一点也不简单。
这是我的文件夹结构:
+-shared
-- pom.xml
-- someProject
--- pom.xml
-- org.apache.felix
--- pom.xml
-- org.apache.activemq
--- pom.xml
-- org.apache.log4j
--- pom.xml
-- org.snake.yaml
--- pom.xml
-- ...
显然,根 POM 应该在这里构建所有内容,各个 POM 简单地描述了包。我在每个包中也有 MANIFEST.MF
个文件(不是自动生成的)。我必须说我们不想从公共存储库中获取内容,而是希望拥有我们自己的本地存储库。
现在,我不会使用任何像maven-bundle-plugin and I am trying to do this myself. However I get a lot of errors, which are mostly package does not exist
errors. Therefore I suspect I am doing something wrong. After looking around in the forum, I noticed that a lot of people have been using the maven-bundle-plugin这样的插件,所以我也开始考虑这样做。然而,官方网站只能帮助我到某个点,然后我就卡住了。
长话短说,我想要一个至少可以编译的功能性 pom.xml
。它也可能会自动生成 MANIFEST.MF
,这很好,但是,我不确定我应该如何进行。
到目前为止,我想出了这个 pom.xml
(someProject1
):
<?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>
<parent>
<groupId>shared</groupId>
<artifactId>shared.master</artifactId>
<relativePath>../pom.xml</relativePath>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>shared</groupId>
<artifactId>shared.cmd.felix</artifactId>
<name>shared.cmd.felix</name>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>shared</groupId>
<artifactId>org.apache.felix</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../org.apache.felix/felix.jar</systemPath>
</dependency>
<dependency>
<groupId>shared</groupId>
<artifactId>org.apache.log4j</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../org.apache.log4j/log4j-1.2.17.jar</systemPath>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Bundle-ClassPath>.</Bundle-ClassPath>
<Export-Package>shared.cmd.felix</Export-Package>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
和 org.apache.felix
的 pom.xml
:
<?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>
<parent>
<groupId>shared</groupId>
<artifactId>shared.master</artifactId>
<relativePath>../pom.xml</relativePath>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>shared</groupId>
<artifactId>org.apache.felix</artifactId>
<name>org.apache.felix</name>
<version>1.0.0</version>
</project>
我的 MANIFEST.MF
是:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Shared Felix Console Extension
Bundle-SymbolicName: shared.cmd.felix
Bundle-Version: 1.0.0
Fragment-Host: shared.mw;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ClassPath: .,
bundle/system/org.apache.felix.gogo.runtime-0.10.0.jar
Export-Package: shared.cmd.ext
Import-Package: shared,
shared.cmd,
shared.comp,
shared.mw,
shared.sched,
shared.service,
org.apache.felix.service.command,
org.apache.log4j,
org.osgi.framework
Require-Bundle: org.apache.felix;bundle-version="1.0.0",
org.apache.activemq
但是,我收到如下错误:
[ERROR] /shared/shared.cmd.felix/src/shared/cmd/ext/ListScheduledTasks.java:[11,40] package org.apache.felix.service.command does not exist
[ERROR] /shared/shared.cmd.felix/src/shared/cmd/ext/ListScheduledTasks.java:[15,19] cannot find symbol
现在,如果我想把它变成可以利用maven-bundle-plugin的状态,那怎么可能呢?我想出了这个,但不知道这是否符合我上面的那个:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>shared</groupId>
<artifactId>shared.cmd.felix</artifactId>
<packaging>bundle</packaging>
<name>shared.cmd.felix</name>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.felix</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.apache.log4j</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${pom.groupId}</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>--WHAT TO PUT HERE?--</Export-Package>
<Private-Package>--WHAT TO PUT HERE?-</Private-Package>
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
<Bundle-Activator>--WHAT TO PUT HERE?-</Bundle-Activator>
<Export-Service>--WHAT TO PUT HERE?-</Export-Service>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
更重要的是,我需要在那里插入所有内容吗?我不能跳过其中的一些,例如 Export-Service
吗?我在上面输入的本地路径发生了什么,为什么插件没有这些?它会自动找到它们还是?
有人可以帮我解决这个问题吗?我将不胜感激任何贡献。
提前致谢。
手工完成所有的包导入和导出是非常困难的。即使您实现了它,代码也会非常脆弱,因为您必须适应所有重构。如果您还想手动执行 package uses 子句,那您就完蛋了。
我用过maven-bundle-plugin 和bnd-maven-plugin。两者都很好用。如果您的项目设计得很好,那么您根本不需要太多配置。
tasklist-ds example 展示了如何将其应用于完整的束树。
我配置了导入的 maven-bundle-plugin only in the parent pom. The actual config is done in bnd.bnd 个文件。
您可以先将它们留空。然后查看生成的包。然后您可以调整导入和导出,但尽量将这些特殊配置保持在最低限度。
假设您正在使用 bnd-maven-plugin
,您 根本不需要在 bnd.bnd
文件中添加依赖项。您只需以标准 Maven 方式将它们添加到 pom.xml
中。为此,请遵循任何标准 Maven 教程。
如果您从 Java 编译器收到关于未知包的错误,那么这只是意味着您错过了 pom.xml.
中的构建依赖项考虑到您的出发点,我认为最简单的方法是将您的项目构建为普通 Java 项目...完全不用担心 OSGi!这将确保您拥有所需的所有编译时依赖项,如果遇到困难,您可以再次使用任何标准 Maven 教程。
一旦你有一个实际构建的普通 Java 项目,那么你可以添加 bnd-maven-plugin
以便将你的 JAR 变成包。
完全披露:我是 bnd-maven-plugin
.