Setting Logger Implementation to Test Scope with Maven for IntelliJ - maven

For automated tests of an API, I need to have an implementation of a logger present. But the logger is supposed to not ship with the API itself. To that end I set up the relevant part of the pom.xml of the API module itself like so:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
When I manually run maven from the command line the test where the logger is relevant passes. But when I run the test file from within Intellij I get the following error:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
I have spent several hours now trying to figure out what is wrong and followed multiple tutorials. None actually covered the sort of setup I need though and so I am still stuck with this error.
Do you know what the actual problem is here and how to set this up correctly?

Related

Correctly fixing multiple `StaticLoggerBinder` bindings in Spark

I had a nice little Maven-built CLI application using Java 17 on Windows 10. For logging I went over SLF4J (org.slf4j:slf4j-api:1.7.36) with Logback (ch.qos.logback:logback-classic:jar:1.2.11) as the implementation.
That was fine until I added Spark 3.3.0 into the mix:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
Then when I run my application, I get this:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in […/lib/logback-classic-1.2.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in […/lib/log4j-slf4j-impl-2.17.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
When I do a mvn dependency:tree, it looks like Spark is bringing in all this mess:
[INFO] | +- org.slf4j:jul-to-slf4j:jar:1.7.36:compile
[INFO] | +- org.slf4j:jcl-over-slf4j:jar:1.7.36:compile
[INFO] | +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.17.2:compile
[INFO] | +- org.apache.logging.log4j:log4j-api:jar:2.17.2:compile
[INFO] | +- org.apache.logging.log4j:log4j-core:jar:2.17.2:compile
[INFO] | +- org.apache.logging.log4j:log4j-1.2-api:jar:2.17.2:compile
In particular org.apache.logging.log4j:log4j-slf4j-impl:jar:2.17.2 is the core problem; it's a Log4j 2 SLF4J Binding for an application logging to SLF4J, to use Log4J as the SLF4J implementation. But I'm using Logback as my SLF4J implementation. So I can exclude the Log4J implementation like this:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_${scala.version}</artifactId>
<version>${spark.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
Wonderful; now the warning goes away. I've solved the problem.
But here is my concern: you can see above that Spark is also bringing in log4j-api (the Log4J API itself) as well as log4j-1.2-api, which is a Log4j 1.2 Bridge for applications that write to the Log4J 1.x API! Does this mean that Spark is writing to the Log4J 2.x API itself, or even (horrors!) to the Log4J 1.x API? 🤦‍♂️
Do I also need to include a Log4J-to-SLF4J bridge dependency so that whatever code that uses Log4J in some corner of Spark will correctly get its log output routed to SLF4J? Or is all this extra Log4J gunk included because someone setting up the POM didn't quite fully understand what it means to write to the SLF4J API, and just threw the kitchen sink at things?
In other words, am I good with the Log4J 2 implementation exclusion above, or do I also need to add Log4J-to-SLF4j bridges for some piece of Spark that writes directly to the Log4J API rather than through the SLF4J API?

Adding slf4j-simple.jar doesn't solve: Failed to load class "org.slf4j.impl.StaticLoggerBinder"

On starting spring boot application, I get:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
In maven dependency tree, I see following occurrences of slf4j:
org.slf4j:slf4j-api:jar:1.7.30:compile
com.typesafe.akka:akka-slf4j_2.11:jar:2.5.21:compile
org.clapper:grizzled-slf4j_2.11:jar:1.3.2:compile
org.apache.logging.log4j:log4j-to-slf4j:jar:2.13.3:compile
org.slf4j:jul-to-slf4j:jar:1.7.30:compile
At this link, it mentions to add slf4j-simple.jar to solve it. I did so:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.0-alpha1</version>
</dependency>
....but I still get the error.
How to solve it?

Missing newline character in rawlogs using log4j and slf4j

I am working on a bug using log4j2 and slf4j. I have been reviewing the commit history in Github, but cannot find where the bug was introduced. In the log file rawlogs.log the newline character %n has been replaced by %replace%n. Please see the example below:
applog.line=16,applog.msg=ConfigChangeListener Initilized!%replace%nXXXXXXXX03172 123456789 2019-06-11 15:06:35.080 devHostname
I am using the following dependencies:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.10.0</version>
</dependency>
In the files with logs the LoggerFactory is created with the example below:
private static final Logger LOGGER = LoggerFactory.getLogger(ClassName.class);
I have tried using both a log4j2.properties, and log4j2.xml files from log4j2 examples, but always get this error on startup:
2019-06-11 15:19:16,063 warmup - 7 ERROR No log4j2 configuration file found. Using default configuration: logging only errors to the console.
The rawlogs.log file is created and populated on startup.
Has anyone experienced this before? Any insight is appreciated.
EDIT: To clarify, project did not use a .xml or .properties file for configurations. I introduced them in an attempt to expose the root cause of the bug, but have not had success.

Adding javax.servlet-api dependency throws exception that org.slf4j.impl.StaticLoggerBinder faild to load but i don't use sl4j, i use thymeleaf

Basicaly title. I'm trying to run simple spring5 + thymeleaf project. If i don't add servlet-api i get an error that
cannot access javax.servlet.ServletException
But if i add servlet-api, project starts and works fine , but i get an error on startup:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
But i don't use sl4j, i use thymeleaf. How does servlet exception connected with sl4j and how should i manage it?
UPD
I understand that my question is wrong. But i need help with connected problem:
As someone suggested i added
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
But i still get Failed to load class "org.slf4j.impl.StaticLoggerBinder". exception. Any ideas?
UPD
as someone mentioned here this is a bug of ide
Add slf4j.jar in your dependency or your project. Spring internally use slf4j for its own logging.
I'm using IntelIj idea.
As someone sugested i added log4j and sl4j dependencies becouse servlet-api uses loging by default. And my exception that class is failed to load is just a bug of ide as it was mentioned in another question and everything including logging works fine.

Glassfish incremental deployment failes when including Selenium

I have a Java EE project which is meant to run on Glassfish 4.1. I want to use Selenium to collect information from some web pages, i.e. I need to include Selenium in the deployment (not just for tests).
I am using Eclipse IDE and have previously utilized the incremental deployment function in Eclipse to automatically deploy all saved changes to the project. But when I included (with Maven) the dependencies for Selenium incremental deployment stopped working. The project can still be deployed to Glassfish but I have to restart Glassfish between every change. I get the following error in Eclipse:
Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.RuntimeException: com.sun.faces.config.ConfigurationException: java.util.concurrent.ExecutionException: com.sun.faces.config.ConfigurationException: Unable to parse document 'bundle://136.0:1/com/sun/faces/jsf-ri-runtime.xml': DTD factory class org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl does not extend from DTDDVFactory.. Please see server.log for more details.
org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl is included with Selenium as a transitive dependency (xerces:xercesImpl:2.11.0).
Here are my Maven dependencies:
<dependency>
<groupId>org.jboss.arquillian.selenium</groupId>
<artifactId>selenium-bom</artifactId>
<version>2.44.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-htmlunit-driver</artifactId>
</dependency>
I hope there is a solution to this but after reading Jens Schauder's response in Dealing with "Xerces hell" in Java/Maven? I'm afraid there might not be. Anyone?
I currently can't reproduce the issue with a simple project, did you make sure that you don't have any other dependencies which are importing another version of xercesImpl?
You can try to place the xercesImpl-2.11.0.jar and the transitive dependency xml-apis-1.4.01.jar in the lib folder of your Glassfish domain and exclude it from your dependencies like this:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-htmlunit-driver</artifactId>
<version>2.44.0</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
See also:
org.apache.xerces.impl.dv.DVFactoryException: DTD factory class org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl does not extend from DTDDVFactory
Xerces error: org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl

Resources