简体   繁体   中英

Guice Injector keeps application running

I am using guice to inject my dependencies. My IDE is IntelliJ 2017.2.5. When I run the following code my main method keeps on running and is not stopped. When I remove the DI the process stops with Process finished with exit code 0 .

The class with the main method:

public class Test {

@Inject
Provider<EntityManager> em;

public void test() {
    if(em.get().isOpen())
        System.out.println("EM open");
}

public static void main(String args[]) {
    final Injector injector = createInjector(new DatabaseModule());
    Test app = injector.getInstance(Test.class);
    app.test();
    System.out.println("Done");
}
}

The DatabaseModule :

public class DatabaseModule extends AbstractModule {

private static final String PU_NAME = "my_pu";

@Override
protected void configure() {
    install(new JpaPersistModule(PU_NAME));
    bind(JPAInitializer.class).asEagerSingleton();
}

@Singleton
private static class JPAInitializer {
    @Inject
    public JPAInitializer(final PersistService service) {
        service.start();
    }
}

}

If I execute Test.main all goes well, JPA is initialised properly and I see the following output:

EM open
Done

For some reason the application is still running after that. I have to terminate the application manually. 截图

How do I fix this?

You're not releasing acquired resources (DB connections and non-daemon threads).

public class Test {

  @Inject
  Provider<EntityManager> em;

  @Inject
  UnitOfWork unitOfWork;

  public void test() {
    if(em.get().isOpen())
        System.out.println("EM open");
    unitOfWork.end();  // releases DB connection
  }

  public static void main(String args[]) {
    final Injector injector = createInjector(new DatabaseModule());
    Test app = injector.getInstance(Test.class);
    app.test();
    System.out.println("Done");
    injector.get(PersistService.class).stop();  // releases resources acquired by the underlying EntityManagerFactory
  }
}

Technically just stoping PersistService should be enough in this case, but in general you should close EntityManager when it's not needed anymore. The way you're supposed to do this with Guice JPA is either by using @Transactional annotation or manually ending corresponding unit of work (as in the example above).

You probably have some open DB connections/threads waiting to be explicitly closed Since you're using Hibernate make sure you close() the SessionFactory at the end (if that's what you're using)

In IntelliJ you can get the thread dump to see which threads are still running/waiting to be closed

在此处输入图片说明

Check that to see what you missed

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