SLF4J为什么在我的项目中找不到任何提供者?

huangapple go评论83阅读模式
英文:

Why can't SLF4J find any providers in my project?

问题

我最近分叉了一个GitHub项目,并一直在尝试将其更新。我的主要目标之一是删除旧版(有漏洞的)Log4J v1.2,并替换为Log4J 2.2。原始项目使用旧版的SFL4J与Log4J v1.2。

我不怎么写Java,也从未在分叉这个项目之前使用过Gradle,所以请温柔点。

无论我做什么或尝试什么,SLF4J在运行我的应用程序时总是报告以下内容:

SLF4J:找不到SLF4J提供程序。
SLF4J:默认使用无操作(NOP)日志记录器实现
SLF4J:请参阅http://www.slf4j.org/codes.html#noProviders以获取更多详细信息。

我已经阅读了许多涵盖设置的教程,但似乎无法使其正常工作。

我尝试了以下设置:

slf4j-api-2.0.7.jar
log4j-api-2.20.0.jar
log4j-core-2.20.0.jar
log4j-slf4j2-impl-2.20.0.jar
log4j2.properties

我还尝试放弃log4j2,只使用SLF4J的SimpleLogger的更简单的设置:

slf4j-api-2.0.7.jar
slf4j-simple-2.0.7.jar

但是,SLF4J报告了相同的问题。我目前正在从以下公共存储库中工作:
https://github.com/jmoscola/PygmyMarmoset/tree/updateLogging

文件default.deps包括当前的依赖关系。Log4J当前被注释掉,但这将是首选的日志记录器,因为我希望维护日志文件的每日滚动。

子项目PygmyMarmosetLauncher中的文件UberjarDaemon.java显示了使用org.slf4j进行基本Logger/LoggerFactory设置

构建快速且简单:

  1. ./fetchdeps.pl
  2. gradle uberJar

如果有人能给我一些关于我哪里出错的提示,我会非常感激。

英文:

I recently forked a GitHub project and have been trying to bring it up to date. One of my primary goals was to remove the old (vulnerable) Log4J v1.2 and replace it with Log4J 2.2. The original project used an old version of SFL4J with Log4J v1.2.

I don't write much Java and have never used Gradle until I forked this project, so be gentle.

Anyway, no matter what I do or try, SLF4J always reports the following when I run my application:

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.

I've read many tutorials that cover the setup, but I can't seem to get this working.

I tried using setup with the following:

slf4j-api-2.0.7.jar
log4j-api-2.20.0.jar
log4j-core-2.20.0.jar
log4j-slf4j2-impl-2.20.0.jar
log4j2.properties

I've also tried ditching log4j2 and using a simpler setup with just the SimpleLogger from SLF4J:

slf4j-api-2.0.7.jar
slf4j-simple-2.0.7.jar

However, SLF4J reports the same issue. I'm currently working out of the following public repo:
https://github.com/jmoscola/PygmyMarmoset/tree/updateLogging

The file default.deps includes the current dependencies. Log4J is currently commented out, but that would be the preferred logger as I would like to maintain a daily rollover for log files.

The file UberjarDaemon.java in subproject PygmyMarmosetLauncher shows the basic Logger/LoggerFactory setup using org.slf4j

Building is quick and easy:

  1. ./fetchdeps.pl
  2. gradle uberJar

I'd really appreciate it if someone could give me some tips on where I've gone wrong.

答案1

得分: 1

感谢@g00se的评论,我成功地使一切正常运作。

  • 首先,我不得不将我的log4J属性文件放入我的类路径中,这是我的UberJar的根目录。之前,我尝试将我的log4J属性文件放入/war/WEB-INF/classes文件夹中,但这对我来说行不通。我编辑了我的rootProject build.gradle文件,将属性文件放到了它所需的位置。

  • 我还意识到我的log4J属性文件名称不正确。该项目之前使用的是log4J 1.2,所以已经有一个现有的'log4j.properties'文件。在阅读文档和教程时,我起初没有注意到log4J 2.20使用了一个新的文件名,'log4j2.properties'。

  • 最后,我遇到了一些语法问题,因为我没有正确更新log4J 1.2的语法以适应log4J2。

现在,我使用SLF4J API和log4J2进行日志记录。尽管如此,我仍然在stdout中看到“未找到SLF4J提供程序”的消息。但我愿意忽略它,因为日志已经生成。我怀疑这与存在多个子项目有关,其中一个启动了webapp(可能有不同的类路径?)。但这是另一天的问题。

英文:

