3

I have a jersey 2 project with Guice used for DI (via hk2 bridge). Spring JDBC is used for DB calls and is configured via Guice. I'm running it locally with embedded tomcat. This setup works fine for the application i.e. i'm able to access database in my jersey resources

Now I want to write test cases for the application where I need database access for initial setup, but I'm getting NullPointerException on injected objects.

Main file (here inject gives null value)

public class StartApp {
    @Inject
    private JdbcTemplate jdbcTemplate;

    public static void main(String[] args) throws Exception {
        startTomcat();
    }

    private static void startTomcat() throws Exception {
        String webappDirLocation = "src/main/webapp/";
        Tomcat tomcat = new Tomcat();
        String webPort = System.getProperty("app.port", "8080");
        tomcat.setPort(Integer.valueOf(webPort));
        tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
        tomcat.start();
        new StartApp().initDatabase();
        tomcat.getServer().await();
    }

    public void initDatabase() throws Exception {
        String sql = new String(Files.readAllBytes(Paths.get(StartApp.class.getClassLoader().getResource("db_base.sql").toURI())), "UTF-8");
        jdbcTemplate.execute(sql);
    }
}

JdbcTemplate inject fails here only. In the actual jersey resources, it works fine.

web.xml (showing guice part only)

<filter>
    <filter-name>Guice Filter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>Guice Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <listener-class>MyGuiceServletContextListener</listener-class>
</listener>

MyGuiceServletContextListener

public class MyGuiceServletContextListener extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new AbstractModule() {

            @Override
            protected void configure() {
                bind(JdbcTemplate.class).toProvider(JdbcTemplateProvider.class).in(Scopes.SINGLETON);
            }
        });
    }
}

JerseyConfig

public class JerseyConfig extends ResourceConfig {
    @Inject
    public JerseyConfig(ServiceLocator serviceLocator, ServletContext servletContext) {
        packages("resources");

        GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
        GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
        guiceBridge.bridgeGuiceInjector((Injector) servletContext.getAttribute(Injector.class.getName()));
    }
}

1 Answer 1

0

Since tomcat starts in a different process, guice injector created in Jersey App is not accessible in StartApp. Guice injector have to be created in StartApp to get JdbcTemplate instamnce

JdbcTemplate jdbcTemplate = Guice.createInjector(new PaymentGatewayModule()).getInstance(JdbcTemplate.class);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.