Log4j2 api在OSGi环境中找不到Log4j2核心

我正在尝试使用log4j2 OSGi包,但似乎log4j2 api在OSGi环境中找不到log4j2核心。 我不断得到以下exception:

ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console 

我发现在很少的地方讨论了同样的例外,但我仍然无法弄清楚这个问题。 Isuspect我遇到了这个问题,因为log4j2 api无法在log4j2核心的META-INF目录中找到log4j-provider.properties。 有什么线索为什么我得到这个例外,我该如何纠正这个问题? (如果有人有正确的pom文件添加log4j依赖项和捆绑请与我分享)

这些是我使用的依赖项

   org.apache.logging.log4j log4j-api 2.2   org.apache.logging.log4j log4j-core 2.2  

我使用apache felix作为bundle插件。 发生此错误的原因是log4j2-core的META-INF内部的资源特别是log4j-providoer.properties文件对log4j api不可见。

谢谢!

当启动Activator并开始搜索日志插件时,log4j-core包会注册一个bundle监听器,如果找到了什么,它会执行类似于通常的Logger初始化的一系列操作(不是真正惯用的OSGi东西,我不确定它工作,但它似乎至少设置Log4jContextSelectorLoggerContextFactory ),只是为了确保它,你安装启动log4j核心包并validation没有改变?

更新:

我做了一些测试,发现了log4j2 OSGi问题的可接受解决方案/解决方法。 但正如其他人推荐的那样,或者我会使用slf4j,pax-logging或简单的OSGi日志服务(更简单的一堆)。

@Grant,你需要修复两件事:

1.正如您所描述的那样,“log4j2无法找到日志记录实现”错误是由于log4j2-api包无法找到log4j-provider.properties文件 导致的, 并且在修复之后, log4j2-api不能找到log4j2-core类(它是一个不同的bundle,而log4j2-api没有特定的Import-Package:对于那些类)。

解决方法是使用META-INF中的.properties文件和强制动态导入的清单为log4j2-api (我称之为log4j-api-config.jar)创建一个小片段包:

  Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Log4j API configurator Bundle-SymbolicName: org.apache.logging.log4j.apiconf Bundle-Version: 1.0.0 Bundle-Vendor: None Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.2 Fragment-Host: org.apache.logging.log4j.api DynamicImport-Package: * 

我在这里导入*,你可以改进它添加log4j2-api所需的log4j2-core软件包所需的子集。

有了这个,这个错误就会消失,但是log4j会注意到你没有提供log4j2配置文件,接下来要修复(只有在这种情况下你才关心)。

2.此时Felix将显示以下内容:

 log4j2.xml not found by org.apache.logging.log4j.core ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. 

我想你可能想要添加自己的log4j2.xml而不会弄乱原来的log4j2-core.jar 。 您可以创建另一个片段包,这次由log4j2-core托管,只有root4中的log4j2.xml配置文件和一个简单的清单:

 Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Log4j Core configurator Bundle-SymbolicName: org.apache.logging.log4j.coreconf Bundle-Version: 1.0.0 Bundle-Vendor: None Bundle-RequiredExecutionEnvironment: OSGi/Minimum-1.2 Fragment-Host: org.apache.logging.log4j.core 

我在测试期间使用了这个简单的log4j2.xml配置:

              

有了这个,您将不再需要下面描述的那种“桥接”包,并且您只需要一个简单的Import-Package: org.apache.logging.log4j来使用您的包中的log4j。

更新2:

重要的是要注意这两个片段不是原始包的依赖关系(不需要修改log4j jar或甚至你的包来添加导入/导出),因此原始包和你自己的自定义包将保持不变。 此外,它们也不依赖于原始包,它们只是带有清单和附加文本文件的基本jar存档,没有代码,不需要Import-Package或Export-Package。

您只需在安装主机软件包后安装每个片段。

我从空jar手动创建了两个片段,并在存档中复制了属性文件,并使用文本编辑器修改了MANIFEST.MF,你可以用这个pom.xml创建它们,记得复制log4j-provider.properties pom.xml所在的位置。

对于log4j2-api片段:

  4.0.0 my.group log4j2-api-config 1.0 log4j2-api-config bundle  1.7       org.apache.felix maven-bundle-plugin 2.0.0 true   org.apache.logging.log4j.apiconf Log4j API Configurator 1.0.0 org.apache.logging.log4j.api  *;resolution:=optional        .  log4j-provider.properties  META-INF     

在适当的位置修改此pom(包含文件,包名称)以使用log4j2-core配置生成另一个log4j2-core

Log4j不适合OSGi环境。 幸运的是,替换pax-logging有一个很好的下降。 在你的包中你使用log4j api或任何其他支持的apis(我更喜欢slf4j-api)。 然后将pax日志记录部署到OSGi框架和捆绑包。 您可以使用标准log4j配置来配置pax日志记录。 所以它很容易使用。 如果你想要一个非常简单的开始,你可以简单地安装apache karaf并将你的捆绑包部署到它。 Karaf已经包含完全设置的pax日志记录。

尝试更改jar文件的名称,不包含核心词(例如:log4j-zore),然后重试

您需要通过添加以下依赖项在META-INF/MANIFEST.MF为您的bundle指定OSGI相关依赖项:

Require-Bundle: org.apache.logging.log4j.core;org.apache.logging.log4j.api

对我来说,这个错误解决了:

  • 确保在调用logger之前实际激活了log4j-api包 – 而不仅仅是已解决。 我通过将其设置为低启动级别的自动启动来完成此操作。
  • 让log4j-api导入log4j-core的类(如@uraime所述),以确保它找到log4j-core。 最干净的方法是使用片段。 您也可以将其添加到清单中,而不是动态导入:

    Require-Bundle:org.apache.logging.log4j.core

我还使用log4j-core的片段让它找到我的log4j2.xml配置文件,但是当不使用这个片段时,log4j将显示不同的错误消息。

另外我发现log4j-core bundle不需要激活(仅解析),但请注意,这确实意味着Activator无法找到自定义log4j2插件。