Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fix formatting again

...

Following sections shows how to configure different logging solutions/backends dependencies to avoid conflicts. Loggers configuration are out of scope of this document, you should look at relevant library documentation.

Example configuration for Apache Tika 2.5.0+ (Apache Maven)

If you use Apache Maven dependency section in pom.xml will contain something like this:

...

<!-- Merge with your properties section -->
<properties>
  <!-- components versions, feel free keep only required for your case -->
  <tika.version>2.6.0</tika.version>
  <slf4j.version>2.0.3</slf4j.version>
  <log4j2.version>2.19.0</log4j2.version>
  <logback.version>1.4.4</logback.version> <!-- 1.4.4 for Jakarta EE 9+ or 1.3.4 if you use Java EE or Jakarta EE 8 -->
<reload4j.version>1.2.22</reload4j.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.tika</groupId> <artifactId>tika-bom</artifactId> <version>${tika.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-bom</artifactId> <version>${log4j2.version}</version> <type>pom</type> <scope>import</scope> </dependency>   </dependencies> </dependencyManagement> <!-- Merge with your dependencies section --> <dependencies>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
</dependency> <dependency> <groupId>org.apache.tika</groupId> <artifactId>tika-parsers-standard-package</artifactId> <exclusions> <!-- This exclusions will become obsolete at some point but better to keep it now. tika-parser-*-module should excludesexclude commons-logging explicitly but upstream libraries may add it to their direct or transitive dependencies --> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion>

<exclusion> <!--
<groupId>log4j</groupId> These exclusions aren't necessary for tika-parsers-standard-package
<artifactId>log4j</artifactId> </exclusion> but may be required for other <exclusion> artifacts to have explicit logging configuration
<groupId>ch.qos.logback</groupId> and avoid <artifactId>logback-core</artifactId> logging backend loops.
</exclusion> --> <exclusion> <groupId>org.slf4j<<groupId>log4j</groupId> <artifactId>slf4j-reload4j<<artifactId>log4j</artifactId> </exclusion>
<exclusion>
<groupId>ch<groupId>org.qos.logback<slf4j</groupId>
<artifactId>logback<artifactId>slf4j-classic<log4j12</artifactId>
</exclusion> <exclusion> <groupId>ch<groupId>org.qos.reload4j<slf4j</groupId> <artifactId>reload4j<<artifactId>slf4j-reload4j</artifactId> </exclusion>
<exclusion> <groupId>ch.qos.reload4j<logback</groupId> <artifactId>reload4j<<artifactId>logback-core</artifactId> </exclusion>     </exclusions> <exclusion> </dependency> <!-- You may want to add these dependencies to dependencyManagement to force consistent version if you wish.<groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </exclusion> tika-parsers have slf4j-api, jul-to-slf4j and jcl-over-slf4j as dependencies explicitly, so they are here primary as example. --> <dependency> <groupId>org.slf4j</groupId> <exclusion> <groupId>ch.qos.reload4j</groupId> <artifactId>reload4j</artifactId> <artifactId>slf4j-api</artifactId> </exclusion> <version>${slf4j.version}</version>exclusions> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>${slf4j.version}</version> </dependency><!-- You may want to add these dependencies to the dependencyManagement to force consistent versions and omit their versions here --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl<artifactId>slf4j-over-slf4j<api</artifactId> <version>${slf4j.version}</version> </dependency>
<dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over<!-- java.util.logging to slf4j adapter, requires additional configuration, see https://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> </dependencies>

Apache Log4j 2.x with slf4j bridges



<!--
Merge with your dependencies section -->
<dependencies>
<!-- logging backend: log4j 2.xcommons-logging (JCL) to slf4j bridge -->
<dependency>
<groupId>org.apache.logging.log4j<slf4j</groupId>
<artifactId>log4j<artifactId>jcl-over-core<slf4j</artifactId>
<!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in dependencyManagement section -->
<version>${slf4j.version}</version>
<scope>runtime</scope> </dependency>

 <<!-- slf4j implementation that forwardslog4j 1.2.x to log4jslf4j 2.xbridge --> <dependency> <groupId>org.apache.logging.log4j<slf4j</groupId> <artifactId>log4j-slf4j2over-impl<slf4j</artifactId> <version>${slf4j.version}</version>
<scope>runtime</scope> </dependency> </dependencies>

Apache Log4j 2.x with slf4j bridges

<!-- forMerge slf4j 1.7.x use log4j-slf4j-impl insteadwith your dependencies section -->
<dependencies>
<!-- version logging backend: log4j 2.x -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
   <!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
  </dependency>
</dependencies>

...


<!-- Merge with your dependencies section -->
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<!-- TODO: add log4j2 -> slf4j bridge version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
<!-- slf4j implementation <scope>runtime</scope>
</dependency>
 <!-- slf4j implementation that forwards to log4j 2.x -->
<dependency>
<groupId>ch<groupId>org.apache.qoslogging.logback<log4j</groupId>
<artifactId>logback<artifactId>log4j-slf4j2-classic<impl</artifactId>
<!-- for <version>${logback.version}</version>
</dependency>
</dependencies>

TO BE REWRITTEN:

Apache Log4j 2.x with slf4j bridges

slf4j 1.7.x use log4j-slf4j-impl instead -->
<!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
<scope>runtime</scope>
  </dependency>
</dependencies>

Logback

<!-- Merge with your dependencies section -->
<dependencies>
<!-- slf4j implementation -->
<dependency>
<groupId>ch.qos.logback<<dependencies>
<!-- bridges to route jul and jcl (commons-logging) are already present, so just add log4j 1.2.x one -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- slf4j implementation to forward logs to log4j 2.x -->
 <dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j<artifactId>logback-slf4j-impl<classic</artifactId>
<version>${log4j2logback.version}</version>
<scope>runtime</scope>
</dependency>

<!-- logginglog4j2 backend:to log4jslf4j 2.xadapter -->
  <!-- this dependency declarations are optional since <dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
   <!-- version is omitted since there's org.apache.logging.log4j:log4j-slf4j-implbom dependsin onthe themdependencyManagement transitivelysection -->
<dependency>
<scope>runtime</scope>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version></version>
</dependency>
 <dependency>
</dependency>
</dependencies>

Apache Log4j 2.x with native bridges

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j<tika</groupId>
<artifactId>log4j-core<<artifactId>tika-parsers-standard-package</artifactId>
<version>${log4j2.version></version>
</dependency>
</dependencies>

Apache Log4j 2.x with native bridges

<dependencies>
<dependency>
<exclusions> <exclusion> <groupId>org.apache.tika</groupId>
<artifactId>tika<groupId>commons-parsers<logging</artifactId>
groupId> <version>${tika.version}</version>
<exclusions>
<artifactId>commons-logging</artifactId> <!--
/exclusion> <exclusion> This exclusion will become obsolete at some<groupId>log4j</groupId> point but better to keep it now.
<artifactId>log4j</artifactId> tika-parsers usually excludes commons-logging explicitly but upstream libraries
</exclusion> <exclusion> <groupId>org.slf4j</groupId> may add it to their direct or transitive dependencies
<artifactId>slf4j-log4j12</artifactId> </exclusion> -->
<exclusion>
<groupId>commons-logging<<groupId>org.slf4j</groupId>
<artifactId>commons<artifactId>slf4j-logging<reload4j</artifactId>
</exclusion>
<!-- We exclude slf4j bridges and replace them with native log4j 2.x ones below -->
<exclusion> <groupId>ch.qos.logback</groupId> <exclusion>
<artifactId>logback-core</artifactId> </exclusion>      <exclusion> <groupId>org<groupId>ch.qos.slf4j<logback</groupId>
<artifactId>jul<artifactId>logback-to-slf4j<classic</artifactId>
</exclusion>
 <exclusion>
<exclusion> <groupId>org<groupId>ch.qos.slf4j<reload4j</groupId>
<artifactId>jul-to-slf4j<<artifactId>reload4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- slf4j implementation to forward logs to log4j 2.x -->
  <dependency>
<!-- Additionally exclude slf4j bridges --> <exclusion> <groupId>org.apache.logging.log4j<slf4j</groupId>
<artifactId>log4j<artifaftId>jul-slf4jto-impl<slf4j</artifactId>
<version>${log4j2.version}</version>
exclusion> </dependency>
<exclusion> <!-- log4j 2.x bridges to forward java.util.logging, jcl/commons-logging and log4j 1.2.x to log4j 2.x -->
  <dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<version>${log4j2.version}</version>
</dependency>
  <dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<groupId>org.slf4j</groupId> <artifaftId>jul-to-slf4j</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifaftId>jcl-over-slf4j</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifaftId>log4j-over-slf4j</artifactId> </exclusion>    </exclusions> </dependency> <!-- loggingslf4j backend:implementation log4jto 2.x -->
  <!-- this dependency declarations are optional since org.apache.logging.log4j:log4j-slf4j-impl depends on them transitively -->
<dependency>
forward logs to log4j 2.x -->   <dependency> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-api<impl</artifactId>
<!-- for <version>${log4j2.version></version>
</dependency>
  <dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version></version>
</dependency>
</dependencies>

...

slf4j 1.7.x use log4j-slf4j-impl instead -->
    <!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
    <scope>runtime</scope>
  </dependency>

  <!-- log4j 2.x bridges to forward java.util.logging, jcl/commons-logging and log4j 1.2.x to log4j 2.x -->
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-jul</artifactId>
    <!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-jcl</artifactId>
    <!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
    <scope>runtime</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-1.2-api</artifactId>
    <!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
    <scope>runtime</scope>
  </dependency>

  <!-- logging backend: log4j 2.x -->
  <!-- this dependency declarations are optional since org.apache.logging.log4j:log4j-slf4j-impl depends on them transitively -->
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <!-- version is omitted since there's org.apache.logging.log4j:log4j-bom in the dependencyManagement section -->
    <scope>runtime</scope>
  </dependency>
</dependencies>

Example configuration for Apache Tika 2.5.0+ (Gradle)

Common sections

dependencies {
// Import Maven BOM for Tika and Log4j 2.x.
// Depending on your setup `api` could be used instead of `implementation` when `java-library` plugin is activated.
implementation(platform("org.apache.tika:tika-bom:2.6.0"))
implementation(platform("org.apache.logging.log4j:log4j-bom:2.19.0"))

constraints {
   // versions from constraints work like a dependencyManagement section in Maven
implementation("org.slf4j:slf4j-api:2.0.3")
implementation("org.slf4j:jul-to-slf4j:2.0.3")
  implementation("org.slf4j:jcl-over-slf4j:2.0.3")
implementation("org.slf4j:log4j-over-slf4j:2.0.3")
}

implementation("org.apache.tika:tika-core")
implementation("org.apache.tika:tika-parsers-standard-package")
}

configurations.all {
// remove if using Apache Log4j 2.x log4j-jcl native bridge instead of jcl-over-slf4j
exclude("commons-logging", "commons-logging")
}

Apache Log4j 2.x with slf4j bridges

// merge with common section above
dependencies {
// versions from platform/BOM
implementation("org.apache.logging.log4j:log4j-api")
runtimeOnly("org.apache.logging.log4j:log4j-core")
runtimeOnly("org.apache.logging.log4j:log4j-slf4j2-impl") // for slf4j 1.7.x use log4j-slf4j-impl instead

implementation("org.slf4j:jul-to-slf4j") // java.util.logging to slf4j, requires additional configuration, see https://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
runtimeOnly("org.slf4j:jcl-over-slf4j") // commons-logging (JCL) to slf4j
runtimeOnly("org.slf4j:log4j-over-slf4j") // log4j 1.2.x to slf4j
}

Logback

// merge with common section above
dependencies {
constraints {
   // 1.4.x for slf4j 2.x & Jakarta EE 9+, 1.3.x for slf4j 2.x & Jakarta EE 8/Java EE 8, and 1.2.x for slf4j 1.7.x
   implementation("ch.qos.logback:logback-core:1.4.4")
   implementation("ch.qos.logback:logback-classic:1.4.4")
}

runtimeOnly("ch.qos.logback:logback-classic") // slf4j logging backend

 implementation("org.slf4j:jul-to-slf4j") // java.util.logging to slf4j, requires additional configuration, see https://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
 runtimeOnly("org.slf4j:jcl-over-slf4j") // commons-logging (JCL) to slf4j
 runtimeOnly("org.slf4j:log4j-over-slf4j") // log4j 1.2.x to slf4j
runtimeOnly("org.apache.logging.log4j:log4j-to-slf4j") // log4j 2.x to slf4j adapter
}

Apache Log4j 2.x with native bridges

dependencies {
// versions from platform/BOM
implementation("org.apache.logging.log4j:log4j-api")
runtimeOnly("org.apache.logging.log4j:log4j-core")
 runtimeOnly("org.apache.logging.log4j:log4j-slf4j2-impl") // for slf4j 1.7.x use log4j-slf4j-impl instead

runtimeOnly("org.apache.logging.log4j:log4j-jul") // java.util.logging to log4j 2.x adapter, requires additional configuration see https://logging.apache.org/log4j/2.x/log4j-jul/index.html
runtimeOnly("org.apache.logging.log4j:log4j-jcl") // commons-logging (JCL) to log4j 2.x bridge
runtimeOnly("org.apache.logging.log4j:log4j-1.2-api") // log4j 1.2.x to log4j 2.x bridge
}