Skip to content

Conditionally disable dependencyLock.disableGlobalLock#285

Merged
OdysseusLives merged 5 commits intonebula-plugins:mainfrom
wisechengyi:main
Nov 20, 2025
Merged

Conditionally disable dependencyLock.disableGlobalLock#285
OdysseusLives merged 5 commits intonebula-plugins:mainfrom
wisechengyi:main

Conversation

@wisechengyi
Copy link
Collaborator

@wisechengyi wisechengyi commented Nov 18, 2025

Conditionally Disable Global Lock Feature

Overview

This document describes the dependencyLock.disableGlobalLock property that can be used to disable global lock functionality and avoid concurrency issues in parallel builds.

Problem

The global lock feature (generateGlobalLock, updateGlobalLock, saveGlobalLock) can cause ConcurrentModificationException when:

  • Multiple subproject tasks run in parallel
  • Tasks access the root project's task collection during execution
  • Lazy task realization triggers concurrent configuration creation

This happens even when global lock tasks are not scheduled to run.

Solution

A new Gradle property dependencyLock.disableGlobalLock has been introduced to completely disable the global lock feature.

Usage

Option 1: Via gradle.properties

Add to your project's gradle.properties file:

dependencyLock.disableGlobalLock=true

Option 2: Via Command Line

Pass the property when running Gradle commands:

./gradlew build -PdependencyLock.disableGlobalLock=true

Option 3: Via ~/.gradle/gradle.properties

Add to your global Gradle properties file for all projects:

dependencyLock.disableGlobalLock=true

What Gets Disabled

When dependencyLock.disableGlobalLock=true is set:

  1. Tasks NOT created:

    • generateGlobalLock - Generate global lock file
    • updateGlobalLock - Update existing global lock file
    • saveGlobalLock - Save global lock to project directory
    • deleteGlobalLock - Delete global lock file
  2. Validations skipped:

    • saveLock tasks no longer check for global lock file existence
    • No concurrent access to root project's task collection
  3. What still works:

    • generateLock - Generate individual project lock files
    • updateLock - Update individual project lock files
    • saveLock - Save individual project lock files
    • deleteLock - Delete individual project lock files
    • All other dependency locking features

Implementation Details

Code Changes

1. New Property Constant (DependencyLockPlugin.kt)

const val DISABLE_GLOBAL_LOCK = "dependencyLock.disableGlobalLock"

2. Helper Method (DependencyLockTaskConfigurer.groovy)

private boolean isGlobalLockDisabled() {
    return project.hasProperty(DependencyLockPlugin.DISABLE_GLOBAL_LOCK) &&
           Boolean.parseBoolean(project.property(DependencyLockPlugin.DISABLE_GLOBAL_LOCK) as String)
}

3. Conditional Task Creation

// configure global lock only on rootProject (unless disabled via property)
if (project == project.rootProject && !isGlobalLockDisabled()) {
    // Create global lock tasks
}

4. Early Return in Validation

saveTask.doFirst {
    // Skip global lock check if global locks are disabled
    if (isGlobalLockDisabled()) {
        return
    }
    // Validation logic...
}

Benefits

  • ✅ Prevents ConcurrentModificationException in parallel builds
  • ✅ Eliminates unnecessary task creation for unused features
  • ✅ Reduces configuration overhead
  • ✅ Maintains all individual project locking functionality
  • ✅ Easy to enable/disable per project or globally

When to Use

Enable this property if:

  • You don't use global lock files in your project
  • You experience ConcurrentModificationException errors
  • You want faster configuration time by skipping global lock setup
  • You only need per-project lock files

Backward Compatibility

  • Default behavior unchanged: If the property is not set, global lock tasks are created as before
  • No breaking changes: Existing projects continue to work without modification
  • Opt-in feature: Must explicitly set the property to disable global locks

Example Scenarios

Multi-project Build Without Global Locks

# gradle.properties
dependencyLock.disableGlobalLock=true

# Run build with parallel execution (safe with this property)
./gradlew build --parallel

Debugging Concurrency Issues

# Temporarily disable global locks to isolate the issue
./gradlew help -PdependencyLock.disableGlobalLock=true

CI/CD Pipeline

# In CI script
./gradlew test \
  -PdependencyLock.disableGlobalLock=true \
  --parallel \
  --max-workers=8

@wisechengyi wisechengyi marked this pull request as ready for review November 19, 2025 00:01
@OdysseusLives OdysseusLives merged commit 12dfc81 into nebula-plugins:main Nov 20, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants