The Checker Framework's Nullness Checker generates an error when it encounters an uninitialised field.
[ERROR] /home/glts/src/example/src/main/java/BookRepositoryImpl.java:[39,7]
error: [initialization.fields.uninitialized] the constructor does not initialize fields: em
Now, it is a common pattern to have some fields injected via dependency injection:
@Repository
public class BookRepositoryImpl implements BookRepository {
@PersistenceContext
private EntityManager em;
@Override
@Nullable
public Book findById(int id) {
return em.find(Book.class, id);
}
// ...
}
Here, the @javax.persistence.PersistenceContext
annotation ensures that em
will hold a reference to an EntityManager
instance after the repository has been constructed.
More generally, in these cases the application framework guarantees that fields are initialised and non-null when they are used – but the Checker Framework can't know this.
So far, I've found that one remedy is to convert field injection to constructor injection (@Inject
). This isn't an option in the above example, though.
Is there a way to tell the Checker Framework that a field is injected, and therefore properly initialised and non-null, without simply suppressing these errors?
The reasons why field injection is frowned upon are as follows: You cannot create immutable objects, as you can with constructor injection. Your classes have tight coupling with your DI container and cannot be used outside of it. Your classes cannot be instantiated (for example in unit tests) without reflection.
The Checker Framework enhances Java's type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence.
Injection is a process of injecting dependeny into an object. Field injection is used to set value object as dependency to the field of an object.
You can suppress the error for a single field by writing @SuppressWarnings("initialization.fields.uninitialized")
on the field declaration.
You can suppress the error for all fields by writing @SuppressWarnings("initialization.fields.uninitialized")
on the class.
There exist injection frameworks that can inject null as a value where a @PersistenceContext
annotation exists, such as when the .xml file isn't present, the code isn't running in a transaction, etc. Writing the
@SuppressWarnings("initialization.fields.uninitialized")
annotation is your way of saying that you trust that the one you are using will always inject a non-null value for your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With