I'm in the process of migrating a jetty web app from jetty 9 to jetty 10. We are using google guice to do dependency injection. Currently the guice module looks like this:
public abstract class GuiceModule extends AbstractModule {
@Provides
@Singleton
public EntityManager getEntityManager()
{
PersistenceProviderResolverHolder.setPersistenceProviderResolver(new PersistenceProviderResolver() {
private final List<PersistenceProvider> providers_ = Arrays.asList((PersistenceProvider) new HibernatePersistenceProvider());
@Override
public List<PersistenceProvider> getPersistenceProviders() {
return providers_;
}
@Override
public void clearCachedProviders() {
// TODO Auto-generated method stub
}
});
final EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPU");
final EntityManager em = emf.createEntityManager();
return em;
}
private static final String NAV_DS = "java:comp/env/jdbc/NavDS";
@Provides
public Context getContext() throws NamingException
{
if( context == null)
{
context = new InitialContext();
context.createSubcontext("java:comp/env");
context.createSubcontext("java:comp/env/jdbc");
}
return context;
}
@Provides
@Singleton
public DataSource getNavDS() throws NamingException {
BasicDataSource ds = new BasicDataSource();
ds.setUrl("jdbc:h2:mem:myDB;create=true;MODE=MSSQLServer;DATABASE_TO_UPPER=FALSE;");
Context context = getContext();
context.rebind(NAV_DS, ds);
return ds;
}
@Singleton
@Provides
public ExportData getExportData(DataSource ds)
{
Map<String, String> testData = new HashMap<String,String>();
testData.put("Customer_R", "src/test/resources/nav_customers.csv");
return new ExportData(ds, testData);
}
}
We use those field to inject a test class like:
public abstract class AbstractTest {
@Inject
public Configuration cfg;
@Inject
public ExportData exportData;
@Inject
protected EntityManager entityManager;
}
In jetty 9 this all worked fine. The entity manager provider was able to lookup the datasource defined in persistence.xml . For some reason that doesn't seem to work in jetty 10. When the entity manager provider is called it throws a NameNotFoundException for 'NavDS'.
Any ideas what might be causing this? Is there some migration step I missed?
I managed to figure out the problem. I never set up an explicit dependency between the entity manager provider and the datasource provider. I was getting away with it in the old build because there was another provider method that DID have a dependency on datasource and that provider was getting injected first. When I updated to a newer version of guice, something about the injection order changed.
I simply needed to change the method definition for entity manager to
Once I did that the code worked again.
One question I still have is whether there is a better way to do this. I don't actually use the datasource directly in the provider method, it just needs to have been added to the context before Hibernate does the lookup. Is there a better way to ensure the dependencies for the provider method without adding a parameter that never gets used?