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

在Maven OSGi捆绑包中使用第三方依赖关系,osgi,log4j2,osgi-bundle,maven-bundle-plugin,Osgi,Log4j2,Osgi Bundle,Maven Bundle Plugin,在感觉自己已经掌握了OSGi的使用方法之后,我尝试向我的应用程序添加一个第三方依赖项,特别是log4j2,该应用程序使用ApacheFelix并与maven bundle插件捆绑。不幸的是,我似乎陷入了依赖的地狱 我尝试过使用许多maven捆绑策略,如导入包、嵌入依赖项、wrapImportPackage、嵌入可传递性以及设置特定版本号等等。下面是我的pom对于该插件的外观: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:

在感觉自己已经掌握了OSGi的使用方法之后,我尝试向我的应用程序添加一个第三方依赖项,特别是log4j2,该应用程序使用ApacheFelix并与maven bundle插件捆绑。不幸的是,我似乎陷入了依赖的地狱

我尝试过使用许多maven捆绑策略,如导入包、嵌入依赖项、wrapImportPackage、嵌入可传递性以及设置特定版本号等等。下面是我的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>

4.0.0
父ID
父组ID
x、 x.x
ParentGroupId.ParentId
本模块
捆
本模块
UTF-8
org.osgi
org.osgi.core
6.0.0
假如
${project.groupId}
是
${project.version}
org.apache.logging.log4j
log4japi
2.12.1
org.apache.logging.log4j
log4j型芯
2.12.1
javax.servlet
javax.servlet-api
3.1.0
org.apache.felix
maven捆绑插件
3.5.1
真的
${project.name}
模块激励器
是
格森,
log4japi,
log4j型芯
${project.artifactId}
我觉得我取得的最大进步是使用了上面的pom,我将log4j api和core直接嵌入到包中,但似乎OSGi无法下载和绑定log4j api和core所依赖的编译依赖项。它使用maven成功构建,但当我部署EAR和JAR时,我在运行时(当插件尝试启动时)遇到了这个错误:

原因:org.osgi.framework.BundleException:bundle thisModule[2]中的未解决约束:无法解决2.0:缺少需求[2.0]包;(package=com.conversantmedia.util.concurrent)

将命名log4j需要的特定依赖项的错误。我不想在
embeddedependency
标记中包含每个依赖项及其母亲

我做错了什么

还要注意:由于限制,我在这里的唯一选择是使用ApacheFelix和OSGi


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

  • 嵌入依赖项
    中删除
    log4japi
    log4j核心
    ,并添加
    标签。这样做会产生这种输出,这种输出非常常见,每当我尝试导入时都会发生:
原因:org.osgi.framework.BundleException:bundle thisModule[2]中的未解决约束:无法解决2.0:缺少需求[2.0]包;(&(package=org.apache.logging.log4j)(版本>=2.12.0)(!(版本>=3.0.0))

  • 嵌入依赖项添加*以及添加
    true

原因:org.osgi.framework.BundleException:bundle thisModule[2]中的未解决约束:无法解决2.0:缺少需求[2.0]包;(package=android.dalvik)

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

在大多数情况下,安全的方法是简单地保持maven bundle插件config为空,让它完成自己的任务

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

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

对于ApacheKaraf,默认情况下已经是这样了。如果您使用bndtools或您自己的基于PlainFelix的应用程序集,请查看我的。
它展示了如何在您自己的bundle中使用slf4j api,以及如何在基于karaf和bndtools的应用程序中配置日志系统。

我明白了您关于嵌入库的说法,以及这有什么意义。然而,当您提到在运行时部署日志框架时,您是在说创建一个包含配置并导出其内容的log4j2包吗?然后log4j2框架使用slf4j api来记录,而不局限于该捆绑包?另外,感谢您发布您的OSGi最佳实践。不幸的是,apche karaf目前不是我的选择,但查看您的示例仍然很有帮助。在我的示例中,我使用logback作为日志框架。在karaf之外运行时。请参阅:。在这里您可以看到要设置的捆绑包和框架属性。你也可以对普通的菲利克斯这样做。