I don't normally use reflection directly while programming in Java. But I do use APIs and frameworks that internally rely on reflection or annotations to provide customization points.

A lot of frameworks use annotations to set up dependency injection or do some sort of automated logic wiring on your behalf.

This results in a lot of field, method, and constructor accesses which the static code analyzer can't follow, resulting in many false positives (not only "unused method/field" warnings). Is my only realistic option to continue to suppress these warnings, or are there other things I can do to help the analyzer better understand the real entry points of my classes?

I've heard some people discuss using test code for this purpose.

In a lot of the cases, I could probably write relevant test cases that make the warnings disappear, but I am worried about the rather large number of cases where that would involve testing implementation details instead of observable behavior. This code already has adequate branch coverage, and I don't want to write tests that I will regret writing every time I do maintenance. But if whitebox testing is really sometimes the "best" alternative, are there ways to help minimize the downsides? Fragility and implementation leakage are my primary concerns.

  • 1
    Code analyzers have warning suppression mechanisms precisely for this reason. – Robert Harvey May 17 '18 at 15:47
  • You'd have to ask about a specific analyzer, since they all differ. And that would then go to SO, since it's about a specific tool. But a lot of them allow either: Suppressing warnings on fields/methods that have X annotation, or allowing to suppress a rule entirely, and rewriting it to take your annotations into account. How exactly those are done and which is available depends on your tool. – Ordous May 17 '18 at 15:59
  • @Ordous I know how to suppress the warnings in many different ways. I don't need help with that. I am specifically asking if I have alternatives to that, given that it does have significant downsides. If the answer is no, then so be it. – Tim Seguine May 17 '18 at 16:20
  • @TimSeguine What downsides would those be? You'd essentially have the tool better fit the reality of your code. – Ordous May 17 '18 at 16:58
  • What are the downsides? What does "fragility and implementation leakage" mean? – Robert Harvey May 17 '18 at 17:45

When you use dynamic features (reflection, downcasts, metaprogramming, code generation, scripting languages) there's an implicit understanding that you are willingly sacrificing static analyzability for coding convenience. There is definitively a tradeoff here.

For many projects, this is not a good trade. Or maybe it was a good idea early in the inception of the project, but has now become a maintenance burden. When type checking, IDE support, and static analysis are more valuable than convenience, it may be worth rewriting the relevant parts to avoid dynamic features.

This is not always possible or desirable. Some problems are inherently dynamic. For some projects, writing extra boilerplate would be a larger maintenance burden than dealing with incomplete tool support. In your case, continuing to disable some static analysis checks may be the best you can do.

While the choice between expressiveness and static analysis is generally exclusive, there might be a third option: improve your tools. In the case of Java, you could perhaps write annotations that your static analysis tools understand.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.