Ranjan
Ranjan

Reputation: 96

UncaughtException: java.lang.ExceptionInInitializerError

I am getting the following error while injecting ServiceGenerator.class.

I am trying to inject ServiceGenerator.Class from SignUpActivity.Class mainly used for retrofit api services generation and depends on Retrofit.Builder instance injected via Constructor injection that I have exposed from my ApplicationComponent.Class.

SignUpActivity.Class

Public class SignUpActivity extends AppCompatActivity {

  @Inject
  ServiceGenerator serviceGenerator;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_up);

    AppGenerator.getPresenterComponent().inject(this);

  }

  private void saveMobileNumberService(String mNumber) {

        MobileNumberService mobileService =
                serviceGenerator.createService(MobileNumberService.class);

        ..

  }

}

ServiceGenerator.Class

public class ServiceGenerator {
  private static Retrofit.Builder builder;

  @Inject
  public ServiceGenerator(Retrofit.Builder builder) {
    this.builder = builder;

  }

  private static Retrofit retrofit = builder.build();

  public static <S> S createService(Class<S> serviceClass) {
    return retrofit.create(serviceClass);

  }

}

NetModule.class

@Module
public class NetModule {

    ....

    @Singleton
    @Provides
      ServiceGenerator provideServiceGenerator(Retrofit.Builder builder) {
      return new ServiceGenerator(builder);
    }

    @Singleton
    @Provides
      Retrofit.Builder provideRetrofitBuilder() {
      Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl(baseUrl)
      return retrofitBuilder;
    }

}

ApplicationComponent.Class

@Singleton
@Component( modules = {AppModule.class, NetModule.class} )

public interface ApplicationComponent {

  ..

  Retrofit.Builder exposeRetrofit();
  ServiceGenerator exposeServiceGenerator();

}

PresentationComponent.Class

@PerActivity
@Component(modules = PresentationModule.class, dependencies = ApplicationComponent.class)

public interface PresenterComponent {
    void inject (SignUpActivity signUpActivity);
}

Error

I am getting the following error at runtime.

