[Prévia] [Próxima] [Prévia por assunto] [Próxima por assunto]
[Índice cronológico] [Índice de assunto]

Uso de ejb-ref inter-servidores



Todo mundo teve ou está tendo problema para, de dentro de um EJB1 rodando
no servidor 1, pegar uma referência para o home de um EJB2 implantado no
servidor 2. Tem vários jeitos de fazer isso:

(1) Usando o JNP (serviço de nomes proprietário do JBoss). Funciona, mas 
    conceitualmente não é uma boa solução pois requer que o servidor 2 
    seja JBoss.

(2) Fazendo o EJB1 usar, via JNDI, o serviço de nomes CORBA do servidor 2.
    Funciona, desde que se tome o cuidado de contar ao provedor JNDI qual 
    é o ORB que ele deve utilizar (via propriedade java.naming.corba.orb).
    Essa solução é feia: como o valor da propriedade java.naming.corba.orb 
    não pode ser colocado num arquivo de configuração tipo jndi.properties
    (pois o ORB não é "stringficável"), você é obrigado a "sujar" o seu 
    código com algo como
    env.put("java.naming.corba.orb", initialCtx.lookup("java:comp/ORB"));

(3) Fazendo o EJB1 usar uma ejb-ref. O código do EJB1 dá lookup na
    ejb-ref no contexto de nomes usual. A ejb-ref é definida no
    ejb-jar.xml e no jboss.xml do EJB1, de modo a apontar para o
    home do EJB1, que pode estar implantado em qualquer servidor
    de aplicações compatível com as especificações EJB/J2EE.

Deixei em 

  http://www.ime.usp.br/~reverbel/SMA/exemplos/test-iiop-ejb-ref.zip

um exemplo completo de ejb-ref inter-servidores. O EJB referenciado
pela ejb-ref roda em localhost:3628. Ele é registrado no serviço
de nomes CORBA em localhost:3628 sob o nome "ejb/SimpleConverter".
O EJB que define (e usa) a ejb-ref roda em localhost:3528. A ejb-ref
associa o nome "java:comp/env/ejb/ConverterHome" ao home do EJB
remoto.

Código de lookup no EJB que usa a ejb-ref:

    Context iniCtx = new InitialContext(); 
    Object objref = iniCtx.lookup("java:comp/env/ejb/ConverterHome");
    ConverterHome home = (ConverterHome) 
    PortableRemoteObject.narrow(objref, ConverterHome.class);


Definição da ejb-ref no ejb-jar.xml deste EJB:

<ejb-ref>
  <description>
    The ConverterHome used by this ConverterFrontEnd.
  </description>
  <ejb-ref-name>ejb/ConverterHome</ejb-ref-name> 
  <ejb-ref-type>Session</ejb-ref-type> 
  <home>converter.interfaces.ConverterHome</home> 
  <remote>converter.interfaces.Converter</remote> 
</ejb-ref>


Complemento da definição da ejb-ref no jboss.xml deste EJB:

<ejb-ref>
  <ejb-ref-name>ejb/ConverterHome</ejb-ref-name>
  <jndi-name>corbaname:iiop:1.2@localhost:3628#ejb/SimpleConverter</jndi-name>
</ejb-ref>

Repare que é usada uma URL tipo corbaname contendo o nome 
(ejb/SimpleConverter) sob o qual o home EJB alvo está registrado no 
serviço de nomes CORBA em localhost:3628. 

Esta é a maneira limpa de lidar com referências inter-servidores. 
Infelizmente ela NÃO vem habilitada na distribuição do JBoss. :-(
Para que ela funcione é preciso mudar duas coisinhas:

1) O arquivo server/config-name/conf/jndi.properties vem assim:

# DO NOT EDIT THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING
#
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Igore o comentário ameaçador, edite esse arquivo e troque a linha 
java.naming.factory.initial=... por

java.naming.factory.initial=org.jboss.iiop.naming.ORBInitialContextFactory

O propósito dessa alteração é fazer com que a resolução do
corbaname use o ORB do JBoss e não um ORB novo, sem interceptadores.

2) Adicione isto ao arquivo jacorb.properties em
server/config-name/conf/jndi.properties:

# map objectKey "NameService" to "JBoss/Naming/root" to allow
# corbaname URLs that don't specify an objectKey (and default 
# to the objectKey "NameService") to resolve correctly
jacorb.orb.objectKeyMap.NameService=JBoss/Naming/root

Esses são os dois acertos que habilitam ejb-refs inter-servidores.
A mudança 1) é necessária no servidor que define e usa uma ejb-ref.
A mudança 2) é necessária no servidor que contém o EJB alvo da
ejb-ref. O melhor é usar sempre servidores com as duas mudanças!
A distribuição do JBoss já deveria ter sido corrigida de modo a
incorporar essas mudanças.

Reverbel