I have two applications running on my local glassfish server. One to rent bicylces and one to buy train tickets. I now wanted to call a remote ejb from the train application
In your bicycle app you have to:
@Remote
annotation from your interface FahrradRemote
@Remote
annotation to your FahrradService
EJB
You can follow this snippet:
@Remote(FahrradRemote.class)
@Stateless
public class FahrradService implements FahrradRemote, Serializable {
.... // your code
}
(if your are using EJB 3.X, there is no need for an EJB to explicitly implement the SessionBean interface)
In your train app:
@EJB(name="FahrradService")
private FahrradRemote fahrradService;
(use name
attribute instead of mappedName
; and you cannot have static properties in a stateless EJB)
Finally you have to tell the container where to lookup for the EJB implementation: create the descriptor glassfish-ejb-jar.xml
and, inside glassfish-ejb-jar
tags, put this:
<enterprise-beans>
<ejb>
<ejb-name>BahnPM</ejb-name>
<ejb-ref>
<ejb-ref-name>FahrradService</ejb-ref-name>
<jndi-name>java:global/MyRemoteBeanModule/MyRemoteBean</jndi-name>
</ejb-ref>
</ejb>
</enterprise-beans>
The portable JNDI name for your remote EJB (what I have called java:global/MyRemoteBeanModule/MyRemoteBean
) is available in GlassFish logs when you deploy the bicycle application.
You should have a FahrradService-EJB
jar, and an FahrradService-client
jar (names are examples, just have the two jars). Your IDE would have generated both for you if you created an EJB using Jave EE plugins/tooling.
Your EBJ jar and the client jar will both be packaged with one of the applications. Deployment of the application will establish the EJB, so it can be referenced, looked up, injected, etc.
Your client jar will be packaged in any other application that wants to use the EJB via @EJB or lookup.
Assuming both applications are to be deployed to the same app-server instance, it should be just about that simple.
We've made the same example work in two servers: Glassfish 4.1.1 and Websphere Traditional 8.5.5.5
In both cases we deployed two independent packages:
The servlet injects the EJB via the remote interface with @EJB without any parameter for the injection point. This worked in Glassfish. However, to make it work in Websphere we had to include the following explicit lookup in the injection point @EJB(lookup="java:global/ejbBasico/NewSessionBean")
Glassfish Servlet snippet:
/*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*/
}
Glassfish EJB snippet:
/*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();
}