10/11/2007

Resource Injection and Findbugs

Findbugs should have a place in every Java developer's toolbox. But it doesn't seem to understand Java EE resource injection yet, giving some false alarms.

If I run findbugs on this simple JavaEE application client code:

public class AppClientMain {
@EJB
protected static CalculatorRemote calc;

public static void main(String[] args) {
AppClientMain main = new AppClientMain();
main.calculate();
}

public void calculate() {
calc.calculate();
}
}
FindBugs will emit at least 2 false alarms:
1. Class AppClientMain(Priority 1, Category MALICIOUS_CODE)
MS_SHOULD_BE_FINAL: AppClientMain.calc isn't final but should be

A mutable static field could be changed by malicious code or by
accident from another package. The field could be made final to
avoid this vulnerability.
The injection field in application client main class must be declared static, though it can use any access modifier like public, protected, package private, or private. That's the rule. If I change the field to final, as suggested by findbugs, the container (application client container) won't be able to inject anything into it. However, once I change the field to private, findbugs is happy.

BTW, just to be clear, injection fields in all components other than application client main class or its superclass must not be static. In all cases, injection fields must not be final. But I don't think findbugs need to complain about non-final instance fields.
2. Class AppClientMain(Priority 2, Category CORRECTNESS)
NP_UNWRITTEN_FIELD: Read of unwritten field calc in
AppClientMain.calculate()

The program is dereferencing a field that does not seem to ever
have a non-null value written to it. Dereferencing this value
will generate a null pointer exception.
Another variant of this warning is:
UWF_UNWRITTEN_FIELD: Unwritten field:...This field is never written.
All reads of it will return the default value. Check for errors
(should it have been initialized?), or remove it if it is useless.
No, this shouldn't result in NPE. If you do see NPE at runtime, it can only mean one of the following:

1. Your application is not properly configured. For instance, the @EJB reference cannot be resolved to a deployed EJB. Then you need to make sure the @EJB reference is correctly mapped via @EJB(mappedName) attribute, mapped-name, ejb-link, or jndi-name elements in descriptors and deployment plans. Most likely, your server should already reported a NameNotFoundException in server log.

2. A bug in your application server, which is much less likely than (1) but still possible.