EJB 3 Interface e Remota

ola galera,

estou precisando criar um ejb que seja local e remoto ao mesmo tempo, detalhe estou utilizando o glassfish.
alguma ideia?

Crie uma interface de negócio, e depois outras duas classes implementando essa interface, sendo em uma você anotará com o @Remote e a outra com o @Local

sim, mais neste caso vou ter duplicidade de código, pois vou ter que implementar os métodos no ejb local e remoto

Acredito que o Sou mais Java se confundiu. Na verdade seria o inverso. Voce teria de criar 2 interfaces. Cada uma voce anotaria com a respectiva annotation.

Exemplo:

@Local
public interface MeuServicoLocal {

}

@Remote
public interface MeuServiceRemoto {

}

public class MeuServiceBean implements MeuServiceLocal, MeuServicoRemoto {

}

Outra alternativa que nao lembro se funciona (provavelmente nao… :lol: ), seria de repente de voce criar somente 1 interface. Dai imagino que seria algo assim:

public interface MeuServico {

}

@Remote(value = MeuServico.class)
@Local(value = MeuServico.class)
public class MeuServicoBean implements MeuServico {

}

}

[]s

fiz desta forma:

public interface MeuServicoLocal {  
   
}  
   
public interface MeuServiceRemoto {  
  
}  

@Stateless(mappedName="MeuServicoBean")
@Local(MeuServicoLocal.class)
@Remote(MeuServicoRemoto.class)
 
public class MeuServiceBean implements MeuServiceLocal, MeuServicoRemoto {  
  
}  

porém não estou conseguindo fazer lookup local. se eu tirar a anotação @Remote e fazer o lookup assim ( new InitialContext().lookup(“java:module/NoticiaEJB”); ) funciona.

alguma ideia?

obrigado

thiagohneves, o lookup remoto se faz usando java:global:/NOME_DO_EAR/NOME_DO_MODULO_EJB/NOME_DO_EJB. Foi assim que voce usou suas chamadas remotas?

Além disso atente para os maming-conventions, embora não seja obrigatório é uma boa prática.

<nome>Bean - implementação <nome>Remote - interface remota <nome>Local - interface local

Se você tiver rodando dentro da mesma JVM onde você está tentando fazer lookup, voce consegue injetar utilizando InitialContext, senão não vai funcionar mesmo, tanto porque é um EJB Local. Eu não tenho certeza como os EJBs no Glassfish são publicados, porém, não vejo a necessidade de você ter de usar o InitialContext para faze-lo.

Aonde você quer injetar esse EJB?

Dependendo onde vc o fizer, basta colocar a anotação @EJB e ele já estará la injetado pra você;

Exemplo:

public class MeuSessionBeanFacade implements MeuSessionFacade {

  @EJB
  private MeuService meuService;
}

O mesmo vale dentro de componentes gerenciados pelo Container, como Servlets, ManagedBeans, etc…

[quote=garcia-jj]thiagohneves, o lookup remoto se faz usando java:global:/NOME_DO_EAR/NOME_DO_MODULO_EJB/NOME_DO_EJB. Foi assim que voce usou suas chamadas remotas?

Além disso atente para os maming-conventions, embora não seja obrigatório é uma boa prática.

<nome>Bean - implementação <nome>Remote - interface remota <nome>Local - interface local[/quote]

estou fazendo lookup pelo valor definido em mappedName
@Stateless(mappedName=“NomeBean”);

[quote=alexmdo]Se você tiver rodando dentro da mesma JVM onde você está tentando fazer lookup, voce consegue injetar utilizando InitialContext, senão não vai funcionar mesmo, tanto porque é um EJB Local. Eu não tenho certeza como os EJBs no Glassfish são publicados, porém, não vejo a necessidade de você ter de usar o InitialContext para faze-lo.

Aonde você quer injetar esse EJB?

Dependendo onde vc o fizer, basta colocar a anotação @EJB e ele já estará la injetado pra você;

Exemplo:

public class MeuSessionBeanFacade implements MeuSessionFacade {

  @EJB
  private MeuService meuService;
}

O mesmo vale dentro de componentes gerenciados pelo Container, como Servlets, ManagedBeans, etc…[/quote]

Com a anotação @EJB ele injeta local? mesmo que o ejb seja remoto? caso sim, dai não preciso criar a interface local, a não para alterar a visibilidade de metodos para acesso local e remoto.

Correto. Isso é independente se é local ou remoto. É o famosa IoC.

Agora, você precisa levar em consideração o seguinte: Trabalhar somente com EJB Remoto não é a resposta. Você precisa levar em conta certos fatores em optar pelo Remoto ao Local.

