Log4j2 api无法在OSGi环境中找到Log4j2核心[英] Log4j2 api cannot find Log4j2 core in OSGi environment

本文是小编为大家收集整理的关于Log4j2 api无法在OSGi环境中找到Log4j2核心的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在尝试使用log4j2 osgi捆绑包,但是在OSGI环境中,Log4J2 API似乎找不到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 Core的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核的元I-INF内部的资源特别是log4j-providoer.properties文件,log4j api不可见.

谢谢!

推荐答案

启动激活器并开始搜索日志插件时,log4j核捆绑包登录器bundle侦听器,如果发现某些东西,则执行类似于通常的logger初始化的操作序列(不是真正的惯用osgi的东西和我不确定它有效,但似乎至少设置了Log4jContextSelector和LoggerContextFactory),只是为了确保它,您是否安装了和启动log4j核心捆绑包并进行了验证没什么改变吗?

更新:

我进行了一些测试,并找到了log4j2 OSGI问题的可接受的解决方案/解决方法.但是,正如其他人所建议的那样,我会使用slf4j,pax-logging或简单的OSGI日志服务(束的简单).

@grant,您有2个需要修复的单独的东西:

1.,如您所述," Log4J2找不到日志记录实现"错误是由于捆绑包找不到 log4j-provider的事实引起的. properties file 和,在修复此之后,log4j2-api找不到log4j2-core类(这是一个不同的捆绑包,log4j2-api没有特定的导入包装:for for这些课).

解决方法是为log4j2-api创建一个小片段捆绑包(我称其为mine log4j-api-config.jar),用META-INF中的.properties file,并迫使动态导入:

    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-core 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 jars甚至您的捆绑包来添加导入/导出),因此原始捆绑包和您自己的自定义捆绑包将保持不变. 另外,它们也不依赖于原始捆绑包,它们只是带有清单和附加文本文件的基本jar存档,无代码,不需要进口包装或导出包.

您只需要在安装主机束后安装每个片段.

我已经从一个空的jar开始手动创建了两个片段,然后在存档中复制属性文件并使用文本编辑器修改清单. pom.xml所在的提供者.

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(包括文件,捆绑名称),以生成另一个POM使用log4j2-core配置.

其他推荐答案

log4j不适合OSGI环境.幸运的是,替换 pax-logging"> pax-logging .在您的捆绑包中,您使用Log4J API或任何其他支持的API(我更喜欢SLF4J-API).然后,您将PAX登录到OSGI框架和捆绑包. 您可以使用标准log4j配置配置PAX记录.因此,它很容易使用.如果您想要一个非常简单的启动,则可以简单地安装 apache karaf 并将您的捆绑包部门.卡拉夫已经包含了一个完全设置的PAX记录.

其他推荐答案

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

本文地址:https://www.itbaoku.cn/post/1574897.html

问题描述

I'm trying to use log4j2 OSGi bundles, but it seems log4j2 api cannot find log4j2 core in an OSGi environment. I'm continuously getting the following exception :

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

I found the same exception discussed in few places but still I could not figure out this issue. Isuspect I'm getting this issue because log4j2 api cannot find the log4j-provider.properties inside the META-INF directory of log4j2 core. Is there any clue why I'm getting this exception and how can I correct the issue ? (If anybody has correct pom file for adding log4j dependencies and bundling please share it with me)

These are the dependencies I have used

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

I use apache felix as the bundle plugin. This error occures because resources inside the META-INF of log4j2-core specially the log4j-providoer.properties file is not visible to log4j api.

Thanks!

推荐答案

The log4j-core bundle registers a bundle listener when the Activator is started and starts searching for log plugins and if something is found it performs a sequence of operations similar to the usual Logger initialization (not really idiomatic OSGi stuff and i'm not sure it works, but it seems to set at least Log4jContextSelector and LoggerContextFactory), just to be sure of it, did you install and start the log4j-core bundle and verified that nothing changed?

Update:

I did some testing and found what is an acceptable solution/workaround for log4j2 OSGi issues. But as someone else recommended, alternatively i would use slf4j, pax-logging or simply the OSGi Log Service (the simpler of the bunch).

@Grant, you have 2 separate things that need to be fixed:

1. As you described, the "Log4j2 could not find a logging implementation" error is caused by the fact that the log4j2-api bundle is unable to find the log4j-provider.properties file and, after that is fixed, log4j2-api cannot find the log4j2-core classes (it's a different bundle and log4j2-api doesn't have a specific Import-Package: for those classes).

The workaround for this is to create a small fragment bundle for log4j2-api (i called mine log4j-api-config.jar) with that .properties file in META-INF and a manifest that forces a dynamic import:

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

I'm importing * here, you can improve it adding the required subset of log4j2-core packages that log4j2-api needs.

With this, that error will disappear, but log4j will notice that you didn't provide a log4j2 configuration file, next thing to fix (only if you care in this case).

2. At this point Felix will display this:

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.

and i suppose you could want to add your own log4j2.xml without messing with the original log4j2-core.jar. You can do this creating another fragment bundle, this time hosted by log4j2-core, with just a log4j2.xml configuration file in the root and a simple manifest:

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

I used this simple log4j2.xml configuration during my tests:

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

With this you will not need that sort of "bridge" bundle you described below anymore, and you'll just need a simple Import-Package: org.apache.logging.log4j to use log4j from your bundle.

Update 2:

Important to note that the two fragments are NOT dependencies of the original bundles (no need to modify log4j jars or or even your bundles to add import/export), so the original bundles and your own custom ones will remain untouched. Also, they don't depend on the original bundle either, they are just basic jar archive with a manifest and an additional text file, no code, no need for Import-Package or Export-Package.

You just need to install each fragment after their host bundle is installed.

I've created both fragments manually starting from an empty jar and copying inside the archive the properties file and modifying the MANIFEST.MF with a text editor, you can create them both with this pom.xml, remember to copy log4j-provider.properties where pom.xml is located.

For the log4j2-api fragment:

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

Modify this pom where appropriate(included file, bundle names) to generate the other one with the log4j2-core configuration.

其他推荐答案

Log4j is not suitable for an OSGi environment. Luckily there is a nice drop in replacement pax-logging. In your bundle you use the log4j api or any other of the supported apis (I prefer slf4j-api). Then you deploy pax logging to your OSGi framework and your bundle. You can configure pax logging using a standard log4j config. So it is very easy to use. If you want a really easy start you can simply install apache karaf and deploy your bundle to it. Karaf already includes a fully set up pax logging.

其他推荐答案

Try changing the name of the jar file something does not contain core word (eg:log4j-zore) and try again