Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MonthViewSkin: Assigning null to a primitive. (V11.12.3) #193

Open
baumeister opened this issue Nov 2, 2022 · 2 comments
Open

MonthViewSkin: Assigning null to a primitive. (V11.12.3) #193

baumeister opened this issue Nov 2, 2022 · 2 comments

Comments

@baumeister
Copy link

I'm getting exceptions in MonthViewSkin$MonthDayEntriesPane.update(MonthViewSkin.java:675) because the return value of a map lookup is assigned to an int even though it may be null:

Trace:

Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object)" is null
at impl.com.calendarfx.view.MonthViewSkin$MonthDayEntriesPane.update(MonthViewSkin.java:675)
at impl.com.calendarfx.view.MonthViewSkin$MonthDayEntriesPane.lambda$new$0(MonthViewSkin.java:632)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(Unknown Source)

@baumeister
Copy link
Author

baumeister commented Oct 9, 2023

Confirmed to still exist in 11.12.6.

I assume this is some sort of threading synchronization issue involving positionMap as it not always appears but can be very easily reproduced by clicking on the previous/next button in quick succession. It also happens randomly otherwise though.

Outside of analyzing the threading problem, a possible fix is to simply avoid the NPE in MonthDayEntriesPane:update, so changing

int position = positionMap.get(Objects.requireNonNull(entry.getId(), "entry ID is missing, entry type = " + entry.getClass().getName() + ", entry title = " + entry.getTitle()));
maxPosition = Math.max(maxPosition, position);

to

Integer position = positionMap.get(Objects.requireNonNull(entry.getId(), "entry ID is missing, entry type = " + entry.getClass().getName() + ", entry title = " + entry.getTitle()));
if (position!=null) 
    maxPosition = Math.max(maxPosition, position);

@baumeister
Copy link
Author

baumeister commented Oct 9, 2023

Test case to reproduce:

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Random;
import java.util.UUID;

import com.calendarfx.model.Calendar;
import com.calendarfx.model.Calendar.Style;
import com.calendarfx.model.CalendarSource;
import com.calendarfx.model.Entry;
import com.calendarfx.view.CalendarView;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;


public class FxCalendarTest extends Application {
	@Override
	public void start(Stage stage) {
		final VBox box = new VBox();
		final Scene scene = new Scene(box);
		stage.setScene(scene);
		Calendar calendarIncomplete = null;
		Calendar calendarComplete = null;
		CalendarView calendarView = new CalendarView();
		calendarIncomplete = new Calendar("incomplete"); 
		calendarIncomplete.setStyle(Style.STYLE2); 
		calendarComplete = new Calendar("complete"); 
		calendarComplete.setStyle(Style.STYLE1); 

		CalendarSource myCalendarSource = new CalendarSource("Calendars"); 
		calendarView.getCalendarSources().clear();
		calendarView.getCalendarSources().addAll(myCalendarSource); 
		myCalendarSource.getCalendars().clear();
		myCalendarSource.getCalendars().addAll(calendarComplete,calendarIncomplete);

		calendarView.setRequestedTime(LocalTime.now());
		calendarView.setShowPrintButton(false);
		calendarView.setShowAddCalendarButton(false);
		calendarView.setShowSearchField(false);
		calendarView.setShowSearchResultsTray(false);
		calendarView.setShowSourceTray(false);
		calendarView.setShowSourceTrayButton(false);
		calendarView.setShowPageToolBarControls(false);
		calendarComplete.setReadOnly(true);
		calendarIncomplete.setReadOnly(true);
		calendarView.setShowPageSwitcher(true);
		calendarView.setCalendarVisibility(calendarIncomplete, true);
		calendarView.setCalendarVisibility(calendarComplete, true);
		for (int i=0;i<100;i++) {
			Entry e = new Entry();
			e.setTitle(UUID.randomUUID().toString());
			e.setId(UUID.randomUUID().toString());
			e.setFullDay(true);
			e.changeStartDate(LocalDate.of(2023, randomInt(3, 11), randomInt(1,29)));
			e.changeEndDate(e.getStartDate().plusDays(randomInt(2,10)));
			e.setCalendar(randomInt(1)==0? calendarIncomplete : calendarComplete);
		}
		VBox.setVgrow(calendarView,Priority.ALWAYS);
		box.getChildren().add(calendarView);
		calendarView.showMonthPage();

		stage.show();
	}

	public static void main(String[] args) {
		launch(args);
	}
	
	static private Random randomInt = new Random(System.currentTimeMillis());
	
	public static int randomInt(int max) {
		return randomInt.nextInt(max+1);
	}

	public static int randomInt(int min,int max) {
		return randomInt.nextInt(max-min+1)+min;
	}
}

Click a couple of times on month forward and/or backward button to cause the NPE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant