Grid problem after update from 8.1.8 to 8.3.2

After update when trying to send class via super(clazz) in my Class CGrid i got NullPointerException. Its realy strange because at 8.1.8 everything work ok. Problem start with version 8.2.0.

I realy dont know where is a problem. Maybe because i use MappedSuperclass but dont think soo.

java.lang.NullPointerException
	at com.vaadin.ui.Grid$Column.updateSortable(Grid.java:1169)
	at com.vaadin.ui.Grid$Column.access$2200(Grid.java:831)
	at com.vaadin.ui.Grid.addColumn(Grid.java:2846)
	at com.vaadin.ui.Grid.addColumn(Grid.java:2779)
	at com.vaadin.ui.Grid.addColumn(Grid.java:2718)
	at com.vaadin.ui.Grid.addColumn(Grid.java:2677)
	at com.vaadin.ui.Grid.addColumn(Grid.java:2631)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1620)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
	at com.vaadin.ui.Grid.<init>(Grid.java:2491)
	at com.vaadin.ui.Grid.<init>(Grid.java:2401)
	at com.vaadin.ui.Grid.<init>(Grid.java:2382)
	at pl.gov.ipn.components.CGrid.<init>(CGrid.java:72)
	at pl.gov.ipn.wnioski_IT.view.employee.EmployeeCGrid.<init>(EmployeeCGrid.java:25)
	at pl.gov.ipn.wnioski_IT.view.EmployeeView.initGrid(EmployeeView.java:269)

Are you able to share the code in the constructor of CGrid and the relevant part of EmployeeView.initGrid?

CGrid constructor:

public CGrid (Class<T> clazz){
		super(clazz);

		this.clazz = clazz;
	
		dataProvider = DataProvider.ofCollection( collectionItems = getItems(clazz) );

		setDataProvider(dataProvider);
	}

and
EmployeeView

EmployeeCGrid grid = new EmployeeCGrid();

and

	public EmployeeCGrid (){
		super(Employee.class);
		
		initFilters();
	}

From what i see in my class CGrid when using super(class), method updateSortable don’t see default dataProvider… and thats why it’s realy strange i think…

Are you able to share a minimal runnable project that reproduces the problem?

In weekend will try to recreate it.

I’m running in a comparable issue, don’t know whether it is the same.

I fill a grid with elements from a DB query and when clicking a row I want to get more details or so, at least an action based on the clicked row.

the clicklistener definition:

dataSetGrid.addItemClickListener(
		event ->
		getUI().getNavigator().navigateTo((event.getItem()).getMeasurementtype() + "/" +
		  ((DataSet)event.getItem())).getDatasetid()));

Strange thing is that this goes well the first time.
Second time it results in a NullPointerException

java.lang.NullPointerException
at com.donaldson.engine.iot.Views.EditExperimentView.lambda$Body$ef66bd7$1(EditExperimentView.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:499)

I verified that at the moment of the click the event contains the element, but it results in a NPE.
It even get weirder: in another Grid I have no problems, the principle is the same.

experimentGrid.addItemClickListener(event ->
       getUI().getNavigator().navigateTo("EditExperimentView/" + ((Experiment)event.getItem()).getExperimentid()));

Do you know for sure which part of the code is throwing the NPE? There’s quite a bit of statements put into a single line of code. For the sake of debugging, you can make the same code quite a bit more elaborate, to see closer what is going on. You could do the same with a breakpoint without code changes also.

dataSetGrid.addItemClickListener(event -> {
  SomeType item = event.getItem();
  SomeMeasurementType type = item.getMeasurementType();
  String id = item.getDatasetID();
  String destination = type + "/" + id;
  
  UI ui = getUI();
  Navigator navigator = ui.getNavigator();
  navigator.navigateTo(destination);
});

This should be equivalent code. I don’t know the type of item, measurementType and datasetId so I just put something there. Now if you rerun you should get more info on what exactly is null and causing the issue, with a more precise row number. If I would have to guess I would say event.getItem() returns null and then null.getMeasurementType() throws the exception. Does you Grid behave so that you can deselect, and there is no item selected? If you somehow can fire a itemClickListener, and an item is not selected out of it, then that will definitely throw an NPE.

I implemented the extended version and it is the navigator retreval that fails.

Navigator navigator = ui.getNavigator();

I hope this helps in pinning the issue.

Something potentially important to know is that I fill the Grid and other values in an overrided enter procedure.
I do this as I need the parameters from the previous click and I pass them through the IRL

Rafal Kozyra:
From what i see in my class CGrid when using super(class), method updateSortable don’t see default dataProvider… and thats why it’s realy strange i think…

I just would like you to check if this one is related

https://github.com/vaadin/framework/issues/10809

Okay. So if ui.getNavigator() throws NPE, then it means that UI ui = getUI() returns null. I can’t clearly say what would the reason be that it can’t find the UI reference. A example to play with would be a lot easier to work with.

As a workaround, the ui and navigator instance doesn’t change from one click to the next, and you could look it up only once. For example you could have a Navigator as a field in your Java class, and before you add the clicklistener, you fetch the instance. Then you use that reference within the clicklistener.

public class YourClass extends VerticalLayout {
	private Navigator navigator;

	public YourClass(){
		...
		navigator = getUI().getNavigator();
		dataSetGrid.addItemClickListener(event -> {
			...
			navigator.navigateTo(destination);
		}
	}
}

Now you have to make certain that getUI().getNavigator() runs correctly the one time when you initialize the component instead of for every click on the Grid. Maybe it also is more reliable when it is outside of a listener.

I understand that a workaround is not the best solution. I’m not able to pinpoint why it happens with the few code snippets.

The workaround is making things worse: it pulls the retrieval of the UI to the initiation of the view so it fails at that stage.
I will make a version of my code without the database links so you can run it on your computer.

For those that want to take a look into the issue: an simplified version without the dB links and GoogleMap widget
It still has the issue.
17051456.zip (196 KB)

I have been experimenting whith the location of the navigator = getUI().getNavigator(); statement.

When it is in the enter() procedure of the view the issue is not there.

For now it is solved with a workaround (thanks for the tip), but this is somehow a bug in the Grid component.

I loaded up your code and noticed the problem. You use component.getUI(). It asks the component in question that to which UI it is attached. Body() is called before addComponent is called on it. This will correclty return null because it is not attached anywhere.

You can instead use the static method UI.getCurrent() which doesn’t ask the component, but goes to the app directly and fetches the reference from there. So change EditExperimentView:28 from navigator2 = getUI().getNavigator(); to navigator2 = UI.getCurrent().getNavigator(); and it works.

You can read more about this in https://vaadin.com/docs/v8/framework/application/application-architecture.html#application.architecture.accessing

Jens,

I implemented your suggestion to handle the navigator retrieval using UI.getCurrent() and it indeed works better.

Thanks, Gwen

I’m glad you got it sorted out. Happy coding!

Just a question: how to do this in Vaadin Flow/10 ?

UI.navigate(destination) should do the same in Vaadin 10

Check [JavaDocs]
(https://demo.vaadin.com/javadoc/com.vaadin/flow-server/1.0.0.beta9/com/vaadin/flow/component/UI.html#navigate-java.lang.String-) and [documentation]
(https://vaadin.com/docs/v10/flow/routing/tutorial-routing-navigation.html) for more details.

Sorry, should have been more precise: how to add the clicklistener to a grid so that I have the object from the row on which I clicked?
But I fear we are leaving the original question.