感觉像我掌握了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-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)
答案 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的应用程序中配置日志系统。