Here's my last week story. I was trying to debug an NPE, so I added the `notNull(` line in the follwing:
@PUT
@Path("/{rest}/path")
@LogBody
public Answer controllerMethod(
@PathParam("param1") UUID param1,
@ApiParam(required = true, value = "body") @NotNull @Valid Body1 body1) {
notNull(body1, "Annotations are a joke. This null value made it through reqired=true, NotNull, and Valid");
return service.serviceMethod(param1, body1);
}
And sure enough that line was hit:
2023-09-08T07:34:34,511 ${env:K8S_POD_IP} WARN org.eclipse.jetty.server.HttpChannel - /api/v3/service/rest/path
javax.servlet.ServletException: javax.servlet.ServletException: org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException: Annotations are a joke. This null value made it through reqired=true, NotNull, and Valid
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:162) ~[jetty-server-9.4.44.v20210927.jar:9.4.44.v20210927]
at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:179) ~[jetty-server-9.4.44.v20210927.jar:9.4.44.v20210927]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[jetty-server-9.4.44.v20210927.jar:9.4.44.v20210927]
I just don't know what is to be done at this point. I don't know how the median Java programmer doesn't walk away after getting burned by this one.
There are various different @NotNull so I'm not sure which you're using, some (but not all) of them are more compile-time contract type things. So if you called that method with null then you'd get an error from a code analysis tools. But that @PUT method is called by the framework at runtime based on an incoming REST request, there's no line in your code which calls the method with null, therefore nowhere for the code analysis tool to see the error and report it.
So yeah, all really confusing, and doesn't always do what you want. Nevertheless, I feel that at least there is a chance to use them and they do sometimes find bugs, which is better than Go's situation of having no way to specify that a method shouldn't be called with null. So if you do call such methods with nil in Go, even in a way that could never work, and which would theoretically be detectable at compile time, you just always get a runtime crash.