Reputation: 1385
I am working on a TCP server, and I am trying to add logging. I have decided to use Logback
. Here is my code :
final static Logger logger = LoggerFactory.getLogger(Ecmg.class);
public static void main(String[] args)
{
new Ecmg(args);
}
public Ecmg(String[] args) {
logger.info("Hello world.");
System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "/src/main/resources/logback.xml");
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
StatusPrinter.print(lc);
waitForConnection();
}
Unfortunatly I am getting the following output :
[main] INFO Ecmg - Hello world.
Exception in thread "main" java.lang.ClassCastException: org.slf4j.simple.SimpleLoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext at Ecmg.<init>(Ecmg.java:41) at Ecmg.main(Ecmg.java:29)
Process finished with exit code 1
Apparently, the following line is the problem : LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
. I wrote it following a tutorial, and this is supposed to work. Here is my pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<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>Server</groupId>
<artifactId>Server</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.8.0-beta2</version>
</dependency>
</dependencies>
In case it is important, I am using java 8 and Intellij 2018.1.
My question is : Why am I getting this error, and how can I solve it?
NOTE: I found nothing on the Internet, except for this other SO question, that it might be related with. But it has not been solved, and none of the answers proposed worked for me.
Thanks in advance!
Upvotes: 1
Views: 1103
Reputation:
SLF4J is a standardized interface for logging. You use its API for logging, and have a binding on your classpath for the actual logging framework that you want to use.
If your LoggerFactory.getILoggerFactory()
is a SimpleLoggerFactory
, then you're using the SimpleLogger binding. You say that you've decided to use Logback, but you're actually using the SLF4J SimpleLogger instead.
In order to use Logback, you need to ensure that it is on your classpath, and that no other SLF4J binding is on your classpath. Since you're using Maven to manage your dependencies, you may want to run "mvn dependency:tree" to see the list of all dependencies, and what your dependencies are bringing in. That may help you figure out what other bindings you're using.
Well-behaved libraries intended for use with SLF4J will just include slf4j-api, since the binding should just be used by the main application. If you have a not-well-behaved library that does try to use its own binding, you may need to use Maven to exclude that binding.
Also, it's often helpful to use <dependencyManagement>
sections in your POM to ensure that all your dependencies use the same version of slf4j-api and don't try to all include their own separate version, as well as using the maven-enforcer-plugin's bannedDependencies rules to ensure that you don't screw up when making changes in the future and accidentally include another logging framework into your project.
Upvotes: 2