FlowingCode / GridExporterAddon

Other
10 stars 8 forks source link

Cannot access state in VaadinSession or UI without locking the session. #45

Closed anne-k closed 1 year ago

anne-k commented 1 year ago

Hi,

Thanks for this plugin, it's very useful. I want to use it to export to CSV with a custom export button, which works... until I try to hide the buttons generated by the plugin, by setting exporter.setAutoAttachExportButtons(false). If I do that, when I click my export button I get an empty file, and this exception in the application log:

Exception in thread "Thread-23" java.lang.IllegalStateException: Cannot access state in VaadinSession or UI without locking the session.
        at com.vaadin.flow.server.VaadinSession.checkHasLock(VaadinSession.java:576)
        at com.vaadin.flow.server.VaadinSession.checkHasLock(VaadinSession.java:590)
        at com.vaadin.flow.internal.StateTree.checkHasLock(StateTree.java:432)
        at com.vaadin.flow.internal.StateTree.beforeClientResponse(StateTree.java:362)
        at com.vaadin.flow.data.provider.DataCommunicator$FlushRequest.lambda$register$43f5e0c7$1(DataCommunicator.java:1515)
        at com.vaadin.flow.internal.StateNode.runWhenAttached(StateNode.java:895)
        at com.vaadin.flow.data.provider.DataCommunicator$FlushRequest.register(DataCommunicator.java:1511)
        at com.vaadin.flow.data.provider.DataCommunicator.requestFlush(DataCommunicator.java:1107)
        at com.vaadin.flow.data.provider.DataCommunicator.requestFlush(DataCommunicator.java:1093)
        at com.vaadin.flow.data.provider.DataCommunicator.reset(DataCommunicator.java:378)
        at com.vaadin.flow.component.grid.Grid.setClassNameGenerator(Grid.java:3933)
        at com.flowingcode.vaadin.addons.gridhelpers.GridHelper.setClassNameGenerator(GridHelper.java:154)
        at com.flowingcode.vaadin.addons.gridhelpers.GridHelper.<init>(GridHelper.java:77)
        at com.flowingcode.vaadin.addons.gridhelpers.GridHelper.getHelper(GridHelper.java:91)
        at com.flowingcode.vaadin.addons.gridhelpers.GridHelper.getHeader(GridHelper.java:327)
        at com.flowingcode.vaadin.addons.gridexporter.BaseInputStreamFactory.renderCellTextContent(BaseInputStreamFactory.java:84)
        at com.flowingcode.vaadin.addons.gridexporter.BaseInputStreamFactory.lambda$getGridHeaders$0(BaseInputStreamFactory.java:70)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
        at com.flowingcode.vaadin.addons.gridexporter.BaseInputStreamFactory.getGridHeaders(BaseInputStreamFactory.java:71)
        at com.flowingcode.vaadin.addons.gridexporter.CsvInputStreamFactory$1.run(CsvInputStreamFactory.java:46)
        at java.base/java.lang.Thread.run(Thread.java:829)

The only difference is the AutoAttachExportButtons setting. Do you have any idea what could be causing this? I'm using Vaadin 23.3.0 and addon version 1.4.0.

javier-godoy commented 1 year ago

Hello. GridExporter relies on GridHelpers in order to retrieve the headers (among other things); and the initialization of GridHelpers requires that the UI is locked.

When autoAttachExportButtons is true, GridHelpers is initialized earlier. When it's false, the initialization happens inside of the stream factory, and that access is never locked: https://github.com/FlowingCode/GridExporterAddon/blob/98d22acbccb91b31c3af54b78bd1ce219d4971f1/src/main/java/com/flowingcode/vaadin/addons/gridexporter/CsvInputStreamFactory.java#L42

As a workaround, please call GridHelpers.getSelectionFilter(grid); immediately after initializing the grid (that should avoid the late initialization that throws an exception).

I'll keep this issue open in order to deliver a proper fix.

anne-k commented 1 year ago

Thank you! It works! Just a side note, it seems to be GridHelper rather than GridHelpers. Thank you for the quick reply and the workaround.