Como posso injetar um EJB de outro aplicativo no mesmo GlassFish Server?

Eu tenho dois aplicativos em execução no meu servidor glassfish local. Um para alugar bicylces e um para comprar bilhetes de trem. Agora eu queria chamar um ejb remoto do aplicativo de trem para permitir o aluguel de bicicletas para o horário escolhido, mas não tenho certeza de como fazê-lo. Eu já tentei algumas abordagens diferentes. Ambos os aplicativos estão em pacotes diferentes e o aplicativo de trem precisa conhecer a interface remota da bicicleta, mas não sei como fazer isso.

A interface remota (app bicyle):

@Remote public interface FahrradRemote { public List findAvaible(Date start, Date end); public void addAuftrag(Fahrrad fahrrad, Date startDate, Date endDate); public boolean login(String name, String passwort); } 

Bicycle EJB Quero ligar:

 @Stateless(name="FahrradService",mappedName="FahrradService") public class FahrradService implements javax.ejb.SessionBean, FahrradRemote, Serializable { @PersistenceContext private EntityManager em; Kunde customer; ... } 

Início do aplicativo de trem:

 @Named @SessionScoped public class BahnPM implements Serializable { private String startStation; private String zielStation; private String loginName; private String loginPasswort; private String customerName; private String startDateString; private Date startDate; private List available; private List stations; @EJB private BahnService service; @EJB(mappedName="FahrradService") private static FahrradRemote fahrradService; public BahnPM() { } ... } 

Erro eu recebo é uma exceção de class não encontrada, que eu posso entender porque é um aplicativo diferente e meu aplicativo de trem não sabe “FahrradRemote” mas como posso injetar esse EJB?

Em seu aplicativo de bicicleta, você precisa:

  • remova a anotação @Remote da sua interface FahrradRemote
  • adicione a anotação @Remote ao seu EJB FahrradService

Você pode seguir este trecho:

 @Remote(FahrradRemote.class) @Stateless public class FahrradService implements FahrradRemote, Serializable { .... // your code } 

(se você estiver usando o EJB 3.X, não é necessário que um EJB implemente explicitamente a interface SessionBean)

No seu aplicativo de trem:

 @EJB(name="FahrradService") private FahrradRemote fahrradService; 

(use o atributo name vez de mappedName ; e você não pode ter propriedades estáticas em um EJB sem estado)

Finalmente você tem que dizer ao container onde procurar pela implementação do EJB: crie o descritor glassfish-ejb-jar.xml e, dentro das tags glassfish-ejb-jar , coloque isto:

   BahnPM  FahrradService java:global/MyRemoteBeanModule/MyRemoteBean    

O nome JNDI portátil para o seu EJB remoto (o que chamei de java:global/MyRemoteBeanModule/MyRemoteBean ) está disponível nos logs do GlassFish quando você implanta o aplicativo de bicicleta.

Você deve ter um jar FahrradService-EJB e um jar FahrradService-client (nomes são exemplos, apenas tenha os dois jars). Seu IDE teria gerado ambos para você se você criou um EJB usando plugins / ferramentas do Jave EE.

Seu jar do EBJ e o jar do cliente serão empacotados com um dos aplicativos. A implantação do aplicativo estabelecerá o EJB para que possa ser referenciado, pesquisado, injetado etc.

Seu cliente jar será empacotado em qualquer outro aplicativo que queira usar o EJB via @EJB ou pesquisa.

Supondo que ambos os aplicativos devem ser implantados na mesma instância do servidor de aplicativos, ele deve ser simples assim.

Fizemos o mesmo exemplo funcionar em dois servidores: Glassfish 4.1.1 e Websphere Traditional 8.5.5.5

Em ambos os casos, implantamos dois pacotes independentes:

  • Uma guerra com um servlet
  • E um jarro com um EJB.

O servlet injeta o EJB através da interface remota com @EJB sem nenhum parâmetro para o ponto de injeção. Isso funcionou no Glassfish. No entanto , para fazê-lo funcionar no Websphere, tivemos que include a seguinte consulta explícita no ponto de injeção @EJB (lookup = “java: global / ejbBasico / NewSessionBean”)

Snippet Glassfish Servlet :

 /*imports omitted */ @WebServlet(name = "MiServlet", urlPatterns = {"/MiServlet"}) public class Servlet extends HttpServlet { @EJB private Interfaz miEjb; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println("Result: " + miEjb.businessMethod()); } finally { out.close(); } /*Additional servlet code not included*/ } 

Snippet Glassfish EJB :

 /*imports omitted */ @Stateless public class NewSessionBean implements Interfaz { @Override public String businessMethod() { return("You've called the EJB"); } } 

Interface :

 /*imports omitted */ @Remote public interface Interfaz { String businessMethod(); }