A distributed task scheduling framework core library for Java applications
—
Enums, constants, and utility classes for job execution strategies, script types, system configuration, and helper functions.
Defines strategies for handling job execution when a job is already running.
/**
* Strategies for handling job execution blocking
* Determines behavior when job is triggered while already running
*/
public enum ExecutorBlockStrategyEnum {
/**
* Serial execution - wait for current job to finish before starting new one
*/
SERIAL_EXECUTION("Serial execution"),
/**
* Discard later - ignore new trigger if job is already running
*/
DISCARD_LATER("Discard Later"),
/**
* Cover early - stop current job and start new one
*/
COVER_EARLY("Cover Early");
/**
* Get human-readable title for the strategy
* @return Strategy description
*/
public String getTitle();
/**
* Match strategy by name with fallback
* @param name Strategy name to match
* @param defaultItem Default strategy if no match found
* @return Matched strategy or default
*/
public static ExecutorBlockStrategyEnum match(String name, ExecutorBlockStrategyEnum defaultItem);
}Usage Examples:
// Configure job with specific blocking strategy
@XxlJob("serialJob")
public void serialJobHandler() throws Exception {
// This job will use SERIAL_EXECUTION by default
// Configure via admin interface for other strategies
XxlJobHelper.log("Job started - will block concurrent executions");
// Long-running job logic
Thread.sleep(30000); // 30 seconds
XxlJobHelper.handleSuccess();
}
// Check blocking strategy programmatically
public void checkBlockingStrategy(String strategyName) {
ExecutorBlockStrategyEnum strategy = ExecutorBlockStrategyEnum.match(
strategyName,
ExecutorBlockStrategyEnum.SERIAL_EXECUTION
);
System.out.println("Using strategy: " + strategy.getTitle());
}Supported script types for dynamic job execution through the glue mechanism.
/**
* Supported script types for glue-based dynamic job execution
* Allows runtime job definition without redeployment
*/
public enum GlueTypeEnum {
/**
* Java bean method (default)
*/
BEAN("BEAN", false, null, null),
/**
* Embedded Java/Groovy code (not external script)
*/
GLUE_GROOVY("GLUE(Java)", false, null, null),
/**
* Shell script
*/
GLUE_SHELL("GLUE(Shell)", true, "bash", ".sh"),
/**
* Python script
*/
GLUE_PYTHON("GLUE(Python)", true, "python", ".py"),
/**
* PHP script
*/
GLUE_PHP("GLUE(PHP)", true, "php", ".php"),
/**
* Node.js script
*/
GLUE_NODEJS("GLUE(Nodejs)", true, "node", ".js"),
/**
* PowerShell script
*/
GLUE_POWERSHELL("GLUE(PowerShell)", true, "powershell", ".ps1");
/**
* Get human-readable description
* @return Script type description
*/
public String getDesc();
/**
* Check if this is a script type (vs bean type)
* @return true if script type, false for bean
*/
public boolean isScript();
/**
* Get command prefix for script execution
* @return Command to execute script or null for bean
*/
public String getCmd();
/**
* Get file extension for script type
* @return File extension or null for bean
*/
public String getSuffix();
/**
* Match glue type by name
* @param name Glue type name to match
* @return Matched glue type or null if not found
*/
public static GlueTypeEnum match(String name);
}Usage Examples:
// Check glue type capabilities
public void analyzeGlueType(String glueTypeName) {
GlueTypeEnum glueType = GlueTypeEnum.match(glueTypeName);
if (glueType != null) {
System.out.println("Type: " + glueType.getDesc());
System.out.println("Is Script: " + glueType.isScript());
if (glueType.isScript()) {
System.out.println("Command: " + glueType.getCmd());
System.out.println("File Extension: " + glueType.getSuffix());
}
}
}
// Example script content handling
public void prepareScriptExecution(GlueTypeEnum glueType, String scriptContent) {
if (glueType.isScript()) {
String filename = "job_script" + glueType.getSuffix();
String command = glueType.getCmd() + " " + filename;
// Write script to file and execute
writeScriptFile(filename, scriptContent);
executeCommand(command);
}
}Configuration constants and types for executor-admin registry communication.
/**
* Registry configuration constants and types
* Defines timeouts and registry types for executor-admin communication
*/
public class RegistryConfig {
/**
* Heartbeat timeout in seconds
* Time between heartbeat signals from executor to admin
*/
public static final int BEAT_TIMEOUT = 30;
/**
* Dead timeout in seconds (3 times heartbeat timeout)
* Time after which executor is considered dead if no heartbeat received
*/
public static final int DEAD_TIMEOUT = BEAT_TIMEOUT * 3;
/**
* Registry types for different components
*/
public enum RegistType {
/**
* Executor registration type
*/
EXECUTOR,
/**
* Admin server registration type
*/
ADMIN
}
}Usage Examples:
// Configure heartbeat monitoring
public class HeartbeatMonitor {
public void startMonitoring() {
int heartbeatInterval = RegistryConfig.BEAT_TIMEOUT * 1000; // Convert to milliseconds
int deadThreshold = RegistryConfig.DEAD_TIMEOUT * 1000;
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// Send heartbeat every BEAT_TIMEOUT seconds
scheduler.scheduleAtFixedRate(() -> {
sendHeartbeat();
}, 0, heartbeatInterval, TimeUnit.MILLISECONDS);
// Check for dead executors every DEAD_TIMEOUT seconds
scheduler.scheduleAtFixedRate(() -> {
checkDeadExecutors(deadThreshold);
}, deadThreshold, deadThreshold, TimeUnit.MILLISECONDS);
}
}
// Registry type usage
public void registerComponent(RegistryConfig.RegistType type, String key, String value) {
RegistryParam param = new RegistryParam(type.name(), key, value);
switch (type) {
case EXECUTOR:
System.out.println("Registering executor: " + key + " -> " + value);
break;
case ADMIN:
System.out.println("Registering admin: " + key + " -> " + value);
break;
}
}Factory for creating and managing glue-based job handlers with dynamic script execution.
/**
* Factory for creating glue job handlers
* Manages dynamic script compilation and execution
*/
public class GlueFactory {
/**
* Create glue job handler for given glue type and source
* @param glueType Glue type (BEAN, GLUE_GROOVY for embedded code, or script types like Shell, Python, etc.)
* @param glueSource Glue source code
* @return IJobHandler instance for glue execution
*/
public static IJobHandler getInstance(GlueTypeEnum glueType, String glueSource);
/**
* Refresh glue job handler cache
* Forces recompilation of script handlers
*/
public static void refreshInstance();
}File-based logging utilities for job execution with automatic rotation and cleanup.
/**
* File-based logging utilities for job execution
* Handles log file creation, rotation, and cleanup
*/
public class XxlJobFileAppender {
/**
* Initialize log path for job logging
* @param logPath Base directory for log files
*/
public static void initLogPath(String logPath);
/**
* Get current log base path
* @return Base directory for log files
*/
public static String getLogPath();
/**
* Get glue source code storage path
* @return Directory for storing glue scripts
*/
public static String getGlueSrcPath();
/**
* Generate log filename for specific job execution
* @param triggerDate Job trigger date
* @param logId Unique log identifier
* @return Generated log filename
*/
public static String makeLogFileName(Date triggerDate, long logId);
/**
* Append log content to job log file
* @param logFileName Target log file name
* @param appendLog Content to append
*/
public static void appendLog(String logFileName, String appendLog);
/**
* Read log content from specific line number
* @param logFileName Log file to read
* @param fromLineNum Starting line number (1-based)
* @return LogResult containing log content and metadata
*/
public static LogResult readLog(String logFileName, int fromLineNum);
/**
* Read all lines from log file
* @param logFile Log file to read
* @return Complete file content as string
*/
public static String readLines(File logFile);
}Usage Examples:
// Initialize logging system
XxlJobFileAppender.initLogPath("/var/log/xxl-job");
// Generate log filename
Date now = new Date();
long logId = 123456L;
String logFileName = XxlJobFileAppender.makeLogFileName(now, logId);
// Append to log
XxlJobFileAppender.appendLog(logFileName, "Job started at " + now);
XxlJobFileAppender.appendLog(logFileName, "Processing data...");
// Read log content
LogResult logResult = XxlJobFileAppender.readLog(logFileName, 1);
System.out.println("Log content: " + logResult.getLogContent());Date handling utilities for job scheduling and log management.
/**
* Date utility functions for job scheduling
*/
public class DateUtil {
// Standard date formatting and parsing utilities
// Implementation varies - check source for specific methods
}File operation utilities for log management and script handling.
/**
* File operation utilities
*/
public class FileUtil {
// File I/O operations, directory management
// Implementation varies - check source for specific methods
}JSON processing utilities using Google Gson for parameter serialization.
/**
* JSON processing utilities using Gson
*/
public class GsonTool {
// JSON serialization and deserialization methods
// Implementation varies - check source for specific methods
}Network IP address utilities for executor registration and communication.
/**
* Network IP address utilities
*/
public class IpUtil {
// IP address detection and validation methods
// Implementation varies - check source for specific methods
}Network communication utilities for HTTP client operations.
/**
* Network communication utilities
*/
public class NetUtil {
// HTTP client operations, network connectivity checks
// Implementation varies - check source for specific methods
}Script execution utilities for running glue scripts in various languages.
/**
* Script execution utilities for glue jobs
*/
public class ScriptUtil {
// Script execution, process management
// Implementation varies - check source for specific methods
}Exception handling utilities for error processing and logging.
/**
* Exception handling and stack trace utilities
*/
public class ThrowableUtil {
// Stack trace processing, exception formatting
// Implementation varies - check source for specific methods
}Remote communication utilities for admin-executor RPC operations.
/**
* Remote communication utilities for RPC operations
*/
public class XxlJobRemotingUtil {
// HTTP-based RPC communication, request/response handling
// Implementation varies - check source for specific methods
}// Recommended production timeouts
public class ProductionConfig {
// Heartbeat configuration
public static final int PRODUCTION_BEAT_TIMEOUT = 30; // seconds
public static final int PRODUCTION_DEAD_TIMEOUT = 90; // 3x heartbeat
// Log retention
public static final int PRODUCTION_LOG_RETENTION_DAYS = 7;
// Job execution timeouts
public static final int DEFAULT_JOB_TIMEOUT = 300; // 5 minutes
public static final int LONG_RUNNING_JOB_TIMEOUT = 3600; // 1 hour
// Blocking strategies by job type
public static final ExecutorBlockStrategyEnum CRITICAL_JOB_STRATEGY =
ExecutorBlockStrategyEnum.SERIAL_EXECUTION;
public static final ExecutorBlockStrategyEnum BATCH_JOB_STRATEGY =
ExecutorBlockStrategyEnum.DISCARD_LATER;
public static final ExecutorBlockStrategyEnum REAL_TIME_JOB_STRATEGY =
ExecutorBlockStrategyEnum.COVER_EARLY;
}@Configuration
public class EnvironmentJobConfig {
@Value("${environment:development}")
private String environment;
@Bean
public ExecutorBlockStrategyEnum defaultBlockingStrategy() {
switch (environment.toLowerCase()) {
case "production":
return ExecutorBlockStrategyEnum.SERIAL_EXECUTION;
case "staging":
return ExecutorBlockStrategyEnum.DISCARD_LATER;
case "development":
default:
return ExecutorBlockStrategyEnum.COVER_EARLY;
}
}
@Bean
public int logRetentionDays() {
switch (environment.toLowerCase()) {
case "production":
return 30;
case "staging":
return 7;
case "development":
default:
return 3;
}
}
}public class GlueScriptManager {
public void deployScript(String jobHandler, GlueTypeEnum glueType, String scriptContent) {
// Validate script type
if (!glueType.isScript()) {
throw new IllegalArgumentException("Only script types allowed");
}
// Create script file
String filename = jobHandler + glueType.getSuffix();
String scriptPath = XxlJobFileAppender.getGlueSrcPath() + "/" + filename;
try {
// Write script to file
Files.write(Paths.get(scriptPath), scriptContent.getBytes());
// Set executable permissions for shell scripts
if (glueType == GlueTypeEnum.GLUE_SHELL) {
File scriptFile = new File(scriptPath);
scriptFile.setExecutable(true);
}
// Refresh glue factory to pick up changes
GlueFactory.refreshInstance();
System.out.println("Script deployed: " + filename);
} catch (IOException e) {
throw new RuntimeException("Failed to deploy script: " + e.getMessage(), e);
}
}
public void validateScript(GlueTypeEnum glueType, String scriptContent) {
switch (glueType) {
case GLUE_GROOVY:
// GLUE_GROOVY is embedded Java/Groovy code, not an external script
validateGroovyCode(scriptContent);
break;
case GLUE_SHELL:
validateShellScript(scriptContent);
break;
case GLUE_PYTHON:
validatePythonScript(scriptContent);
break;
default:
// Basic syntax check for other types
if (scriptContent == null || scriptContent.trim().isEmpty()) {
throw new IllegalArgumentException("Script content cannot be empty");
}
}
}
}Install with Tessl CLI
npx tessl i tessl/maven-com-xuxueli--xxl-job-core