2013-02-23 4 views
1

j'ai une interface comme ceci:Enterprise Beans Accès via une interface à distance avec @EJB

@Remote 
public interface ClientDataAccessRemote 

Et l'EJB implémente:

@Stateless 
public class ClientDataAccess implements ClientDataAccessRemote 

Et dans le client distant, je peux accéder à l'EJB avec ceci:

@EJB 
private static ClientDataAccessRemote clientDataAccess; 

C'est tout ce que j'ai fait et cela fonctionne. Le client et l'EJB résident sur le même serveur. Cela fonctionnerait-il encore s'ils étaient séparés? Et comment le conteneur trouverait-il l'EJB avec cette interface? J'ai implémenté ceci avec Netbeans et je n'avais pas besoin de spécifier de localisation ou quelque chose comme ça. Comment cela marche-t-il?

Répondre

1

Malheureusement, l'annotation @EJB ne fonctionne que pour les injections locales (JVM unique). Pour les hôtes distincts, vous devez utiliser la recherche JNDI simple. Autant que je sache, il existe des solutions propriétaires non portables pour effectuer des injections de dépendance à distance, comme pour le serveur WebLogic (here), mais je ne le ferais pas.

JNDI travaux de consultation, mais est trop compliqué et assez laid:

  • vous devez savoir fournisseur de serveur et ajouter ses bibliothèques clientes aux dépendances de votre application,
  • vous polluez application avec:
    • formats d'URI propres au fournisseur cryptique
    • numéro de port du service de nommage spécifique au fournisseur (souvent par défaut à 1099, mais qui sait à coup sûr ...)
    • fournisseur spécifique modèle jndi-name

est par exemple recherche ici pour haricot hébergés sur instance distante JBoss 4.x:

Properties properties = new Properties(); 
properties.put(Context.INITIAL_CONTEXT_FACTORY, 
    "org.jnp.interfaces.NamingContextFactory"); 
properties.put(Context.URL_PKG_PREFIXES, 
    "org.jboss.naming:org.jnp.interfaces"); 
properties.setProperty(Context.PROVIDER_URL, "localhost:1099"); 
InitialContext context = null; 
ClientDataAccessRemote cl = null; 
try { 
    context = new InitialContext(properties); 
    cl = (ClientDataAccessRemote) context.lookup("ClientDataAccess/remote"); 
} catch (NamingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

Compte tenu de votre EJB fait partie de l'oreille, vous devez préfixer nom de EJBean avec le nom de l'oreille:

cl = (ClientDataAccessRemote) context.lookup("MyEAR/ClientDataAccess/remote"); 

exemple ci-dessus est JBoss spécifique, je ne suis même pas sûr si cela va fonctionner avec des séries JBoss 5.x sans modifications.

Apparemment, la spécification EJB 3.1 apporte une certaine unification à la dénomination jndi, mais je n'ai pas encore eu le plaisir de la travailler.

Si cet exemple vous effrayait un peu, une meilleure solution serait peut-être d'exposer votre EJB en tant que services Web (style SOAP ou REST). Il apporte des problèmes, mais il est portable au moins.

+0

Comme vous le savez, certains serveurs d'applications prennent en charge l'utilisation de l'annotation @EJB pour cibler les beans distants, y compris JBoss (selon la réponse de rodrigo) et Glassfish. La portabilité est parfois une propriété utile, mais cela dépend de la situation. De même, les services Web ne sont pas intrinsèquement supérieurs à RMI: cela dépend de la situation. – DavidS

Questions connexes