我使用 eclipse 4.31 和 slf4j.api 2.0.12 和 ch.qos.logback.classic 1.5.0。但如果我想记录一些东西,我会得到以下信息:
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.
我创建了此处描述的 eclipse RCP: https://www.vogella.com/tutorials/EclipseRCP/article.html logback 记录器与这里类似(我使用更高版本): https://www.vogella.com/tutorials/EclipseLogging/article.html
这里是目标平台:
<target name="target" sequenceNumber="43">
<locations>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<repository location="https://download.eclipse.org/eclipse/updates/4.31/"/>
<unit id="org.eclipse.jdt.feature.group" version="3.19.400.v20240229-0520"/>
<unit id="org.eclipse.pde.feature.group" version="3.15.300.v20240229-0520"/>
<unit id="org.eclipse.platform.ide" version="4.31.0.I20240229-0520"/>
<unit id="org.eclipse.rcp.feature.group" version="4.31.0.v20240229-0520"/>
<unit id="org.eclipse.sdk.ide" version="4.31.0.I20240229-0520"/>
<unit id="org.eclipse.jdt.source.feature.group" version="3.19.400.v20240229-0520"/>
<unit id="org.eclipse.pde.source.feature.group" version="3.15.300.v20240229-0520"/>
<unit id="org.eclipse.rcp.source.feature.group" version="4.31.0.v20240229-0520"/>
<unit id="org.eclipse.emf.ecore.feature.group" version="2.37.0.v20240203-0859"/>
<unit id="org.eclipse.ecf.core.feature.feature.group" version="1.6.2.v20231021-2127"/>
<unit id="org.eclipse.emf.common.feature.group" version="2.31.0.v20231210-0956"/>
<unit id="org.eclipse.equinox.sdk.feature.group" version="3.23.1100.v20240218-1855"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<repository location="https://download.eclipse.org/releases/2024-03"/>
<unit id="org.eclipse.m2e.logback.feature.feature.group" version="2.6.0.20240217-1525"/>
</location>
</locations>
</target>
清单:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Rcp
Bundle-SymbolicName: com.example.e4.rcp;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: EXAMPLE
Require-Bundle: org.eclipse.swt,
org.eclipse.e4.ui.model.workbench,
org.eclipse.jface,
org.eclipse.e4.ui.services,
org.eclipse.e4.ui.workbench,
org.eclipse.e4.core.di,
org.eclipse.e4.ui.di,
org.eclipse.e4.core.contexts,
org.eclipse.core.runtime,
slf4j.api;bundle-version="2.0.12",
ch.qos.logback.classic;bundle-version="1.5.0",
ch.qos.logback.core;bundle-version="1.5.0"
Bundle-RequiredExecutionEnvironment: JavaSE-17
Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)",
jakarta.inject;version="[2.0.0,3.0.0)"
Automatic-Module-Name: com.example.e4.rcp
带有日志记录的类(转到菜单->帮助->关于执行此代码):
package com.example.e4.rcp.handlers;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.swt.widgets.Shell;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AboutHandler {
@Execute
public void execute(Shell shell) {
Logger LOG = LoggerFactory.getLogger(AboutHandler.class);
}
}
产品:
<product name="com.example.e4.rcp" id="com.example.e4.rcp.product" application="org.eclipse.e4.ui.workbench.swt.E4Application" version="1.0.0.qualifier" type="mixed" includeLaunchers="true" autoIncludeRequirements="true">
<configIni use="default">
</configIni>
<launcherArgs>
<programArgs>-clearPersistedState
</programArgs>
<vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts
</vmArgsMac>
</launcherArgs>
<windowImages/>
<plugins>
<plugin id="com.example.e4.rcp"/>
</plugins>
<features>
<feature id="org.eclipse.e4.rcp"/>
<feature id="org.eclipse.m2e.logback.feature" installMode="root"/>
</features>
</product>
根据这里的手册,类路径上的logback-classic.jar将解决问题: https://www.slf4j.org/codes.html#noProviders
我想说 ch.qos.logback.classic 是类路径中的 logback-classic.jar。但问题依然存在。
问题在于 org.slf4j.LoggerFactory 想要使用“LoggerFactory.class.getClassLoader()”加载 SLF4JServiceProvider。这是 org.eclipse.osgi.internal.loader.EquinoxClassLoader。这样就不会找到 SLF4JServiceProvider。
我找到了解决此问题的方法,其中我使用其他类加载器:
将 logback 添加到类路径:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Test2
Bundle-SymbolicName: test2;singleton:=true
Bundle-Version: 1.0.0.qualifier
Eclipse-BundleShape: jar
Require-Bundle: org.eclipse.swt,
org.eclipse.e4.ui.model.workbench,
org.eclipse.jface,
org.eclipse.e4.ui.services,
org.eclipse.e4.ui.workbench,
org.eclipse.e4.core.di,
org.eclipse.e4.ui.di,
org.eclipse.e4.core.contexts,
org.eclipse.core.runtime,
slf4j.api;bundle-version="2.0.12",
ch.qos.logback.classic;bundle-version="1.5.0",
ch.qos.logback.core;bundle-version="1.5.0"
Bundle-RequiredExecutionEnvironment: JavaSE-17
Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)",
jakarta.inject;version="[2.0.0,3.0.0)",
org.slf4j;version="[2.0.0,3.0.0]"
Automatic-Module-Name: test2
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: lib/ch.qos.logback.classic_1.5.6.jar,
lib/ch.qos.logback.core_1.5.6.jar,
lib/slf4j.api_2.0.13.jar,
.
初始化 SLF4JServiceProvider 的代码:
private static void initSLF4JServiceProvider() {
ServiceLoader<SLF4JServiceProvider> serviceLoader = ServiceLoader.load(SLF4JServiceProvider.class);
// init service provider manually
Optional<SLF4JServiceProvider> serviceProviderOpt = serviceLoader.findFirst();
if (serviceProviderOpt.isEmpty()) {
System.err.println("LogbackInitializer: No SLF4JServiceProvider found to init logging");
return;
}
SLF4JServiceProvider slf4jServiceProvider = serviceProviderOpt.get();
slf4jServiceProvider.initialize();
ILoggerFactory loggerFactory = slf4jServiceProvider.getLoggerFactory();
Logger logger = loggerFactory.getLogger("test");
logger.info("Test");
}