Mechanical-Advantage / AdvantageKit

Monorepo for robot framework and tools
GNU General Public License v3.0
152 stars 42 forks source link

Null Pointer Exception when null members exist in Robot class #61

Closed vichik123 closed 8 months ago

vichik123 commented 8 months ago

I was trying to run a simulation with advantage kit, and I got this error:

Error at org.littletonrobotics.junction.AutoLogOutputManager.registerFields(AutoLogOutputManager.java:53): Unhandled exception: java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "root" is null at org.littletonrobotics.junction.AutoLogOutputManager.registerFields(AutoLogOutputManager.java:53) at org.littletonrobotics.junction.AutoLogOutputManager.registerFields(AutoLogOutputManager.java:63) at org.littletonrobotics.junction.AutoLogOutputManager.lambda$registerFields$3(AutoLogOutputManager.java:141) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.littletonrobotics.junction.AutoLogOutputManager.registerFields(AutoLogOutputManager.java:106) at org.littletonrobotics.junction.AutoLogOutputManager.lambda$registerFields$3(AutoLogOutputManager.java:141) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.littletonrobotics.junction.AutoLogOutputManager.registerFields(AutoLogOutputManager.java:106) at org.littletonrobotics.junction.AutoLogOutputManager.lambda$registerFields$3(AutoLogOutputManager.java:141) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.littletonrobotics.junction.AutoLogOutputManager.registerFields(AutoLogOutputManager.java:106) at org.littletonrobotics.junction.AutoLogOutputManager.registerFields(AutoLogOutputManager.java:43) at org.littletonrobotics.junction.LoggedRobot.startCompetition(LoggedRobot.java:86) at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:361) at edu.wpi.first.wpilibj.RobotBase.lambda$startRobot$0(RobotBase.java:433)

After some debugging I realized that the recursive auto logging found the robot container, which was null during the construction of the Robot object.

if (!root.getClass().getPackageName().startsWith(packageName)) return; This is line 53 of the AutoLogOutputManager, I think that it should be invoked only if the root variable isn't null.

jwbonner commented 8 months ago

Thanks for finding this. Based on the stacktrace, it looks like there was a null value in one of the arrays that was scanned. It already checks whether the value of a field is null here, but the same check is not applied here to array items. I'll push a fix for that, since it appears to be the root problem rather than the robot container being null.

vichik123 commented 8 months ago

But, that would mean that the robot container registers as an array?

jwbonner commented 8 months ago

Not necessarily, just that a null value was found somewhere during the recursive search. The stack trace shows that it had already scanned several levels past the root, which means that the robot container wasn't the issue. registerFields was last invoked from line 63, which is calling it for each item in the array (without checking for null values). The only other places that registerFields is called are for single field values (where null values are checked) and at the root level (the instance of Robot cannot be null since it is the one calling the function in the first place).

vichik123 commented 8 months ago

Ah I see. Thanks!