Cannot save PersistentStateComponent when class has project even if project is private

Answered

PersistentStateComponent cause Error on save when the class has private project.

 

The error message is like this.

 

Unable to serialize TestState state

com.intellij.util.xmlb.XmlSerializationException: Can't serialize instance of class models.TestState
at com.intellij.configurationStore.XmlSerializer.serialize(xmlSerializer.kt:59)
at com.intellij.configurationStore.XmlSerializer.serialize$default(xmlSerializer.kt:43)
at com.intellij.configurationStore.SaveSessionBaseKt.serializeState(SaveSessionBase.kt:57)
at com.intellij.configurationStore.SaveSessionBase.setState(SaveSessionBase.kt:29)
at com.intellij.configurationStore.StateStorageManagerImpl$startExternalization$1.setState(StateStorageManagerImpl.kt:440)
at com.intellij.configurationStore.ComponentStoreImpl.commitComponent(ComponentStoreImpl.kt:251)
at com.intellij.configurationStore.ComponentStoreImpl.doSaveComponents(ComponentStoreImpl.kt:198)
at com.intellij.configurationStore.ComponentStoreImpl.save(ComponentStoreImpl.kt:134)
at com.intellij.openapi.components.impl.stores.StoreUtil.save(StoreUtil.java:40)
at com.intellij.openapi.project.impl.ProjectImpl.save(ProjectImpl.java:331)
at com.intellij.openapi.project.impl.ProjectImpl.save(ProjectImpl.java:315)
at com.intellij.openapi.components.impl.stores.StoreUtil.saveProject(StoreUtil.java:137)
at com.intellij.openapi.components.impl.stores.StoreUtil.saveProjectsAndApp(StoreUtil.java:128)
at com.intellij.openapi.components.impl.stores.StoreUtil.saveDocumentsAndProjectsAndApp(StoreUtil.java:113)
at com.intellij.openapi.application.impl.ApplicationImpl.saveAll(ApplicationImpl.java:1441)
at com.intellij.ide.SaveAndSyncHandlerImpl.saveProjectsAndDocuments(SaveAndSyncHandlerImpl.java:126)
at com.intellij.ide.SaveAndSyncHandlerImpl$2.lambda$onFrameDeactivated$0(SaveAndSyncHandlerImpl.java:94)
at com.intellij.openapi.application.TransactionGuardImpl.runSyncTransaction(TransactionGuardImpl.java:88)
at com.intellij.openapi.application.TransactionGuardImpl.lambda$submitTransaction$1(TransactionGuardImpl.java:111)
at com.intellij.openapi.application.TransactionGuardImpl.submitTransaction(TransactionGuardImpl.java:120)
at com.intellij.openapi.application.TransactionGuard.submitTransaction(TransactionGuard.java:122)
at com.intellij.ide.SaveAndSyncHandlerImpl$2.onFrameDeactivated(SaveAndSyncHandlerImpl.java:92)
at com.intellij.ide.FrameStateManagerImpl.fireDeactivationEvent(FrameStateManagerImpl.java:86)
at com.intellij.ide.FrameStateManagerImpl.access$500(FrameStateManagerImpl.java:32)
at com.intellij.ide.FrameStateManagerImpl$2.lambda$applicationDeactivated$0(FrameStateManagerImpl.java:72)
at com.intellij.util.concurrency.QueueProcessor.runSafely(QueueProcessor.java:232)
at com.intellij.util.Alarm$Request.runSafely(Alarm.java:405)
at com.intellij.util.Alarm$Request.access$700(Alarm.java:330)
at com.intellij.util.Alarm$Request$1.run(Alarm.java:371)
at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:315)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.doRun(LaterInvocator.java:447)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.runNextEvent(LaterInvocator.java:431)
at com.intellij.openapi.application.impl.LaterInvocator$FlushQueue.run(LaterInvocator.java:415)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:762)
at java.awt.EventQueue.access$500(EventQueue.java:98)
at java.awt.EventQueue$3.run(EventQueue.java:715)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:732)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:781)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:722)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:382)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodException: models.TestState.<init>()
at com.intellij.util.ExceptionUtil.rethrow(ExceptionUtil.java:160)
at com.intellij.util.ReflectionUtil.newInstance(ReflectionUtil.java:427)
at com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters.getDefaultBean(SkipDefaultValuesSerializationFilters.java:59)
at com.intellij.util.xmlb.SkipDefaultsSerializationFilter.equal(SkipDefaultsSerializationFilter.java:25)
at com.intellij.util.xmlb.BeanBinding.serializeInto(BeanBinding.java:83)
at com.intellij.util.xmlb.BeanBinding.serialize(BeanBinding.java:68)
at com.intellij.configurationStore.XmlSerializer.serialize(xmlSerializer.kt:49)
... 49 more

 

Class implementation is like this.

 

@State(
name = "TestState"
)
public class TestState implements PersistentStateComponent<TestState> {
private Project project;
public String test;

public static TestState getInstance(Project project) {
return ServiceManager.getService(project, TestState.class);
}

public TestState(Project project) {
this.project = project;
}

public void update(List<PullRequest> pullRequests) {
this.test = "test";
}

@Nullable
@Override
public TestState getState() {
return this;
}

@Override
public void loadState(@NotNull TestState state) {
XmlSerializerUtil.copyBean(state, this);
}
}

 

Private variables is not saved. Why it cause error??

Do you have any annotation or something to prevent this error?

3 comments
Comment actions Permalink

Without private project, it can be saved.

 

@State(
name = "TestState"
)
public class TestState implements PersistentStateComponent<TestState> {
public String test;

public static TestState getInstance(Project project) {
return ServiceManager.getService(project, TestState.class);
}

public void update(List<PullRequest> pullRequests) {
this.test = "test";
}

@Nullable
@Override
public TestState getState() {
return this;
}

@Override
public void loadState(@NotNull TestState state) {
XmlSerializerUtil.copyBean(state, this);
}
}
0
Comment actions Permalink
NoSuchMethodException: models.TestState.<init>()

PersistentStateComponent deserialisation logic can't create objects without default constructor.
You can store state in a separate data object - see https://github.com/JetBrains/intellij-community/blob/master/xml/xml-psi-impl/src/com/intellij/application/options/editor/XmlFoldingSettings.java as an example.

1
Comment actions Permalink

Thank you.

I will try to separate data.

 

0

Please sign in to leave a comment.