Add Spring.Scheduling.Quartz4 for Quartz.NET 4.x alongside Spring.Scheduling.Quartz3

オープン
#388 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
25/100
issue の種類
機能追加
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
csharp
領域
backend, databases

調査の方向性

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.

索引モデルが issue の本文から書いたものです。

説明

New Feature

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. Quartz 4.7.1 ships only net10.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.Hosting and Quartz.Serialization.SystemTextJson are now part of Quartz. 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, targeting net10.0 only ($(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 XML type="..." references, and C# code that doesn't subclass the job contracts keeps compiling.
  • Sources:
    • The A and B types are compiled from Spring.Scheduling.Quartz3 by link, with a QUARTZ4 define for the signature differences (ValueTask and 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.
  • Central package management: Directory.Packages.props keeps Quartz at 3.22.9. The Quartz4 projects use <PackageReference Include="Quartz" VersionOverride="4.x" />. Check how Dependabot handles VersionOverride, and add a dependabot.yml rule 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:
    1. Supply Spring's provider with UsePersistentStore(s => s.UseConnectionProvider(...)) and UseAmbientTransactions() (the ExternalTransactionJobStore path), using a connection provider that hands out Spring's transaction-bound connection. Check how the store releases connections.
    2. A custom IJobStore built on DelegatingJobStore.
    3. Drop job-store transaction participation for 4.x and document it.
  • Configuration: move SchedulerFactoryObject to QuartzSchedulerBuilder. Keep QuartzProperties (flat keys), JobFactory, DbProvider, TaskExecutor, Triggers/JobDetails, AutoStartup/StartupDelay and WaitForJobsToCompleteOnShutdown, so XML configurations port with minimal edits. Drop SchedulerFactoryType in 4.x, unless there is a builder-level equivalent.

Work items

  • src/Spring/Spring.Scheduling.Quartz4 project (net10.0, VersionOverride, metadata, tags), added to Spring.Net.sln
  • Linked shared sources plus the QUARTZ4 signature differences
  • New SchedulerFactoryObject on QuartzSchedulerBuilder, with repository/exposure semantics on ISchedulerRepository
  • Job-store / Spring transaction bridge (see the options above)
  • IJobFactory port (JobScope) and the IThreadPool adapter
  • 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.md for 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 EnablePackageValidation off for it until 4.0.0 ships
  • build-support/build: add it to the packed modules in Build.cs, and confirm the test selection
  • BreakingChanges.txt / docs: the 3→4 differences, including ExecuteInternal's signature and the behaviour changes above
  • .github/dependabot.yml: rules for Quartz 3 vs 4

Open questions

  1. Ship in 4.0.0, or in a 4.x minor after 4.0?
  2. Linked sources with a QUARTZ4 define, or a full copy?
  3. How should the job store take part in Spring transactions on 4.x (options 1–3 above)?
  4. Should SchedulerFactoryObject stay property-bag compatible (QuartzProperties), or move to typed options as well?
  5. Should the README point users who don't need Spring-managed triggers or jobs to Quartz 4's native AddQuartz(...) hosting?
  6. Should Spring.Scheduling.Quartz3 be 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

主要言語
C#
スター
883
フォーク
374
平均マージ
2時間 48分
マージ済み PR(30日)
17

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

spring-projects/spring-net のほかの issue

spring-projects/spring-net の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。