This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/2.x by this push:
new 619debb4e9 Improve logging for `LinkageError` scenarios involving the
LMAX Disruptor library (#4124)
619debb4e9 is described below
commit 619debb4e96c0d85508525a6a25f2c26b98d2349
Author: Ramanathan <[email protected]>
AuthorDate: Fri May 29 16:54:39 2026 +0530
Improve logging for `LinkageError` scenarios involving the LMAX Disruptor
library (#4124)
Co-authored-by: Volkan Yazıcı <[email protected]>
---
.../log4j/core/async/DisruptorUtilTest.java | 63 ++++++++++++++++++++++
.../logging/log4j/core/async/DisruptorUtil.java | 10 ++--
.../fix-log-disruptor-initialization-errors.xml | 13 +++++
3 files changed, 83 insertions(+), 3 deletions(-)
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/DisruptorUtilTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/DisruptorUtilTest.java
new file mode 100644
index 0000000000..4bd1048715
--- /dev/null
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/DisruptorUtilTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.core.async;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.status.StatusData;
+import org.apache.logging.log4j.test.ListStatusListener;
+import org.apache.logging.log4j.test.junit.UsingStatusListener;
+import org.junit.jupiter.api.Test;
+
+@UsingStatusListener
+class DisruptorUtilTest {
+
+ @Test
+ void detectDisruptorMajorVersion_returnsValidVersion() throws Exception {
+ final Method method =
DisruptorUtil.class.getDeclaredMethod("detectDisruptorMajorVersion");
+ method.setAccessible(true);
+ final int detectedVersion = (int) method.invoke(null);
+
+ assertThat(detectedVersion).isIn(3, 4);
+ }
+
+ @Test
+ void detectDisruptorMajorVersion_logsVersionDetection(final
ListStatusListener statusListener) throws Exception {
+ final Method method =
DisruptorUtil.class.getDeclaredMethod("detectDisruptorMajorVersion");
+ method.setAccessible(true);
+ final int detectedVersion = (int) method.invoke(null);
+
+ final List<StatusData> debugData =
+
statusListener.findStatusData(Level.DEBUG).collect(Collectors.toList());
+
+ if (detectedVersion == 4) {
+ // v4 path: ClassNotFoundException caught, falls through to
LOGGER.debug()
+ assertThat(debugData)
+ .anySatisfy(data ->
assertThat(data.getMessage().getFormattedMessage())
+ .contains("LMAX Disruptor version detected: 4"));
+ } else {
+ // v3 path: early `return 3` inside try — LOGGER.debug() is never
reached
+ assertThat(debugData)
+ .noneSatisfy(data ->
assertThat(data.getMessage().getFormattedMessage())
+ .contains("LMAX Disruptor version detected:"));
+ }
+ }
+}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
index f115e2ae37..11479928f6 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/DisruptorUtil.java
@@ -55,13 +55,17 @@ final class DisruptorUtil {
// TODO: replace with LoaderUtil.isClassAvailable() when TCCL is removed
// See: https://github.com/apache/logging-log4j2/issues/3706
private static int detectDisruptorMajorVersion() {
+ int version = 4;
try {
Class.forName(
- "com.lmax.disruptor.SequenceReportingEventHandler", true,
DisruptorUtil.class.getClassLoader());
+ "com.lmax.disruptor.SequenceReportingEventHandler", false,
DisruptorUtil.class.getClassLoader());
+ version = 3;
return 3;
- } catch (final ClassNotFoundException e) {
- return 4;
+ } catch (final ClassNotFoundException ignored) {
+ // Do nothing
}
+ LOGGER.debug("LMAX Disruptor version detected: {}", version);
+ return version;
}
private DisruptorUtil() {}
diff --git a/src/changelog/.2.x.x/fix-log-disruptor-initialization-errors.xml
b/src/changelog/.2.x.x/fix-log-disruptor-initialization-errors.xml
new file mode 100644
index 0000000000..c47b11fb80
--- /dev/null
+++ b/src/changelog/.2.x.x/fix-log-disruptor-initialization-errors.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+ type="changed">
+ <issue id="3176"
link="https://github.com/apache/logging-log4j2/issues/2250"/>
+ <issue id="3176"
link="https://github.com/apache/logging-log4j2/pull/4124"/>
+ <description format="asciidoc">
+ Improve logging for `LinkageError` scenarios involving the LMAX
Disruptor library
+ </description>
+</entry>