{"record":{"id":"eff482ba909886d7","repo":"jeecgboot/JeecgBoot","slug":"support-for-specifying-l-with-other-days-of-the","errorCode":null,"errorMessage":"Support for specifying 'L' with other days of the week is not implemented","messagePattern":"Support for specifying 'L' with other days of the week is not implemented","errorType":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java","lineNumber":491,"sourceCode":"            if (years == null) {\n                years = new TreeSet<>();\n            }\n\n            int exprOn = SECOND;\n\n            StringTokenizer exprsTok = new StringTokenizer(expression, \" \\t\",\n                    false);\n\n            if(exprsTok.countTokens() > 7) {\n                throw new ParseException(\"Invalid expression has too many terms: \" + expression, -1);\n            }\n\n            while (exprsTok.hasMoreTokens() && exprOn <= YEAR) {\n                String expr = exprsTok.nextToken().trim();\n\n                // throw an exception if L is used with other days of the week\n                if(exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1  && expr.contains(\",\")) {\n                    throw new ParseException(\"Support for specifying 'L' with other days of the week is not implemented\", -1);\n                }\n                if(exprOn == DAY_OF_WEEK && expr.indexOf('#') != -1 && expr.indexOf('#', expr.indexOf('#') +1) != -1) {\n                    throw new ParseException(\"Support for specifying multiple \\\"nth\\\" days is not implemented.\", -1);\n                }\n\n                StringTokenizer vTok = new StringTokenizer(expr, \",\");\n                while (vTok.hasMoreTokens()) {\n                    String v = vTok.nextToken();\n                    storeExpressionVals(0, v, exprOn);\n                }\n\n                exprOn++;\n            }\n\n            if (exprOn <= DAY_OF_WEEK) {\n                throw new ParseException(\"Unexpected end of expression.\",\n                        expression.length());\n            }","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-server-cloud/jeecg-visual/jeecg-cloud-xxljob/src/main/java/com/xxl/job/admin/business/scheduler/cron/CronExpression.java#L473-L509","documentation":"Thrown by CronExpression's parser when the day-of-week field contains 'L' (last weekday of month) combined with other days using commas — e.g., 'FRI,L' or '1,L'. Quartz supports 'L' as a standalone modifier meaning 'last <day> of the month' (e.g., '6L' = last Friday), but mixing it with additional days in a comma-separated list is not implemented. This is a parser-level limitation, not a configurable behavior.","triggerScenarios":"Cron expression with day-of-week field like 'MON,TUE,L' or '1,2,L' intending 'Mondays, Tuesdays, and last day-of-week of month'. Expression like '6L,FRI' trying to say 'last Friday and every Friday'. Using 'L' as shorthand for 'last day of any week' combined with specific days.","commonSituations":"Writing complex scheduling rules that need both recurring weekdays and the last occurrence of a weekday. Misunderstanding 'L' semantics — thinking it means 'last day of month' generically rather than modifying the specific day it's attached to. Attempting to combine end-of-month logic with regular weekly schedules in a single expression.","solutions":["Split the schedule into multiple triggers/jobs: one for the recurring days and a separate one for the 'L' (last weekday) rule.","If you need 'last Friday of every month', use '6L' alone in the day-of-week field: '0 0 12 ? * 6L'.","If you need every Monday, use 'MON' or '2' alone: '0 0 12 ? * 2'.","Combine multiple CronTriggers in the scheduler for the same job rather than trying to express everything in one cron string."],"exampleFix":"// before: invalid — mixing L with other days\nString cron = \"0 0 12 ? * 2,6L\"; // Monday + last Friday\nCronExpression expr = new CronExpression(cron);\n\n// after: use two separate triggers for the same job\n// Trigger 1: every Monday\nCronTrigger monday = TriggerBuilder.newTrigger()\n    .withSchedule(CronScheduleBuilder.cronSchedule(\"0 0 12 ? * 2\"))\n    .build();\n// Trigger 2: last Friday of month\nCronTrigger lastFriday = TriggerBuilder.newTrigger()\n    .withSchedule(CronScheduleBuilder.cronSchedule(\"0 0 12 ? * 6L\"))\n    .build();\nscheduler.scheduleJob(jobDetail, monday);\nscheduler.scheduleJob(jobDetail, lastFriday);","handlingStrategy":"validation","validationCode":"// Pre-validate day-of-week field for L+comma conflict\npublic void validateDayOfWeekField(String cronExpression) {\n    String[] fields = cronExpression.trim().split(\"\\\\s+\");\n    if (fields.length >= 6) {\n        String dayOfWeek = fields[5];\n        if (dayOfWeek.contains(\"L\") && dayOfWeek.contains(\",\")) {\n            throw new IllegalArgumentException(\n                \"Cannot combine 'L' with other days in day-of-week: \" + dayOfWeek);\n        }\n    }\n}","typeGuard":"// Check if day-of-week field is valid for Quartz\npublic boolean isValidDayOfWeek(String dow) {\n    if (dow == null || dow.isEmpty()) return false;\n    if (dow.contains(\"L\") && dow.contains(\",\")) return false;\n    return true;\n}","tryCatchPattern":"try {\n    CronExpression cron = new CronExpression(expression);\n} catch (ParseException e) {\n    if (e.getMessage().contains(\"'L' with other days\")) {\n        // Suggest splitting into multiple triggers\n        throw new IllegalArgumentException(\n            \"Cannot combine 'L' with comma-separated days. Use separate triggers for each rule.\", e);\n    }\n    throw e;\n}","preventionTips":["Use 'L' only as a standalone day-of-week modifier (e.g., '6L' for last Friday).","Never combine 'L' with additional days using commas — split into multiple triggers instead.","Provide a cron expression builder UI that prevents invalid combinations.","Document Quartz cron syntax differences from Unix cron for your team."],"tags":["cron","quartz","scheduling","xxl-job","day-of-week"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}