I have a strange problem, and it been showing up intermittently for over a year.
I create a set of files as compile time in src/main/resources and read them at run time. Most of the time I have no problem with this, either when deployed on the robot or when run in the desktop simulator. However, under certain circumstances, the resource is not found in the simulator. I haven’t seen it happen on the RoboRio.
So, files in the resources directory are supposed to get included in the jar file for the application, and I have verified that they are, even when the getResourcesAsStream fails. The intermittent nature of the problem has made it extremely difficult to debug, but I finally have a test case that seems to be one hundred percent repeatable, on multiple systems.
First, clone the github repo (or fork if you want to futz with it. The problem follows the fork) GitHub - blu28/ChargedUp2023
Then, do the following exactly:
Let the initial clone and initialization complete.
Switch the local branch from “main” to “testbranch”
In a terminal window run “./gradlew spotlessApply”
The above task will cause three files to be modified, although doing a compare will show nothing changed (!).
Run WPILIB: Build Robot Code
Run WPILIB: Simulate Robot Code.
Select “SimGUI” as the type.
When the simulation runs, it will quit with an uncaught null pointer exception:
Error at frc.robot.Splash.printStatusFile(Splash.java:61): Unhandled exception: java.lang.NullPointerException: Cannot invoke "java.io.InputStream.read(byte[])" because "statusfile" is null
at frc.robot.Splash.printStatusFile(Splash.java:61)
at frc.robot.Splash.printAllStatusFiles(Splash.java:31)
at frc.robot.Robot.robotInit(Robot.java:37)
at edu.wpi.first.wpilibj.TimedRobot.startCompetition(TimedRobot.java:106)
at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:349)
at edu.wpi.first.wpilibj.RobotBase.lambda$startRobot$0(RobotBase.java:422)
at java.base/java.lang.Thread.run(Thread.java:833)
The code where this is failing looks like this:
try (InputStream statusfile =
(Boolean.TRUE.equals(isResource))
? Main.class.getResourceAsStream("/" + filename)
: new BufferedInputStream(new FileInputStream(filepath))) {
System.out.print((filename + ": ").replace(".txt", ""));
try {
for (int length = 0; (length = statusfile.read(buffer)) != -1; ) {
The read is throwing the exception because statusfile is null. The “Main.class.getResourceAsStream” call has returned null trying to open the resource “/buildtime.txt”.
This is where it gets weird. If you look at the jar file under build/libs, the jar file has the correct file buildtime.txt as a member, right where it is supposed to be. You can re-run the build and re-run the simulate tasks all you like and it will still fail. But if you use the “Change Desktop Enabled Setting” to set it to disabled and then do it again to enable it again, then the problem goes away and I can’t get it to happen again.
I am at a loss. The same code is there in both cases, the resource is there in both cases. I just can’t figure out what is causing the problem. I guess there is some clean step I am missing when switching between branches. Is there a “proper” procedure for that?