UncaughtException: java.lang.ExceptionInInitializerError
                                                             at com.project.android.dependencies.modules.NetModule.provideServiceGenerator(NetModule.java:80)
                                                                        at com.project.android.dependencies.modules.NetModule_ProvideServiceGeneratorFactory.get(NetModule_ProvideServiceGeneratorFactory.java:26)
                                                                        at com.project.android.dependencies.modules.NetModule_ProvideServiceGeneratorFactory.get(NetModule_ProvideServiceGeneratorFactory.java:10)
                                                                        at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
                                                                        at com.project.android.dependencies.components.DaggerApplicationComponent.exposeServiceGenerator(DaggerApplicationComponent.java:120)
                                                                        at com.project.android.dependencies.components.DaggerPresenterComponent$com_project_android_dependencies_components_ApplicationComponent_exposeServiceGenerator.get(DaggerPresenterComponent.java:327)
                                                                        at com.project.android.dependencies.components.DaggerPresenterComponent$com_project_android_dependencies_components_ApplicationComponent_exposeServiceGenerator.get(DaggerPresenterComponent.java:314)
                                                                        at com.project.android.presentation.frameworks.onboarding.SignUpActivity_MembersInjector.injectMembers(SignUpActivity_MembersInjector.java:26)
                                                                        at com.project.android.presentation.frameworks.onboarding.SignUpActivity_MembersInjector.injectMembers(SignUpActivity_MembersInjector.java:8)
                                                                        at com.project.android.dependencies.components.DaggerPresenterComponent.inject(DaggerPresenterComponent.java:162)
                                                                        at com.project.android.presentation.frameworks.onboarding.SignUpActivity.onCreate(SignUpActivity.java:79)
                                                                        at android.app.Activity.performCreate(Activity.java:6119)
                                                                        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
                                                                        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2491)
                                                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2618)
                                                                        at android.app.ActivityThread.access$800(ActivityThread.java:183)
                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1475)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:111)
                                                                        at android.os.Looper.loop(Looper.java:194)
                                                                        at android.app.ActivityThread.main(ActivityThread.java:5651)
                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                        at java.lang.reflect.Method.invoke(Method.java:372)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
                                                                     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'retrofit2.Retrofit retrofit2.Retrofit$Builder.build()' on a null object reference
                                                                        at com.project.android.presentation.entrypoints.ServiceGenerator.<clinit>(ServiceGenerator.java:47)
                                                                        at com.project.android.dependencies.modules.NetModule.provideServiceGenerator(NetModule.java:80) 
                                                                        at com.project.android.dependencies.modules.NetModule_ProvideServiceGeneratorFactory.get(NetModule_ProvideServiceGeneratorFactory.java:26) 
                                                                        at com.project.android.dependencies.modules.NetModule_ProvideServiceGeneratorFactory.get(NetModule_ProvideServiceGeneratorFactory.java:10) 
                                                                        at dagger.internal.DoubleCheck.get(DoubleCheck.java:47) 
                                                                        at com.project.android.dependencies.components.DaggerApplicationComponent.exposeServiceGenerator(DaggerApplicationComponent.java:120) 
                                                                        at com.project.android.dependencies.components.DaggerPresenterComponent$com_yangout_android_dependencies_components_ApplicationComponent_exposeServiceGenerator.get(DaggerPresenterComponent.java:327) 
                                                                        at com.project.android.dependencies.components.DaggerPresenterComponent$com_yangout_android_dependencies_components_ApplicationComponent_exposeServiceGenerator.get(DaggerPresenterComponent.java:314) 
                                                                        at com.project.android.presentation.frameworks.onboarding.SignUpActivity_MembersInjector.injectMembers(SignUpActivity_MembersInjector.java:26) 
                                                                        at com.project.android.presentation.frameworks.onboarding.SignUpActivity_MembersInjector.injectMembers(SignUpActivity_MembersInjector.java:8) 
                                                                        at com.project.android.dependencies.components.DaggerPresenterComponent.inject(DaggerPresenterComponent.java:162) 
                                                                        at com.project.android.presentation.frameworks.onboarding.SignUpActivity.onCreate(SignUpActivity.java:79) 
                                                                        at android.app.Activity.performCreate(Activity.java:6119) 
                                                                        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112) 
                                                                        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2491) 
                                                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2618) 
                                                                        at android.app.ActivityThread.access$800(ActivityThread.java:183) 
                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1475) 
                                                                        at android.os.Handler.dispatchMessage(Handler.java:111) 
                                                                        at android.os.Looper.loop(Looper.java:194) 
                                                                        at android.app.ActivityThread.main(ActivityThread.java:5651) 
                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                        at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) 
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)

I have exposed ServiceGenerator.Class from ApplicationComponent.Class and using PresentationComponent.Class to inject from SignUpActivity.Class. I am struggling to figure it out why I am getting this ExceptionInInitializerError.

Upvotes: 1

Views: 5297

Answers (2)

Sunil
Sunil

Reputation: 3504

Update Retrofit 2.8.1. it's resolved now.

Upvotes: 2

David Rawson
David Rawson

Reputation: 21487

There is a problem with your ServiceGenerator (see comments):

public class ServiceGenerator {
  private static Retrofit.Builder builder; //no!! use Dagger 2 @Singletons instead

  @Inject
  public ServiceGenerator(Retrofit.Builder builder) {
    this.builder = builder;

  }

  private static Retrofit retrofit = builder.build(); //no! don't do this

  public static <S> S createService(Class<S> serviceClass) {
    return retrofit.create(serviceClass);

  }
}

The builder.build() will be called before the Dagger 2 has provided the Builder through the constructor hence the null pointer exception.

Maintaining a static reference to Retrofit inside the ServiceGenerator is probably not the solution you want. Dependency injection and roll-your-own static singleton caching are like elves and dwarves - they don't co-exist well.

In fact, the whole ServiceGenerator is an extra layer of redirection that you probably don't need.

Why not configure Dagger 2 to provide Retrofit instead of Retrofit.Builder? Then you will not need to manage the instance of Retrofit yourself using the static field:

 @Singleton
 @Provides
  Retrofit provideRetrofit() {
  return new Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl(baseUrl)
        .build();
  }

Then if you still need the ServiceGenerator it would be much simpler:

public class ServiceGenerator {
    private final Retrofit retrofit;

    @Inject
    public ServiceGenerator(Retrofit retrofit) {
        this.retrofit = retrofit;
    }

    public static <S> S createService(Class<S> serviceClass) {
        return retrofit.create(serviceClass);
    }
}

Upvotes: 0

Related Questions