【问题标题】:Log4j2 api cannot find Log4j2 core in OSGi environmentLog4j2 api 在 OSGi 环境中找不到 Log4j2 核心
【发布时间】:2015-05-05 06:41:00
【问题描述】:

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

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

我在几个地方发现了相同的异常,但我仍然无法弄清楚这个问题。怀疑我遇到了这个问题,因为 log4j2 api 在 log4j2 核心的 META-INF 目录中找不到 log4j-provider.properties。 是否有任何线索为什么我会收到此异常以及如何纠正该问题? (如果有人有正确的 pom 文件来添加 log4j 依赖项和捆绑,请与我分享)

这些是我用过的依赖

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.2</version>
    </dependency>

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

谢谢!

【问题讨论】:

  • 你加载 log4j-core 包吗?你如何管理你的依赖关系?使用 Maven?
  • 我在依赖项中添加了 log4j2 核心和 api。
  • 您能指定您使用的是哪个框架吗?该属性文件无法从另一个捆绑上下文访问,需要一种从 -core 加载它的机制,请参阅我的暂定答案。
  • 我使用的是 Felix,OSGi 环境基于 Eclipse Equinox。
  • 实际上,如果我们在纯 Eclipse Equinox 环境中使用 log4j2 OSGi 包,它们可以正常工作。我收到此异常是因为我使用的应用程序具有 Equinox 的自定义版本。因此请注意,它们在 OSGi 环境中正常工作的 log4j2 OSGi 最新捆绑包没有任何问题。

标签: java logging log4j osgi log4j2


【解决方案1】:

log4j-core 包在 Activator 启动并开始搜索日志插件时注册一个包侦听器,如果找到某些东西,它会执行一系列操作,类似于通常的 Logger 初始化(不是真正惯用的 OSGi 东西,我是不确定它是否有效,但它似乎至少设置了Log4jContextSelectorLoggerContextFactory),为了确定这一点,您是否安装了 启动 log4j-core 包并验证没有任何变化?

更新:

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

@Grant,你有 2 个不同的事情需要修复:

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

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

    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 托管,根目录中只有一个 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 配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

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

更新 2:

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

您只需要在安装了它们的主机包后安装每个片段。

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

对于log4j2-api 片段:

<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>

    <groupId>my.group</groupId>
    <artifactId>log4j2-api-config</artifactId>
    <version>1.0</version>
    <name>log4j2-api-config</name>
    <packaging>bundle</packaging>
    <properties>
        <java-version>1.7</java-version>
    </properties>

    <dependencies>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.0.0</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>org.apache.logging.log4j.apiconf</Bundle-SymbolicName>
                        <Bundle-Name>Log4j API Configurator</Bundle-Name>
                        <Bundle-Version>1.0.0</Bundle-Version>
                        <Fragment-Host>org.apache.logging.log4j.api</Fragment-Host>
                        <DynamicImport-Package>
                            *;resolution:=optional
                        </DynamicImport-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>.</directory>
                <includes>
                    <include>log4j-provider.properties</include>
                </includes>
                <targetPath>META-INF</targetPath>
            </resource>
        </resources>
    </build>
</project>

在适当的地方修改这个 pom(包含的文件、包名称)以生成另一个带有 log4j2-core 配置的 pom。

【讨论】:

  • 我正在使用 Felix,在 OSGi 控制台中我可以看到所有 log4j-api 和 log4j-core 处于活动状态,但是我收到了上述错误。如果我用 api 和 core 的依赖项创建一个单独的包并导出 org.apache.logging.* 包,并且还需要将 log4j-provider.properties 文件复制到该包的 META-INF 目录中,这工作正常,但是我想直接使用 log4j2 OSGi 包。
  • 可以分享一下你用过的pom.xml吗?我们是否需要将此片段添加为我们使用 log4j2 的依赖项?
  • 添加了一个 pom 以使用 felix 的 maven-bundle-plugin 生成 -api-config jar。无需将它们作为依赖项添加到任何地方,只需安装这两个片段,它们就会将其内容与原始包合并
  • 感谢您的回答,这在纯 Equinox 环境中运行良好,但如果我在捆绑包中有自定义转换器插件,log4j2 找不到该插件,所以我得到“无法识别的格式说明符”异常。对此有什么想法吗?
  • 搜索该错误,除此之外,我发现了无法加载 META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat 的提示,您可以尝试将其包含在核心片段中,但考虑到您已经构建了一个自定义转换器我不太确定它会修复它。
【解决方案2】:

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

【讨论】:

  • 这不是一个好的选择,因为我问了 log4j2 的问题
  • Log4j 不是为 OSGi 构建的。 Pax 日志记录是我知道的唯一选择。尽管在开发方面您像以前一样使用 log4j API,但这不是一个坏选择。
  • 我们怎么能说 log4j2 不是为 OSGi 构建的?
  • 这是开发人员在我要求改进 OSGi 支持时告诉我的。 OSGi 中 log4j 的一个问题是它只能使用 log4j 从包中加载配置。这意味着每个包都需要自己的配置,并且无法在运行时更改配置。 Pax 日志使用 OSGi 标准机制配置管理员来外部化配置。因此,您可以为所有捆绑软件提供一个配置,并在运行时更改它。另一个问题是附加程序。 Log4j 附加程序必须在使用日志记录的包内。在 pax 日志中,您可以在运行时安装它们。
  • 我刚刚检查了 log4j jira。显然他们正在研究 OSGi 对 log4j2 的支持。如您所见,部分已完成,但许多步骤仍未解决。见issues.apache.org/jira/browse/LOG4J2-515所以也许它很快就会起作用..手头上的一些问题来自2008年。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    您需要在 META-INF/MANIFEST.MF 中指定您的捆绑包的 OSGI 相关依赖项,方法是添加以下依赖项:

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

    【讨论】:

      【解决方案5】:

      对我来说,这个错误是通过以下方式解决的:

      • 确保在调用记录器之前实际激活了 log4j-api 包 - 而不仅仅是解决了问题。我通过将其设置为低启动级别的自动启动来做到这一点。
      • 让 log4j-api 导入 log4j-core 的类(如 @uraime 所述)以确保它找到 log4j-core。最干净的方法是使用片段。除了动态导入,您还可以将其添加到清单中:

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

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

      此外,我发现激活 log4j-core 包不是必需的(仅已解决),但请注意,这确实意味着 Activator 找不到自定义 log4j2 插件。

      【讨论】:

      • 在我的 Eclipse 工作区中,不知何故我不需要为 log4j-api 动态导入的片段。它能够在不这样做的情况下加载 log4j-core。但是在我的最终产品构建中,我仍然遇到了同样的错误。我的捆绑包配置完全相同 - 直到订购!我怀疑 log4j-api (2.3.0) 正在执行一些类加载技巧(可能使用线程上下文类加载器),这些技巧在 OSGi 中可能工作也可能不工作,具体取决于 OSGi 实现(对我来说:org.eclipse.osgi_3.7.2.v20120110 -1415.jar) 捆绑包的解析顺序。)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-18
      • 1970-01-01
      • 2021-03-19
      • 2018-07-30
      • 2019-05-12
      • 2014-12-30
      相关资源
      最近更新 更多