2017-08-06 5 views
0

J'essaie de faire des recherches EJB par ServiceLocator sans coder en dur le nom JNDI, en utilisant uniquement le nom de l'interface locale. Le problème est que les EJB sont distribués dans d'autres modules (JAR). Par exemple, j'ai ce scénario:Recherche d'un EJB par interface locale dans un projet multi-module

projet xxx:

@Stateless 
class EjbXBean implements EjbX { 

} 

Enregistré par le conteneur avec le JNDI: java:global/project-xxx/EjbXBean

projet yyy:

@Stateless 
class EjbYBean implements EjbY { 

} 

Enregistré par le conteneur avec le JNDI: java:global/project-yyy/EjbYBean 01 Les termes EjbX et EjbY sont tous deux @Local. Je voudrais obtenir l'EJB faire ce que dans un autre module:

EjbX ejbx = ServiceLocator.lookup(EjbX.class); 
EjbY ejby = ServiceLocator.lookup(EjbY.class); 

Mais je ne sais pas quel est le module (projet-yyy ou d'un projet-xxx) uniquement avec l'interface locale à l'intérieur du ServiceLocator. Je ne peux pas faire que la recherche en utilisant le nom complet de JNDI avec le nom du module:

EjbX ejbx = ServiceLocator.lookup("java:global/project-yyy/EjbXBean"); 
EjbY ejby = ServiceLocator.lookup("java:global/project-yyy/EjbYBean"); 

J'essaie de comprendre ce qui est la meilleure pratique dans ce cas, parce que je ne sais pas si le hardcoded le nom JNDI est une bonne pratique ou pas dans le monde JavaEE. J'utilise OpenEjb 4.7.4 pour les tests de développement et d'intégration, Wildfly 10.1.0 pour la production.

Mise à jour

que je peux pour cela en utilisant CDI dans wildfly 10.1.0:

@Override 
public Object lookup(Class<?> type, Annotation... annotations) throws NamingException { 
    BeanManager manager = CDI.current().getBeanManager(); 
    Iterator<Bean<?>> beans = manager.getBeans(type, annotations).iterator(); 

    if (!beans.hasNext()) { 
     throw new NamingException("CDI BeanManager cannot find an instance of requested type " + type.getName()); 
    } 
    Bean<?> bean = beans.next(); 
    CreationalContext<?> ctx = manager.createCreationalContext(bean); 
    return manager.getReference(bean, type, ctx); 
} 

Et pour appeler:

MyClass.lookup(EjbX.class); 

Mais je ne voudrais pas utiliser CDI parce que dans I had some problems to put this to work un conteneur intégrable (OpenEJB).

Répondre

1

Pourquoi avez-vous besoin de différents modules? Avoir tout en un WAR vous permettrait de seulement @Inject les haricots. (Vous avez seulement besoin d'un beans.xml dans chaque guerre qui contient des haricots gérés)

Je ne suis pas sûr si la normalisation de la dénomination fonctionne avec openejb et wildfly. puisque les deux sont ejb 3.1, il devrait mais avez-vous vérifié si vos noms respectent la norme? J'ai eu dans le passé des problèmes lors de l'utilisation des files d'attente et des sujets. peut-être jboss naming ejb3.1 peut aider.

Pour vous assurer que les noms sont utilisables, peut-être vous devriez envisager d'utiliser arquillian pour les tests. Mais je voudrais me débarrasser de ces problèmes Namingservice avec les haricots locaux du tout.

Aussi, je ne voudrais pas utiliser OpenEJB pour les tests. Je sais que c'est embarquable mais les différences sont grandes. Un autre CDI-Container, peut-être eclipselink au lieu d'hiberner. Les deux font une grande différence. Je ne voudrais pas tester sur ceux-ci et déployer en wildfly.

Si vous voulez quelque chose intégrable basé sur la soudure et en utilisant Mise en veille prolongée peut-être envisager cdi-unit ou ejb-cdi-unit (ok que l'on est mon projet, donc je ne suis pas complètement impartial ;-))

+0

Salut! J'utilise OpenEJB pour effectuer une transition à partir d'un autre conteneur EJB inconnu (appelé MyContainer, qui utilise Jetty to WebApp). Il est aussi utilisé pour le développement et les tests de sélénium, dans une configuration très similaire à celle-ci: http://tomee.apache.org/functional-testing-with-openejb,-jetty-and-selenium.html (exemple unique que j'ai trouvé avec OpenEJB et Jetty). Je peux mettre ça au travail en utilisant des noms JNDI complets, mais maintenant nous migrons vers Java8/Wildfly et rien ne fonctionne plus, parce que la recherche d'EJB utilise BeanManager et l'interface @Local (je change OpenEJB en TomEE, pour le CDI). – Dherik

+0

Bonjour, si vous essayez simplement de tester votre service web de repos, il existe de bonnes alternatives en utilisant Weld, regardez peut-être [ex7-plus simple] (https://github.com/1and1/ejb-cdi-unit/tree/master/examples/ex7-plus simple). En ce qui concerne la recherche, je n'ai pas encore compris, quel est le vrai problème. Comment l'ancienne application tisse-t-elle ces modules ensemble? JNDI, je présume. Pourquoi ne pouvez-vous pas laisser CDI scanner les beans et tout assembler par lui-même, sans faire aucune recherche? – aschoerk

+0

Oui, par JNDI. Dans la nouvelle version, ils arrêtent d'utiliser JNDI et utilisent maintenant CDI pour obtenir les EJB, mais nous avons quelques problèmes (https://stackoverflow.com/q/45538143/2387977) et j'essaie d'utiliser à nouveau JNDI et laisse ce problème CDI pour l'avenir. Vous comprendrez l'ensemble du scénario dans cette autre question SO :) – Dherik