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 752d023795 Fix header write in `RollingRandomAccessFileManager` (#4008)
752d023795 is described below

commit 752d023795fc518a38ecae73bb6455e2723cecea
Author: NeatGuyCoding <[email protected]>
AuthorDate: Wed Dec 31 00:26:56 2025 +0800

    Fix header write in `RollingRandomAccessFileManager` (#4008)
    
    Co-authored-by: Volkan Yazıcı <[email protected]>
---
 .../RollingRandomAccessFileManagerTest.java        | 63 ++++++++++++++++++++++
 .../rolling/RollingRandomAccessFileManager.java    |  4 +-
 ..._RollingRandomAccessFileManager_writeHeader.xml | 12 +++++
 3 files changed, 78 insertions(+), 1 deletion(-)

diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
index 5937242be6..ab97d7b5ab 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
@@ -41,11 +41,14 @@ import java.nio.file.attribute.PosixFilePermissions;
 import java.util.Set;
 import java.util.concurrent.locks.LockSupport;
 import org.apache.logging.log4j.core.config.DefaultConfiguration;
+import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.util.Closer;
 import org.apache.logging.log4j.core.util.FileUtils;
 import org.apache.logging.log4j.core.util.NullOutputStream;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
 
 /**
  * Tests the RollingRandomAccessFileManager class.
@@ -333,4 +336,64 @@ class RollingRandomAccessFileManagerTest {
                 .permissions();
         assertEquals(filePermissions, actualFilePermissions);
     }
+
+    @ParameterizedTest
+    @CsvSource({
+        "true,true",
+        "true,false",
+        "false,true",
+        "false,false",
+    })
+    void testWriteHeaderWhetherAppendOrExists(final boolean append, final 
boolean fileExists) throws Exception {
+        final File file = File.createTempFile("log4j2", "test");
+        if (!fileExists) {
+            file.delete(); // Ensure file doesn't exist
+        } else {
+            // If file exists, write some content to it so it's not empty
+            try (FileOutputStream fos = new FileOutputStream(file)) {
+                fos.write("EXISTING_CONTENT".getBytes());
+            }
+        }
+        file.deleteOnExit();
+
+        final String header = "HEADER";
+        final PatternLayout layout =
+                PatternLayout.newBuilder().setHeader(header).build();
+
+        final RollingRandomAccessFileManager manager = 
RollingRandomAccessFileManager.getRollingRandomAccessFileManager(
+                file.getAbsolutePath(),
+                Strings.EMPTY,
+                append,
+                true,
+                RollingRandomAccessFileManager.DEFAULT_BUFFER_SIZE,
+                new SizeBasedTriggeringPolicy(Long.MAX_VALUE),
+                null,
+                null,
+                layout,
+                null,
+                null,
+                null,
+                null);
+        assertNotNull(manager);
+        manager.close();
+
+        // Verify header was written based on logic: writeHeader = !append || 
!fileExistedBefore
+        // Note: writeHeader() also checks file.length() == 0, so header is 
only written if file is empty
+        assertTrue(file.exists(), "File should exist");
+        final byte[] fileContent = Files.readAllBytes(file.toPath());
+        final String content = new String(fileContent);
+        final boolean expectedHeaderWritten = !append || !fileExists;
+        if (expectedHeaderWritten) {
+            assertTrue(
+                    content.startsWith(header),
+                    "File should start with header when append=" + append + ", 
fileExists=" + fileExists + ", content: "
+                            + content);
+        } else {
+            // When append=true and fileExists=true, file has existing 
content, so header should not be written
+            assertTrue(
+                    !content.startsWith(header),
+                    "File should not start with header when append=" + append 
+ ", fileExists=" + fileExists
+                            + ", content: " + content);
+        }
+    }
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
index 1c0a0241fe..abb50f587f 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManager.java
@@ -174,8 +174,10 @@ public class RollingRandomAccessFileManager extends 
RollingFileManager {
                             long size = 0;
                             long time = System.currentTimeMillis();
                             RandomAccessFile raf = null;
+                            boolean fileExistedBefore = false;
                             if (fileName != null) {
                                 file = new File(name);
+                                fileExistedBefore = file.exists();
 
                                 if (!append) {
                                     file.delete();
@@ -207,7 +209,7 @@ public class RollingRandomAccessFileManager extends 
RollingFileManager {
                                     return null;
                                 }
                             }
-                            final boolean writeHeader = !append || file == 
null || !file.exists();
+                            final boolean writeHeader = !append || file == 
null || !fileExistedBefore;
 
                             final RollingRandomAccessFileManager rrm = new 
RollingRandomAccessFileManager(
                                     data.getLoggerContext(),
diff --git 
a/src/changelog/.2.x.x/fix_RollingRandomAccessFileManager_writeHeader.xml 
b/src/changelog/.2.x.x/fix_RollingRandomAccessFileManager_writeHeader.xml
new file mode 100644
index 0000000000..a23c6497f9
--- /dev/null
+++ b/src/changelog/.2.x.x/fix_RollingRandomAccessFileManager_writeHeader.xml
@@ -0,0 +1,12 @@
+<?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="fixed">
+  <description format="asciidoc">
+    Fix header write in `RollingRandomAccessFileManager` that was being 
incorrectly skipped if `append=true` and the file didn't exist before.
+  </description>
+</entry>
+

Reply via email to