osgi - 在 Maven OSGi 包中使用第 3 方依赖项

标签 osgi log4j2 osgi-bundle maven-bundle-plugin

在感觉自己掌握了 OSGi 的使用方式之后,我尝试向使用 apache felix 并与 maven-bundle-plugin 捆绑的应用程序添加第 3 方依赖项(特别是 log4j2)。不幸的是,我似乎陷入了依赖 hell 。

我尝试过使用多种 maven-bundle 策略,例如 Import-Package、Embed-Dependency、wrapImportPackage、Embed-Transitive,以及设置特定版本号(仅举几例)。下面是这个插件的 pom 的样子:

<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>ParentId</artifactId>
    <groupId>ParentGroupId</groupId>
    <version>x.x.x</version>
</parent>

<groupId>ParentGroupId.ParentId</groupId>
<artifactId>thisModule</artifactId>
<packaging>bundle</packaging>

<name>thisModule</name>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>org.osgi.core</artifactId>
        <version>6.0.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>AM</artifactId>
        <version>${project.version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.12.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.12.1</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>3.5.1</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>${project.name}</Bundle-SymbolicName>
                    <Bundle-Activator>moduleActivator</Bundle-Activator>
                    <Embed-Dependency>
                        AM,
                        gson,
                        log4j-api,
                        log4j-core
                    </Embed-Dependency>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
    <finalName>${project.artifactId}</finalName>
</build>

我觉得我取得的最大进展是上面的 pom,我将 log4j api 和核心直接嵌入到 bundle 中,但似乎 OSGi 无法下载和捆绑 log4j 的编译依赖项api和core是依赖的。它使用 maven 成功构建,但是当我部署 EAR 和 JAR 时,我在运行时收到此错误(当插件尝试启动时):

Caused By: org.osgi.framework.BundleException: Unresolved constraint in bundle thisModule [2]: Unable to resolve 2.0: missing requirement [2.0] package; (package=com.conversantmedia.util.concurrent)

将命名 log4j 所需的特定依赖项的错误。我不想做的是将每个依赖项及其母亲包含在 Embed-Dependency 中标签。

我在这里做错了什么?

另请注意:由于限制,我唯一的选择是使用 apache felix 和 OSGi。


下面是我对上述 POM 所做的修改的其他示例及其结果输出:

  • 同时删除 log4j-apilog4j-core来自Embed-Dependency并添加 <wrapImportPackage>;</wrapImportPackage>标签。这样做会产生以下输出,这种输出非常常见,每当我尝试导入时都会发生:

Caused By: org.osgi.framework.BundleException: Unresolved constraint in bundle thisModule [2]: Unable to resolve 2.0: missing requirement [2.0] package; (&(package=org.apache.logging.log4j)(version>=2.12.0)(!(version>=3.0.0)))

  • 将 * 添加到 Embed-Dependency以及添加 <Embed-Transitive>true</Embed-Transitive> :

Caused By: org.osgi.framework.BundleException: Unresolved constraint in bundle thisModule [2]: Unable to resolve 2.0: missing requirement [2.0] package; (package=android.dalvik)

最佳答案

嵌入日志库是一个坏主意。毕竟,您希望在一个中心位置配置日志记录,当每个包都嵌入一个日志记录框架时,这是非常困难的。

在大多数情况下,安全的选择是简单地将 maven-bundle-plugin 配置保留为空并让它做它的事情。

我个人总是使用 slf4j 来登录 OSGi。您只需依赖 slf4j-api。 maven-bundle-plugin 自动创建导入包语句。

然后在运行时,您只需部署一个支持您想要的日志记录 API 的日志记录框架即可。

对于 apache karaf,默认情况下已经是这种情况。如果您使用 bndtools 或您自己的基于普通 felix 的应用程序组件,请查看我的 osgi best practices example 。 它展示了如何在您自己的 bundle 中使用 slf4j-api,以及如何在基于 karaf 和 bndtools 的应用程序中配置日志系统。

关于osgi - 在 Maven OSGi 包中使用第 3 方依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58884266/

相关文章:

java - Class.getName() 的静态调用

java - 在 OSGI 4.2 包中使用 JAX-WS 时出现 NoClassDefFoundError

eclipse - Tycho和Eclipse:如何在开发时在Eclipse中将OSGI依赖项解析为我自己的 bundle ,而无需在IDE中打开所有 bundle

Java - 如何配置 log4j2.xml

java - log4j2 RollingFile 附加程序

java - 在OSGI中导入内部包

java - R3 导入不能包含指令

java - 使用 log4j 配置进行日志记录不起作用

java - eclipse4 RCP 片段 "Unable to load class from bundle"

maven - 如何在Karaf中安装Apache Hadoop客户端