Thanks to the comment made by @g00se I was able to get everything working.

  • First, I had to put my log4J properties file into my classpath, which was the root of my UberJar. Previously, I was attempting to put my log4J properties file into my /war/WEB-INF/classes folder and that wasn't working out for me. I edited my rootProject build.gradle file to get the properties file where it needed to go.

  • I also realized that my log4J properties file had the wrong name. The project previously used log4J 1.2 so it already had an existing 'log4j.properties' file. While reading documentation and tutorials I didn't initially notice that log4J 2.20 uses a new filename, 'log4j2.properties'.

  • Lastly, I had some syntax issues as I hadn't properly updated the log4J 1.2 syntax for log4J2.

I now have logging working using the SLF4J API with log4J2. With that said, I STILL see the "No SLF4J providers were found" message in my stdout. But I'm willing to ignore it since logs are being produced. I suspect it has something to do with the existence of multiple subprojects, one of which starts the webapp (and maybe has a different classpath?). But, that's a problem for a different day.

答案2

得分: 1

SLF4J 2.x和许多其他服务依赖于ServiceLoader来查找提供者(对于Log4j API 3.x也是如此)。服务在META-INF/services文件中声明,您可以在您的build.gradle文件中删除这些声明:

// 将Jetty jar文件的所有内容复制到超级JAR暂存区。
task copyJettyDeps(type: Copy, dependsOn: [':copyJettyLoggingProperties']) {
	duplicatesStrategy = 'INCLUDE'
	from requiredJars(project(':PygmyMarmosetLauncher')).collect { zipTree(it) }
	into 'build/uberJarStaging'
	exclude 'META-INF/**'
}

您应该优化排除资源的列表:

// 将Jetty jar文件的所有内容复制到超级JAR暂存区。
task copyJettyDeps(type: Copy, dependsOn: [':copyJettyLoggingProperties']) {
	duplicatesStrategy = 'WARN'
	from requiredJars(project(':PygmyMarmosetLauncher')).collect { zipTree(it) }
	into 'build/uberJarStaging'
	exclude(
			'module-info.class',
			'about*',
			'META-INF/DEPENDENCIES*',
			'META-INF/MANIFEST.MF',
			'META-INF/LICENSE*',
			'META-INF/NOTICE*',
			'META-INF/versions/9/module-info.class'
		)
}

module-info.class来自Log4j API,并且仅导出Log4j API特定的包,因此应将其删除。MANIFEST.MF也是如此,它包含在您遮蔽的所有JAR文件中。从技术上讲,删除许可证和通知是安全的,并且可以消除许多警告,但如果您要发布应用程序,您需要咨询律师。

备注: 通过遮蔽log4j-api,您还会破坏Log4j API和相关功能的位置支持。要修复它,您需要将以下内容替换为:

	manifest {
		attributes 'Main-Class' : 'edu.ycp.cs.pygmymarmoset.main.UberjarMain'
	}

改为

	manifest {
		attributes ([
			'Main-Class' : 'edu.ycp.cs.pygmymarmoset.main.UberjarMain',
			'Multi-Release' : 'true'
		])
	}
英文:

SLF4J 2.x and many other services rely on ServiceLoader to find providers (same for Log4j API 3.x). Services are declared in META-INF/services files and you remove the declarations, in your build.gradle file:

// Copy all of the contents of the Jetty jarfiles into the uberjar staging area.
task copyJettyDeps(type: Copy, dependsOn: [':copyJettyLoggingProperties']) {
	duplicatesStrategy = 'INCLUDE'
	from requiredJars(project(':PygmyMarmosetLauncher')).collect { zipTree(it) }
	into 'build/uberJarStaging'
	exclude 'META-INF/**'
}

You should refine the list of excluded resources:

// Copy all of the contents of the Jetty jarfiles into the uberjar staging area.
task copyJettyDeps(type: Copy, dependsOn: [':copyJettyLoggingProperties']) {
	duplicatesStrategy = 'WARN'
	from requiredJars(project(':PygmyMarmosetLauncher')).collect { zipTree(it) }
	into 'build/uberJarStaging'
	exclude(
			'module-info.class',
			'about*',
			'META-INF/DEPENDENCIES*',
			'META-INF/MANIFEST.MF',
			'META-INF/LICENSE*',
			'META-INF/NOTICE*',
			'META-INF/versions/9/module-info.class'
		)
}

The module-info.class comes from Log4j API and exports only the packages specific to Log4j API, so it should be removed. Same goes for MANIFEST.MF, which is contained in all the JARs you shade. Removing licenses and notices is technically safe and removes a lot of warnings, but if you were to publish the app, you need to consult a lawyer.

Remark: by shading log4j-api you also break location support in Log4j API and related features. To fix it you need to replace:

	manifest {
		attributes 'Main-Class' : 'edu.ycp.cs.pygmymarmoset.main.UberjarMain'
	}

with

	manifest {
		attributes ([
			'Main-Class' : 'edu.ycp.cs.pygmymarmoset.main.UberjarMain',
			'Multi-Release' : 'true'
		])
	}

huangapple
  • 本文由 发表于 2023年8月10日 11:56:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76872568.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定