在Maven OSGi捆绑包中使用第三方依赖

时间:2019-11-15 20:30:42

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

感觉像我掌握了OSGi的使用方式后,我尝试着向我的应用程序中添加第三方依赖项,特别是log4j2,该应用程序使用apache felix并与maven-bundle-plugin捆绑在一起。不幸的是,似乎我陷入了依赖地狱。

我尝试了使用许多Maven捆绑策略,例如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和核心直接嵌入到捆绑包中,但是似乎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-api中同时删除log4j-coreEmbed-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)

1 个答案:

答案 0 :(得分:2)

嵌入日志记录库不是一个好主意。毕竟,您想在一个中央位置配置日志记录,这在每个捆绑软件嵌入日志记录框架时非常困难。

在大多数情况下,安全的押注是简单地将maven-bundle-plugin配置保留为空,并让其执行操作。

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

然后,在运行时,您只需部署一个支持所需日志API的日志框架。

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