The _Minimal reproducible example_ (see below) errors out (with IndexOutOfBoundsException) for me once I scroll past the first 49 results.
No IndexOutOfBoundsException when using a range/offsets.
IndexOutOfBoundsException as follows:
[INFO] java.lang.IndexOutOfBoundsException: Index 50 out of bounds for length 50
[INFO] at jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) ~[?:?]
[INFO] at jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) ~[?:?]
[INFO] at jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248) ~[?:?]
[INFO] at java.util.Objects.checkIndex(Objects.java:372) ~[?:?]
[INFO] at java.util.ArrayList.get(ArrayList.java:458) ~[?:?]
[INFO] at com.vaadin.flow.data.provider.DataCommunicator.lambda$getJsonItems$3(DataCommunicator.java:611) ~[flow-data-2.0.14.jar:2.0.14]
[INFO] at java.util.stream.IntPipeline$1$1.accept(IntPipeline.java:180) ~[?:?]
[INFO] at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:104) ~[?:?]
[INFO] at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:699) ~[?:?]
[INFO] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[?:?]
[INFO] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?]
[INFO] at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?]
[INFO] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
[INFO] at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[?:?]
[INFO] at com.vaadin.flow.data.provider.DataCommunicator.getJsonItems(DataCommunicator.java:613) ~[flow-data-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.data.provider.DataCommunicator.lambda$collectChangesToSend$2(DataCommunicator.java:571) ~[flow-data-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.data.provider.DataCommunicator.applyIfNotEmpty(DataCommunicator.java:627) ~[flow-data-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.data.provider.DataCommunicator.withMissing(DataCommunicator.java:621) ~[flow-data-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.data.provider.DataCommunicator.collectChangesToSend(DataCommunicator.java:570) ~[flow-data-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.data.provider.DataCommunicator.flush(DataCommunicator.java:473) ~[flow-data-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.data.provider.DataCommunicator.lambda$requestFlush$2f364bb9$1(DataCommunicator.java:421) ~[flow-data-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.internal.StateTree.lambda$runExecutionsBeforeClientResponse$1(StateTree.java:364) ~[flow-server-2.0.14.jar:2.0.14]
[INFO] at java.util.ArrayList.forEach(ArrayList.java:1540) ~[?:?]
[INFO] at com.vaadin.flow.internal.StateTree.runExecutionsBeforeClientResponse(StateTree.java:361) ~[flow-server-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.server.communication.UidlWriter.encodeChanges(UidlWriter.java:392) ~[flow-server-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.server.communication.UidlWriter.createUidl(UidlWriter.java:182) ~[flow-server-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.server.communication.UidlRequestHandler.writeUidl(UidlRequestHandler.java:116) ~[flow-server-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89) ~[flow-server-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-2.0.14.jar:2.0.14]
[INFO] at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1540) ~[flow-server-2.0.14.jar:2.0.14]
@Route
public class Test extends Div {
public Test() {
List<String> items = IntStream.range(0, 500).mapToObj(Integer::toString)
.collect(Collectors.toList());
DataProvider<String, Void> licenseDataProvider = DataProvider
.fromCallbacks(query -> {
Stream<String> licenseStream = items
.subList(query.getOffset(), query.getLimit())
.stream();
return licenseStream;
}, query -> items.size());
Grid<String> grid = new Grid<>();
grid.setDataProvider(licenseDataProvider);
grid.addColumn(item -> item);
add(grid);
}
}
You don't want to use query.getLimit() as the second parameter to subList.
Simply use items.stream().skip(query.getOffset()).limit(query.getLimit()); or use something like query.getOffset() + query.getLimit() as a second parameter.
Thank you very much for precise issue description which exact code snippet!
:+1:
But in fact the ticket is invalid.
The previous comment is absolutely right :https://github.com/vaadin/flow/issues/6631#issuecomment-539661604.
List.subList() uses the first argument as offset ( the very fist index) and the second argument as the last index in the list.
You are passing query.getLimit() which is wrong. It should be query.getOffset() + query.getLimit() as precisely said in the comment .
Thank you @INPUTsys-Chris for the exact answer :+1:
Most helpful comment
You don't want to use
query.getLimit()as the second parameter tosubList.Simply use
items.stream().skip(query.getOffset()).limit(query.getLimit());or use something likequery.getOffset() + query.getLimit()as a second parameter.