Add Spring.Scheduling.Quartz4 for Quartz.NET 4.x alongside Spring.Scheduling.Quartz3
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 25/100
Línea de trabajo
Start with the Quartz 4 migration guide linked in the issue and inspect src/Spring/Spring.Scheduling.Quartz3 alongside the project, build, and test configuration named in the work items. The issue identifies the required package, compatibility changes, and test areas, but leaves transaction design, source sharing, and configuration choices open. Done means a net10.0 Quartz 4 package, working transaction and scheduler integration, tests, example, documentation, and build support.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
Add a Spring.Scheduling.Quartz4 package for Quartz.NET 4.x, shipped alongside the existing Spring.Scheduling.Quartz3. Quartz 4 isn't a drop-in upgrade for the current integration. It changes the job and job-factory contracts. It also removes StdSchedulerFactory and the process-wide singletons that SchedulerFactoryObject is built on, and it no longer supports subclassing the ADO.NET job stores, which LocalDataSourceJobStore relies on. So it needs its own package. Spring.Scheduling.Quartz3 stays for 3.x users, and Quartz 3.x is still maintained.
Quartz.NET 4.x facts
- Releases. 4.0.0 through 4.7.1 are on nuget.org; 4.7.1 is the latest. 3.x is still maintained: 3.22.9 shipped on 2026-10-26, and recent 3.x patches come out alongside 4.x releases.
- Target framework.
Quartz4.7.1 ships onlynet10.0: no netstandard2.0 and no .NET Framework. 3.22.9 ships net462, net472, netstandard2.0, net8.0, net9.0 and net10.0. - Dependencies. 4.x depends on
Microsoft.Extensions.*10.0.0: DependencyInjection, Hosting.Abstractions, Logging.Abstractions, Options.ConfigurationExtensions, Configuration.Binder and Diagnostics.HealthChecks. That's fine for a net10.0-only package. Spring's own floors stay at 8.0.x. - Merged packages.
Quartz.Extensions.DependencyInjection,Quartz.Extensions.HostingandQuartz.Serialization.SystemTextJsonare now part ofQuartz. One assembly can't reference Quartz 3 and Quartz 4 at once. - Migration guide. All of the points above come from it:
docs/documentation/quartz-4.x/migration-guide.md@ v4.7.1.
What changes for the Spring integration
The code is in src/Spring/Spring.Scheduling.Quartz3, namespace Spring.Scheduling.Quartz. Each type is marked A (compiles unchanged), B (mechanical change) or C (design change).
| Spring type | Quartz 4 change | Class |
|---|---|---|
SchedulerFactoryObject |
StdSchedulerFactory and its 47 constants are gone. The replacement is QuartzSchedulerBuilder.UseProperties(...) / BuildScheduler(). Flat quartz.* keys still work, but a key that names a component by type is refused unless QuartzLegacyComponentKeysSupport is on. SchedulerRepository.Instance and DBConnectionManager.Instance are gone, replaced by an ISchedulerRepository and an IDbProvider resolved from the container. Today Spring uses these for the "already registered" check and for ExposeSchedulerInRepository, and it hands the [ThreadStatic] ConfigTimeDbProvider over at config time. The SchedulerFactoryType property ("any ISchedulerFactory") no longer maps to anything. |
C |
LocalDataSourceJobStore (derives from JobStoreCMT) and SpringDbProviderAdapter |
JobStoreCMT is now ExternalTransactionJobStore, and subclassing the ADO.NET stores to change transaction handling is unsupported. The guide says "implement IJobStore" for that. The overrides that join Spring-managed transactions through ConnectionUtils (GetNonManagedTXConnection and CloseConnection) have no 4.x hook. This is the hardest item. |
C |
AdaptableJobFactory, SpringObjectJobFactory |
IJobFactory.NewJob(...) / ReturnJob(IJob) becomes ValueTask<JobScope> CreateJob(bundle, scheduler, ct) / ReturnJob(JobScope, ct). |
C |
LocalTaskExecutorThreadPool |
IThreadPool now runs ValueTask delegates and takes a CancellationToken. It's registered with UseThreadPool(...). |
B/C |
QuartzJobObject, DelegatingJob, MethodInvokingJob, StatefulMethodInvokingJob |
Task Execute(IJobExecutionContext) becomes ValueTask Execute(IJobExecutionContext, CancellationToken). QuartzJobObject.ExecuteInternal is the extension point users override, so its signature changes are source-breaking for subclasses. |
B |
CronTriggerObject, SimpleTriggerObject |
The misfire instruction int constants become per-trigger enums (CronTriggerMisfireInstruction and others). Spring maps MisfireInstructionName through reflection over the old constants, so that mapping has to be rewritten. There are also behaviour changes, such as cron day-field and DST semantics and an inclusive EndTime for simple triggers; document them, don't paper over them. |
B |
JobDetailObject, MethodInvokingJobDetailFactoryObject |
They use JobDetailImpl and JobKey, which are still there. Check that the setters Spring uses survive. |
B (to verify) |
SchedulerAccessor, SchedulerAccessorObject |
Calls move to the ValueTask / CancellationToken overloads. Check the XMLSchedulingDataProcessor usage against 4.x. |
B (to verify) |
ITaskExecutor, IThreadRunnable, MethodInvokingRunnable, SchedulingException, TaskRejectedException, IJobDetailAwareTrigger, ISchedulerContextAware |
Spring-owned types with no Quartz 4 impact, apart from ISchedulerContextAware, which is still there. |
A |
Logging and serialization don't affect Spring's code. Quartz 4 logs through Microsoft.Extensions.Logging, and Spring doesn't wire Quartz's logging. Spring's Quartz types aren't [Serializable]. Users still have to follow Quartz's data migration: the 3.x→4.x schema script is mandatory, and 4.x can't read BinaryFormatter-serialized job data. The package README should link to that, not repeat it.
Proposal
- Package and assembly:
Spring.Scheduling.Quartz4, targetingnet10.0only ($(TargetModernFrameworkVersion)). No other target is possible. - Namespace: keep
Spring.Scheduling.Quartz. The Quartz 2→3 move set the precedent: users switching packages change the assembly name in assembly-qualified XMLtype="..."references, and C# code that doesn't subclass the job contracts keeps compiling. - Sources:
- The A and B types are compiled from
Spring.Scheduling.Quartz3by link, with aQUARTZ4define for the signature differences (ValueTaskand cancellation tokens). SchedulerFactoryObject, the job-store bridge, the job factory and the thread pool get Quartz4-only files, because they differ too much for#if.- The alternative is a full copy. That's simpler to reason about, but it doubles maintenance of the shared types.
- The A and B types are compiled from
- Central package management:
Directory.Packages.propskeepsQuartzat 3.22.9. The Quartz4 projects use<PackageReference Include="Quartz" VersionOverride="4.x" />. Check how Dependabot handlesVersionOverride, and add adependabot.ymlrule so that a Quartz 4 bump is never proposed for the Quartz 3 projects. - Transactions: redesign Spring transaction participation for 4.x. Options, in order of preference:
- Supply Spring's provider with
UsePersistentStore(s => s.UseConnectionProvider(...))andUseAmbientTransactions()(theExternalTransactionJobStorepath), using a connection provider that hands out Spring's transaction-bound connection. Check how the store releases connections. - A custom
IJobStorebuilt onDelegatingJobStore. - Drop job-store transaction participation for 4.x and document it.
- Supply Spring's provider with
- Configuration: move
SchedulerFactoryObjecttoQuartzSchedulerBuilder. KeepQuartzProperties(flat keys),JobFactory,DbProvider,TaskExecutor,Triggers/JobDetails,AutoStartup/StartupDelayandWaitForJobsToCompleteOnShutdown, so XML configurations port with minimal edits. DropSchedulerFactoryTypein 4.x, unless there is a builder-level equivalent.
Work items
-
src/Spring/Spring.Scheduling.Quartz4project (net10.0,VersionOverride, metadata, tags), added toSpring.Net.sln - Linked shared sources plus the
QUARTZ4signature differences - New
SchedulerFactoryObjectonQuartzSchedulerBuilder, with repository/exposure semantics onISchedulerRepository - Job-store / Spring transaction bridge (see the options above)
-
IJobFactoryport (JobScope) and theIThreadPooladapter - Misfire-instruction mapping onto the 4.x enums
-
test/Spring/Spring.Scheduling.Quartz4.Tests(net10.0), linking the shared Quartz3 tests, with 4.x-specific factory and job-store tests; integration tests against SQL Server with the 4.x schema - Example: a Quartz 4 variant of
examples/Spring/Spring.Scheduling.Quartz.Example -
README.mdfor the package, including links to Quartz's 3→4 migration guide and the schema script - Package validation: there is no 3.1.0 baseline for a new package, so turn
EnablePackageValidationoff for it until 4.0.0 ships -
build-support/build: add it to the packed modules inBuild.cs, and confirm the test selection -
BreakingChanges.txt/ docs: the 3→4 differences, includingExecuteInternal's signature and the behaviour changes above -
.github/dependabot.yml: rules for Quartz 3 vs 4
Open questions
- Ship in 4.0.0, or in a 4.x minor after 4.0?
- Linked sources with a
QUARTZ4define, or a full copy? - How should the job store take part in Spring transactions on 4.x (options 1–3 above)?
- Should
SchedulerFactoryObjectstay property-bag compatible (QuartzProperties), or move to typed options as well? - Should the README point users who don't need Spring-managed triggers or jobs to Quartz 4's native
AddQuartz(...)hosting? - Should
Spring.Scheduling.Quartz3be marked as maintenance-only once this ships?
Related: #297 / #298 (the earlier break in Quartz 3.12, from the SchedulerRepository change).
🤖 Generated with Claude Code
- Lenguaje dominante
- C#
- Estrellas
- 883
- Forks
- 374
- Merge medio
- 2 h 48 min
- PR fusionados (30 d)
- 17
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de spring-projects/spring-net
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
spring-projects/spring-net#218 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
spring-projects/spring-net#196 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
spring-projects/spring-net#189 · 16 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 25/100
spring-projects/spring-net#163 · 2 reacciones ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 10/100
spring-projects/spring-net#144 · 99 comentarios · 13 reacciones ·
Los mantenedores suelen responder en 1 día
Todos los issues de spring-projects/spring-net
Issues similares
-
ci-flake kind:tests size:S type:bug
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
elsa-workflows/elsa-foundation#4058 · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
games-on-whales/wolf-ui#23 ·
-
SkillsAbiertowayfinder:grilling
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
DigiBanks99/lopen#37 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
sebastienros/fluid#1273 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día