2017-09-28 4 views
0

J'utilise guice pour injecter mes dépendances. Mon IDE est IntelliJ 2017.2.5. Lorsque j'exécute le code suivant, ma méthode main continue à fonctionner et n'est pas arrêtée. Lorsque je retire le DI, le processus s'arrête avec Process finished with exit code 0.Guice Injector maintient l'exécution de l'application

La classe avec la méthode main:

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"); 
} 
} 

Le 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(); 
    } 
} 

}

Si j'exécute Test.main tout va bien, JPA est initialisés correctement et je vois ce qui suit sortie:

EM open 
Done 

Pour une raison quelconque, l'application est toujours en cours d'exécution. Je dois terminer l'application manuellement. Screenshot

Comment résoudre ce problème?

Répondre

2

vous êtes ne libère pas les ressources acquises (connexions DB et threads non-démon).

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 
    } 
} 

Techniquement juste stoping PersistService devrait être suffisant dans ce cas, mais en général, vous devriez fermer EntityManager quand il est plus nécessaire. La façon dont vous êtes censé faire cela avec Guice JPA est soit en utilisant l'annotation @Transactional soit en terminant manuellement l'unité de travail correspondante (comme dans l'exemple ci-dessus).

+0

Résolu! Merci! –

0

Vous avez probablement des connexions DB ouvert/threads en attente d'être fermé explicitement Puisque vous utilisez Hibernate assurez-vous que vous fermez() SessionFactory à la fin (si c'est ce que vous utilisez)

En IntelliJ vous pouvez obtenir la décharge de fil pour voir quels fils sont toujours en cours d'exécution/en attente d'être fermé

enter image description here

Vérifiez que pour voir ce que vous avez manqué

+0

Je ne savais pas cela - merci pour l'indice! –