pror21 pror21 - 2 months ago 10
Java Question

Task is not executing code properly

I have a set of tasks that executing in series with an

ExecutorService
.
A
NullPointerException
is throwing the most of the times but not always.

All my previous tasks are requesting data from a website except this one but they all serializing data to a file through the serializeService.

Why this happens? I can't spot the source of the problem.

Tasks:

...
Task<List<Course>> parseGradesTask = new Task<List<Course>>() {
@Override
public List<Course> call() {
return studentParser.parseStudentGrades();
}
};

Task<HashMap<String, String>> parseRegTask = new Task<HashMap<String, String>>() {
@Override
public HashMap<String, String> call() {
return studentParser.parseStudentRegistration();
}
};

parseGradesTask.setOnSucceeded(e -> {
List<Course> newList = parseGradesTask.getValue();
List<Course> newGrades = getNewlyListedCourses(newList);
if(!newGrades.isEmpty()) {
serializeService.serializeRecentCourses(newGrades);
setTableViewRecent();
notifyGrade(newGrades);
}
serializeService.serializeCourses(newList);
setTableViewCourses();
});

parseRegTask.setOnSucceeded(e-> {
// Exception starts from this line:
List<Course> regList = serializeService.fetchRegisterCourseList(parseGradesTask.getValue(), parseRegTask.getValue());
serializeService.serializeRegister(regList);
setTableViewReg();
});

ExecutorService es = Executors.newSingleThreadExecutor();
// other tasks
es.submit(() -> new Thread(parseGradesTask).start());
es.submit(() -> new Thread(parseRegTask).start());
es.shutdown();


NullPointerException on fetch method:

public List<Course> fetchRegisterCourseList(List<Course> courseList, HashMap<String, String> courseIdList) {
List<Course> courseRegList = new ArrayList<>();

Iterator it = courseIdList.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
// NullPointerException on this line:
courseRegList.addAll(courseList.stream().filter(course ->
course.getCourseId().equals(pair.getKey()) && course.getCourseTitle().equals(pair.getValue()))
.collect(Collectors.toList()));
it.remove(); // avoids a ConcurrentModificationException
}
return courseRegList;
}



Exception in thread "JavaFX Application Thread"
java.lang.NullPointerException at
com.example.test.service.Impl.SerializeServiceImpl.fetchRegisterCourseList(SerializeServiceImpl.java:100)
at
com.example.test.controller.MainController.lambda$syncCourses$4(MainController.java:450)

Answer

If parseRegTask finishes before parseGradesTask, then in the handler for parseRegTask, parseGradesTask.getValue() will return null. Since both are running in their own thread, this is clearly possible.

I think you are intending to run both tasks on the single thread provided by the executor. To do this you need

es.submit(parseGradesTask);
es.submit(parseRegTask);
Comments