Remoto costuma ser mais custoso para se trabalhar, pois existe todo o processo de serialização que o container realiza. Com o local, isso não acontece, o que significa tb que vc trabalha com os objetos diretos dentro da mesma JVM. Se esses EJBs forem consumidos somente dentro da mesma aplicação (o que é extremamente comum), não vejo necessidade de expô-los como remoto. Vai muito da decisão da arquitetura.

Por outro lado, você poderia pensar em fazer o seguinte: os beans que acessam a camada de persistencia (famosos DAOs), vc poderia deixá-los como Local. Já os session facades que acessam os DAOs, como Remoto. Não é uma regra, mas pode suprir suas necessidades. De qualquer forma, pra todos os casos, o uso da API InitialContext na versão 3.0 da especificação do EJB, não é necessária se você estiver tentando injetar os EJBs dentro da mesma JVM que o serviço do Glasshfish está rodando.

Do contrário, se vc tiver um servidor A que tente injetar um EJB Remoto no servidor B, dai sim vc necessitara fazer uso do InitialContext, ficou claro?

Na minha aplicação os EJBs vão ficar em outro servidor os outros aplicativos em outros servidores vão consumir esses EJBs, dai a necessidade de serem remotos. A questão do local é justamente para o EJB (no caso remoto) acessar outro EJB dentro da mesma aplicação e/ou dentro do mesmo servidor. Com a injeção de dependências resolvo este problema, minha dúvida era como ia se dar esse acesso (local ou remoto).

Muito obrigado pela ajuda. Valeu!!!

[quote=thiagohneves][quote=garcia-jj]thiagohneves, o lookup remoto se faz usando java:global:/NOME_DO_EAR/NOME_DO_MODULO_EJB/NOME_DO_EJB. Foi assim que voce usou suas chamadas remotas?

Além disso atente para os maming-conventions, embora não seja obrigatório é uma boa prática.

<nome>Bean - implementação <nome>Remote - interface remota <nome>Local - interface local[/quote]

estou fazendo lookup pelo valor definido em mappedName
@Stateless(mappedName=“NomeBean”);[/quote]

Isso que eu falei são as coding conventions da Sun para o nome das classes, e não para o seu lookup. http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/EJBConcepts8.html

Desculpe, mas fiquei com uma dúvida. Afinal você quer rodar EJB remoto ou local? Fiquei na dúvida porque em um post entendi remoto, no outro local. Não sei se você sabe disso, mas um EJB pode ser local e remoto. Vocẽ pode criar uma interface local e uma remota e fazer seu EJB implementar ambas interfaces. Assim você pode disponibilizar tanto métodos locais como remotos.

Eu lí certa vez que isso não era aconselhado, mas como nunca mais achei esse link eu ignorei esse “desaconselho”.

Abraços

Sobre as convenções muito obrigado.

Sobre o ejb gostaria que ele fosse local e remoto ao mesmo tempo. Porém tive problemas para implementar no glassfish, no que diz respeito a lookup.

Aconteceu os seguintes erros, lookup remoto funciona corretamente, porém ao fazer lookup local não conseguia achar o bean. Mas se eu tirar a anotação @Remote e deixar somente a @Local funciona. Outro detalhe e quando faço um lookup pelo valor definido em @Stateless(mappedName=“MeuBean”) consegue encontrar, mais não posso acessar os metodos via interface local da pois, da um erro de cast pois não pode converter a interface remota para a local.

Não sei se ficou claro…

Ressuscitando…

Criei um JAR de um EJB3 (Stateless Session Bean Remoto) e depois um EAR, e coloquei o JAR do EJB como componente desse EAR, tudo pelo Eclipse.
Estou usando Glassfish 2 como servidor de aplicação.

Daí estou querendo chamar esse EJB de um servlet, de uma aplicação WAR.

No Servlet estou tentando acessar o EJB assim:

[code] bean = (EJB2Remote) ctx.lookup(“java:global/NOME_do_EAR/NOME_do_JAR/NOME_do_EJB”);

		String resposta=null;
		resposta=bean.getAloMundo();[/code]

Mas está dandoo seguinte erro:
No object bound to name java:global/NOME_do_EAR/NOME_do_JAR/NOME_do_EJB

Também tentei fazer deploy do EJB separado, mas deu “No object bound” também…

Roger75, portable global JNDI names só virou padrão no JEE5+, portanto você precisa ter no mínimo Glassfish 3.

Valeu.

Tentei no Glassfish 3, mas deu erro:

Segui o que diz esse FAQ sobre EJB:
http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#What_is_the_syntax_for_portable_global_

No Servlet tentei pegar a instância do EJB assim:

Não tinha que dar certo?

java:global[/<app-name>]/<module-name>/<bean-name>