简体   繁体   中英

Null Pointer Exception - Dependency Injection - Google Guice

I am getting a NullPointerException while injecting a dependency inside Jersey's reader interceptor that I created to intercept a particular incoming request.

Here is the code for the ReaderInterceptor I have created, where in I am trying to inject the required dependency.

public class RegisterServiceInterceptor implements ReaderInterceptor {

    @Inject
    private CustomerBackendManager customerBackendManager;

    public static final Logger LOGGER = LoggerFactory.getLogger(RegisterServiceInterceptor.class);

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
        InputStream is = context.getInputStream();
        String body = new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
        ObjectMapper mapper = new ObjectMapper();
        try {
            SampleObject sampleObject = mapper.readValue(body, SampleObject.class);
            customerBackendManager.createDatabase(sampleObject.getDatabaseName());
        } catch (JsonGenerationException | JsonMappingException e) {
            LOGGER.info(e.getMessage());
        }
        InputStream in = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
        context.setInputStream(in);
        return context.proceed();
    }

}

I am getting NPE at the line customerBackendManager.createDatabase(...); . The dependency didn't get injected into this class.

I have defined the configuration for this dependency as

public class ExampleAddonMicroserviceModule extends AbstractModule
        implements ConfigurationAwareModule<ExampleAddonMicroserviceConfiguration> {

    @Provides
    @Singleton
    public CustomerBackendManager customerBackendManager(DBI dbi, Injector injector) {
        CustomerBackendManager manager = dbi.onDemand(CustomerBackendManagerImpl.class);
        injector.injectMembers(manager);
        return manager;
    }

    @Provides
    @Singleton
    public RegisterServiceInterceptor registerServiceInterceptor(DBI dbi, Injector injector) {
        RegisterServiceInterceptor manager = dbi.onDemand(RegisterServiceInterceptor.class);
        injector.injectMembers(manager);
        return manager;
    }
}

What additional configuration do I need to add to be able to add this dependency to this class?

I figured out the solution to this problem.

The issue was that Jersey expects the Interceptor class in the configuration, which it needs to call when the intercepting criteria is fulfilled, and that was causing the RegisterServiceInterceptor class to get initialized twice. Hence, the NPE in the RegisterServiceInterceptor class.

I had defined that configuration in a separate configuration file as

@Provider
public class ResourceFilteringConfiguration implements DynamicFeature {

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
        if (RegistrationService.class.equals(resourceInfo.getResourceClass())
                && resourceInfo.getResourceMethod().getName().equals("register")) {
            context.register(RegisterServiceInterceptor.class);
        }
    }

}

In the line context.register(RegisterServiceInterceptor.class); I was passing the RegisterServiceInterceptor class itself, which was causing it to initialize before the dependency configuration (mentioned in the question) was reached. So, this interceptor was getting initialized twice, which was causing this issue. I changed the configuration file code to

@Provider
public class ResourceFilteringConfiguration implements DynamicFeature {

    @Inject
    private RegisterServiceInterceptor registerServiceInterceptor;

    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
        if (RegistrationService.class.equals(resourceInfo.getResourceClass())
                && resourceInfo.getResourceMethod().getName().equals("register")) {
            context.register(registerServiceInterceptor);
        }
    }

}

As you must have noticed, the change I made was to pass an object of the RegisterServiceInterceptor to the configuration and it started working fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM