I had a Java 8 project and my configuration file was in resource folder and everything worked fine. Now I switched to Java 9, added requirement for log4j.api
, and configuration file cannot be found anymore.
Do I need to add something else in my module-info
file for the logger to find it's config?
For now, it's like this
module project.main {
requires jdk.incubator.httpclient;
requires jackson.databind;
requires jackson.core;
requires jackson.annotations;
requires log4j.api;
}
The Project structure is as:
The build.gradle file is as:
The log4j~faq suggests using at least log4j-api-2.x
and log4j-core-2.x
. Preferably add these to your build.gradle
file:
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.9.0'
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.9.0'
compile group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: '2.9.0'
And make sure conflicting dependencies are excluded
In the module-info.java
further you shall update(this is what I did in a custom maven project)
requires log4j; // not log4j.api
It should work for you then with the same directory structure as well.
Hint: This is where I started debugging it from.
Why do I see a warning about "No appenders found for logger" and "Please configure log4j properly"?
This occurs when the default configuration files log4j.properties and
log4j.xml can not be found and the application performs no explicit
configuration. log4j uses Thread.getContextClassLoader().getResource()
to locate the default configuration files and does not directly check
the file system...
Placed a debug point in the ClassLoader#getResource
method and just keep an eye of resources looked for by the library.
Also to bring up the point over resources like resources/foo/bar/log4j.properties
as stated in the release notes in JDK-8142968
- JDK internal resources, other than class files, in the standard and JDK modules can no longer be located with the
ClassLoader.getResourceXXX
APIs. This may impact code that relies on
using these APIs to get at JDK internal properties files or other
resources.
and seconded by the java-doc of ClassLoader#getResource
as well:
- Resources in named modules are subject to the encapsulation rules
specified by
Module.getResourceAsStream
. Additionally, and except for
the special case where the resource has a name ending with ".class",
this method will only find resources in packages of named modules when
the package is opened unconditionally (even if the caller of this
method is in the same module as the resource).