From e9786e6df83ddde2ade476f01a354c20b6ac8de9 Mon Sep 17 00:00:00 2001 From: sywu14 Date: Sun, 24 May 2026 10:25:43 +0800 Subject: [PATCH] fix(core): refresh callbackLogPath in initLogPath (#3959) initLogPath updates logBasePath and glueSrcPath when a custom log path is supplied, but callbackLogPath keeps its build-time default (/data/applogs/xxl-job/jobhandler/callbacklogs). As a result, TriggerCallbackThread writes callback retry logs to the hard-coded path instead of the user-configured one, and offline callback files are never picked up after restart. Refresh callbackLogPath together with logBasePath/glueSrcPath, and add a regression test under xxl-job-core covering both paths. Assisted-by: Claude Code --- xxl-job-core/pom.xml | 7 +++ .../xxl/job/core/log/XxlJobFileAppender.java | 5 ++ .../job/core/log/XxlJobFileAppenderTest.java | 55 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 xxl-job-core/src/test/java/com/xxl/job/core/log/XxlJobFileAppenderTest.java diff --git a/xxl-job-core/pom.xml b/xxl-job-core/pom.xml index cb1620d1..82b23692 100644 --- a/xxl-job-core/pom.xml +++ b/xxl-job-core/pom.xml @@ -59,6 +59,13 @@ provided + + + org.junit.jupiter + junit-jupiter-engine + test + + \ No newline at end of file diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java b/xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java index 34263b31..b1b9f4a8 100644 --- a/xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java +++ b/xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java @@ -50,6 +50,11 @@ public class XxlJobFileAppender { File glueBaseDir = new File(logPathDir, "gluesource"); FileTool.createDirectories(glueBaseDir); glueSrcPath = glueBaseDir.getPath(); + + // mk callback log dir + File callbackBaseDir = new File(logPathDir, "callbacklogs"); + FileTool.createDirectories(callbackBaseDir); + callbackLogPath = callbackBaseDir.getPath(); } public static String getLogPath() { return logBasePath; diff --git a/xxl-job-core/src/test/java/com/xxl/job/core/log/XxlJobFileAppenderTest.java b/xxl-job-core/src/test/java/com/xxl/job/core/log/XxlJobFileAppenderTest.java new file mode 100644 index 00000000..0ea197ff --- /dev/null +++ b/xxl-job-core/src/test/java/com/xxl/job/core/log/XxlJobFileAppenderTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 1999-2026 xuxueli.com + * + * Licensed 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 com.xxl.job.core.log; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Regression test for issue #3959: + * initLogPath should refresh callbackLogPath together with logBasePath and glueSrcPath. + */ +class XxlJobFileAppenderTest { + + @Test + void initLogPath_shouldRefreshCallbackLogPathRelativeToCustomLogBase(@TempDir Path tempDir) throws IOException { + String customLogPath = tempDir.toFile().getPath(); + + XxlJobFileAppender.initLogPath(customLogPath); + + File expectedCallbackDir = new File(customLogPath, "callbacklogs"); + assertEquals(expectedCallbackDir.getPath(), XxlJobFileAppender.getCallbackLogPath(), + "callbackLogPath should sit under the user-supplied logPath after initLogPath"); + } + + @Test + void initLogPath_shouldRefreshGlueSrcPathRelativeToCustomLogBase(@TempDir Path tempDir) throws IOException { + String customLogPath = tempDir.toFile().getPath(); + + XxlJobFileAppender.initLogPath(customLogPath); + + File expectedGlueDir = new File(customLogPath, "gluesource"); + assertEquals(expectedGlueDir.getPath(), XxlJobFileAppender.getGlueSrcPath()); + assertTrue(expectedGlueDir.exists(), "gluesource directory should be created under custom logPath"); + } +}