Datasource injection problems in Jetty 10

109 Views Asked by At

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?

1

There are 1 best solutions below

0
pbuchheit On

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

public EntityManager getEntityManager(Datasource ds){}

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?