Finlay Weber
Finlay Weber

Reputation: 4143

How to configure sl4j API in library while making it possible for clients to use own logging implementation?

I am currently using Logback for a library and now I want to make changes to use sl4j instead so that the users of my library are not forced to use Logback.

From what I have read so far, in my configuration I should have SL4J-api logback-classic, so basically this:

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>{sl4j-api.version}</version>
</dependency>

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>{logback.version}</version>
</dependency>

This mean in the library I would use the sl4j API while the actual logger implementation will be log4j.

But this also means the log4j jars would also be included as dependencies when my clients make use of the library. And I do not know of any way to prevent this.

I thought the purpose of using sl4j is to prevent a case where the client of the library have to deal with jars of loggers they do not need. But it seems this is not the case.

It means if they want to use log4j instead, they would still have to write <exclusion> rules in their pom that excludes logback-classic.

Or is there any other way to use sl4j, and a specific logger in a library jar, and have the specific logger jar not included in the packaged jar that clients depends upon. Such that clients do not need to exclude the ones that come with the library but they just need to plug in their own specific logger?

If it is possible to do this, what will the configuration look like?

Upvotes: 0

Views: 678

Answers (1)

Tim Moore
Tim Moore

Reputation: 9472

You are correct that the purpose of using slf4j in a library is to allow the consumer of the library to choose the logging backend implementation. The way to achieve that is to remove the dependency on logback-classic from the library. The slf4j-api dependency provides all of the types required to write log statements, and libraries should not depend on a concrete logging implementation.

If you need to use a logging implementation when running tests, you can specify the dependency with test scope:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>{logback.version}</version>
    <scope>test</scope>
</dependency>

This will cause Maven to put the dependency on the classpath only when compiling and running tests. Downstream consumers of the library will not inherit a transitive dependency on logback-classic in this case.

Upvotes: 1

Related Questions