Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid 'uninitialized' errors on injected fields when using the Checker Framework

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?

like image 232
glts Avatar asked Sep 27 '22 08:09

glts


People also ask

Why field based injection is not recommended?

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.

What is checker framework?

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.

What is field injection?

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.


1 Answers

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.

like image 99
mernst Avatar answered Oct 09 '22 03:10

mernst