Since we recently upgraded to Java 25 we wanted to migrate our project to jspecify and stop using javax.annotations.Nullable:
We have run into problems with our nullable provider methods, which look like this:
import dagger.Module;
import dagger.Provides;
import jakarta.inject.Singleton;
import javax.annotation.Nullable;
import org.opentripplanner.datastore.api.GoogleStorageDSRepository;
import org.opentripplanner.datastore.api.OtpDataStoreConfig;
import org.opentripplanner.datastore.base.DataSourceRepository;
import org.opentripplanner.framework.application.OTPFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Module
public class GsDataSourceModule {
private static final Logger LOG = LoggerFactory.getLogger(GsDataSourceModule.class);
@Provides
@Singleton
@Nullable
@GoogleStorageDSRepository
DataSourceRepository provideGoogleStorageDataSourceRepository(OtpDataStoreConfig config) {
if (OTPFeature.GoogleCloudStorage.isOff()) {
return null;
}
return new GsDataSourceRepository(config.gsParameters());
}
}
They cause runtime exceptions when I swap javax.annotation.Nullable with org.jspecify.annotations.Nullable:
java.lang.NullPointerException: Cannot return null from a non-@Nullable @Provides method
at dagger.internal.Preconditions.checkNotNullFromProvides(Preconditions.java:64)
at org.opentripplanner.ext.datastore.gs.GsDataSourceModule_ProvideGoogleStorageDataSourceRepositoryFactory.provideGoogleStorageDataSourceRepository(GsDataSourceModule_ProvideGoogleStorageDataSourceRepositoryFactory.java:52)
at org.opentripplanner.ext.datastore.gs.GsDataSourceModule_ProvideGoogleStorageDataSourceRepositoryFactory.get(GsDataSourceModule_ProvideGoogleStorageDataSourceRepositoryFactory.java:42)
at org.opentripplanner.ext.datastore.gs.GsDataSourceModule_ProvideGoogleStorageDataSourceRepositoryFactory.get(GsDataSourceModule_ProvideGoogleStorageDataSourceRepositoryFactory.java:13)
at dagger.internal.DoubleCheck.getSynchronized(DoubleCheck.java:54)
at dagger.internal.DoubleCheck.get(DoubleCheck.java:45)
at org.opentripplanner.datastore.configure.DataStoreModule_ProvideDataStoreFactory.get(DataStoreModule_ProvideDataStoreFactory.java:51)
at org.opentripplanner.datastore.configure.DataStoreModule_ProvideDataStoreFactory.get(DataStoreModule_ProvideDataStoreFactory.java:15)
at dagger.internal.DoubleCheck.getSynchronized(DoubleCheck.java:54)
at dagger.internal.DoubleCheck.get(DoubleCheck.java:45)
at org.opentripplanner.graph_builder.GraphBuilderDataSources_Factory.get(GraphBuilderDataSources_Factory.java:50)
at org.opentripplanner.graph_builder.GraphBuilderDataSources_Factory.get(GraphBuilderDataSources_Factory.java:14)
at dagger.internal.DoubleCheck.getSynchronized(DoubleCheck.java:54)
at dagger.internal.DoubleCheck.get(DoubleCheck.java:45)
at org.opentripplanner.standalone.configure.DaggerLoadApplicationFactory$LoadApplicationFactoryImpl.graphBuilderDataSources(DaggerLoadApplicationFactory.java:225)
at org.opentripplanner.standalone.configure.LoadApplication.validateConfigAndDataSources(LoadApplication.java:51)
at org.opentripplanner.standalone.OTPMain.startOTPServer(OTPMain.java:120)
at org.opentripplanner.standalone.OTPMain.main(OTPMain.java:55)
I debugged this with Claude and I found the suggestions not all that convincing.
Therefore I would like to hear it straight from the source: are Jspecify-Nullable-annotation provider methods supported or should I keep using javax.annotation.Nullable for that?
Since we recently upgraded to Java 25 we wanted to migrate our project to jspecify and stop using
javax.annotations.Nullable:We have run into problems with our nullable provider methods, which look like this:
They cause runtime exceptions when I swap
javax.annotation.Nullablewithorg.jspecify.annotations.Nullable:I debugged this with Claude and I found the suggestions not all that convincing.
Therefore I would like to hear it straight from the source: are Jspecify-Nullable-annotation provider methods supported or should I keep using
javax.annotation.Nullablefor that?