Inspectopedia 2024.3 Help

Potential deadlock in service initialization

Reports read/write actions and invokeAndWait called from the scope of service initialization:

  • service constructors and initialization blocks (including static)

  • service companion object's initialization blocks (Kotlin)

  • service methods used in initialization blocks and fields initialization

  • PersistentStateComponent initialization lifecycle methods:

    • loadState

    • noStateLoaded

    • initializeComponent

Running a read/write action or calling invokeAndWait during service initialization may cause deadlocks.

Examples:

Kotlin:

@Service internal class MyService { private val myData = initMyData(); constructor() { val data = runReadAction { // bad: read action run in a constructor // read data } } private fun initMyData(): Data { return runWriteAction { // bad: invoked while initializing myData property // write data } } companion object { lateinit var companionData: String init { companionData = runReadAction { // bad: read action run in an init block // read data } } } }

Java:

@Service class MyService { private static final Data ourData1 = ReadAction.compute(() -> { // read data }); private static final Data ourData2; static { ourData2 = ReadAction.compute(() -> { // bad: read action in a static initialization block // read data }); } private final Data myData2 = initMyData(); MyService() { Data data = WriteAction.compute(() -> { // bad: read action run in a constructor // write data }); } private Data initMyData() { return ReadAction.compute(() -> { // bad: invoked while initializing myData property // read data }); } }

PersistentStateComponent:

@Service @State(...) internal class MySettings : PersistentStateComponent<MyService> { var stateValue: String? = null override fun loadState(state: MySettings) { val data = runReadAction { // bad: read action run in loadState // read data } // ... } override fun noStateLoaded() { val data = runWriteAction { // bad: read action run in noStateLoaded // write data } // ... } override fun initializeComponent() { val data = runReadAction { // bad: read action run in initializeComponent // read data } // ... } }

Locating this inspection

By ID

Can be used to locate inspection in e.g. Qodana configuration files, where you can quickly enable or disable it, or adjust its settings.

PotentialDeadlockInServiceInitialization
Via Settings dialog

Path to the inspection settings via IntelliJ Platform IDE Settings dialog, when you need to adjust inspection settings directly from your IDE.

Settings or Preferences | Editor | Inspections | Plugin DevKit | Code

New in 2024.2

Inspection Details

By default bundled with:

IntelliJ IDEA 2024.3, Qodana for JVM 2024.3,

Can be installed with plugin:

Plugin DevKit, 243.23126

Last modified: 03 December 2024