Description
Problem Description
JarUploadService.uploadJar checks for a duplicate job name, then stores the file at {jarDir}/{jobName}-{version}.jar with REPLACE_EXISTING, and only then inserts the definition. Two concurrent uploads with the same job name and version both pass the duplicate check. If the losing request writes its file after the winner, it overwrites the winner's JAR, then fails on the uk_job_name unique key with DuplicateJobDefinitionException. The winner's definition keeps the checksum of its own JAR, but the file on disk now holds the other upload's bytes, so the integrity check fails when the plugin loads.
Proposed Solution
Store new uploads without overwriting an existing file, as storeReplacementJar already does: write to a unique file name and fail instead of replacing. When the insert fails as a duplicate, delete only the file this request wrote.
Acceptance Criteria
- An upload never overwrites a JAR file that another definition references.
- A duplicate upload that loses the race leaves no file of its own on disk.
- A test covers a duplicate rejected by the unique key after the file was stored, and asserts that the other definition's JAR is unchanged.
Affected Area
Plugin lifecycle: JAR upload
Out of Scope
- Changing the duplicate rule (one definition per job name).
Additional Context
Follow-up to #108 / PR #113, which introduced unique file names for replacement JARs.
Activity