问题
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 to allow the rental of bicycles for the chosen time but I'm not really sure how to do it. I already tried a few different approaches. Both applications are in different packages and the train application has to know the bicycle remote interface but I don't know how to accomplish that.
The remote interface (bicyle app):
@Remote
public interface FahrradRemote {
public List<Fahrrad> findAvaible(Date start, Date end);
public void addAuftrag(Fahrrad fahrrad, Date startDate, Date endDate);
public boolean login(String name, String passwort);
}
Bicycle EJB I want to call:
@Stateless(name="FahrradService",mappedName="FahrradService")
public class FahrradService implements javax.ejb.SessionBean, FahrradRemote, Serializable {
@PersistenceContext
private EntityManager em;
Kunde customer;
...
}
Beginning of the train app:
@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<Fahrt> available;
private List stations;
@EJB
private BahnService service;
@EJB(mappedName="FahrradService")
private static FahrradRemote fahrradService;
public BahnPM() {
}
...
}
Error I get is a class not found exception, which i can understand because it's a different application and my train app doesn't know "FahrradRemote" but how can I inject that EJB?
回答1:
In your bicycle app you have to:
- remove the
@Remote
annotation from yourinterface FahrradRemote
- add the
@Remote
annotation to yourFahrradService
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.
回答2:
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.
回答3:
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:
- A war with a servlet,
- And a jar with an EJB.
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();
}
来源:https://stackoverflow.com/questions/11916045/how-can-i-inject-an-ejb-from-an-other-application-on-the-same-glassfish-server