问题
I am trying to perform a JNDI name search using Liberty Application Server.However, It is throwing me a dependency injection issue.Attached is my code
I am getting the following Error:
[ERROR ] SRVE0319E: For the [com.airline.controllers.FlightDetails]
servlet, com.airline.controllers.FlightDetails servlet class was
found, but a resource injection failure has occurred. CWNEN0030E: The
server was unable to obtain an object instance for the
java:comp/env/com.airline.controllers.FlightDetails/flightService
reference.
The exception message was: CWNEN1003E: The server was unable to find
the Web1/FlightService binding with the
com.airline.service.FlightService type for the
java:comp/env/com.airline.controllers.FlightDetails/flightService
reference.
FlightService.java
package com.airline.service;
import java.io.Serializable;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
@Stateless
@LocalBean
public class FlightService implements Serializable {
public FlightService() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public Integer getNumOfSeats() {
return numOfSeats;
}
public void setNumOfSeats(Integer numOfSeats) {
this.numOfSeats = numOfSeats;
}
public String getAirplaneModel() {
return airplaneModel;
}
public void setAirplaneModel(String airplaneModel) {
this.airplaneModel = airplaneModel;
}
private Integer id =23467;
private String from="Los Angles";
private String to="London";
private Integer price=400;
private Integer numOfSeats=250;
private String airplaneModel="Boeing 787";
}
------******FlightDetails.java*******-------------
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out = response.getWriter();
response.setContentType("text/html");
try {
flightService = (FlightService)new InitialContext().lookup("java:comp/env/Web1/FlightService");
System.out.println(flightService);
}
catch(Exception ex){
ex.printStackTrace();
}
if(flightService !=null){
out.println(flightService.getAirplaneModel());
out.println(flightService.getFrom());
out.println(flightService.getTo());
}
}
--------********server.xml*********----------------
<jndiObjectFactory id="flightService"
className="com.airline.service.FlightService"/>
<jndiReferenceEntry jndiName="Web1/FlightService"
factoryRef="flightService"/>
<webApplication id="Web1" location="Web1-0.0.1-SNAPSHOT.war"
name="Web1"/>
<!-- <application context-root="Web1" type="war" id="Web1"
location="Web1-0.0.1-SNAPSHOT.war" name="Web1"/>-->
</server>
Any Help would be appreciated!
回答1:
The <jndiObjectFactory>
element allows you to provide a custom implementation of javax.naming.spi.ObjectFactory, which will create and return an instance of the object being looked up. However, it appears you are attempting to lookup an EJB, and EJB references would be provided by the ejb feature and not application code.
The easiest way to "lookup" an EJB is to look in messages.log for a message like this:
CNTR0167I: The server is binding the com.airline.service.FlightService interface of the FlightService enterprise bean in the Web1.war module of the ???? application. The binding location is: java:global/????/Web1/FlightService!com.airline.service.FlightService
Then, change your lookup string to be the value of the binding location. This is where the EJB has been bound in JNDI, and what should be used to directly look it up.
EJBs are also available in java:app and java:module, which would be similar to the java:global lookup string, but leaving out the application or module name. For example, java:app/Web1/FlightService or java:module/FlightService.
Of course, the EJB must be in the same application for java:app or same module for java:module. Note, the !<interface>
may be left off if the EJB only implements a single interface.
EJBs are not available directly in java:comp. You may however declare an EJB reference that will be bound in java:comp/env. For example, something like this in web.xml
<ejb-local-ref>
<ejb-ref-name>Web1/FlightService</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.airline.service.FlightService</local>
<ejb-link>FlightService</ejb-link>
</ejb-local-ref>
The <ejb-ref-name>
is then bound into java:comp/env, so the application may lookup java:comp/env/Web1/FlightService. The <ejb-link>
element maps that reference to the real EJB named FlightService, as long as the EJB is located in the same application.
If you do not care to use <ejb-link>
, or you wish to override it, that may be done by adding an entry in ibm-web-bnd.xml similar to this:
<ejb-ref name="Web1/FlightService" binding-name="java:global/????/Web1/FlightService!com.airline.service.FlightService"/>
This entry in the binding file maps the reference java:comp/env/Web1/FlightService to the real EJB java:global/????/Web1/FlightService!com.airline.service.FlightService.
回答2:
Since you are trying to access stateless EJB from the servlet, the easiest would be just to inject EJB in the servlet class as:
@EJB
private FlightService flightService;
instead of using initialcontext.lookup
. Then you dont have to care about JNDI names at all.
来源:https://stackoverflow.com/questions/42216333/how-to-lookup-ejb-using-jndi-in-websphere-liberty