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.
New in 2024.2
Last modified: 03 December 2024