I am trying to use hk2 DI in jersey and I have read some texts on the matter. (Most are out dated I think)
Currently I have a class that extends ResourceConfig:
public class MyApplication extends ResourceConfig{
public MyApplication(){
register(new AbstractBinder() {
@Override
protected void configure() {
bind(AuthenticationServiceImpl.class).to(AuthenticationService.class);
bind(PropertiesHandlerImpl.class).to(PropertiesHandler.class).in(Singleton.class);
}
});
packages(true, "com.myclass"); }
}
and in another class I try to inject one of these bound classes:
public class JDBCConnectionStrategy implements DatabaseConnectionStrategy {
private Connection connection;
@Inject
PropertiesHandlerImpl propertiesHandler;
public JDBCConnectionStrategy() throws SQLException{
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String host = propertiesHandler.getProperty("host");
String userName = propertiesHandler.getProperty("userName");
String password = propertiesHandler.getProperty("password");
//Create a connection
this.connection = DriverManager.getConnection(host, userName, password);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
}
....
}
declared thus:
@Singleton
@Service
public class PropertiesHandlerImpl implements PropertiesHandler {...}
Issue: I get the following error when I startup my app
WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 2 java.lang.NullPointerException
at com.myclass.JDBCConnectionStrategy.<init>
Update:
I should add that I added the application package to the scanned path in the web.xml:
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.myclass.system.CmisApplication</param-value>
</init-param>
So I see a few things wrong.
The injected type needs to be the "contract" type, as in bind(Impl).to(Contract)
. The to(Contract)
specifies what should be the "advertised" type to inject.
So instead of trying to inject PropertiesHandlerImpl
, you would inject with the contract PropertiesHandler
@Inject
PropertiesHandler handler;
I don't see how you are using the JDBCConnectionStrategy
. It's not configured in your AbstractBinder
, so I'm guessing you are just instantiating it yourself. This won't work. You need to also hook it up to the DI system and inject it.
Field injection happens after construction. So you can't use the service inside the constructor unless you inject it into the constructor.
@Inject
public JDBCConnectionStrategy(PropertiesHandler handler) {
}