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

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
    }
    // ...
  }

}

New in 2024.2