使用 Glassfish4 的 servlet (JavaEE) 中的 IllegalArgumentException
IllegalArgumentException in servlet (JavaEE) using Glassfish4
我有一个 servlet,用于检索存储在 JavaEE 数据库中的用户。
当我调用 servlet 时,我从 Glassfish4 收到以下错误
type: Exception report
message: Internal Server Error
description: The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Error instantiating servlet class com.storassa.javaee.scuolatennis.nicola.GetPlayersApi
root cause
com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class: class com.storassa.javaee.scuolatennis.nicola.GetPlayersApi
root cause
com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Local ejb-ref name=com.storassa.javaee.scuolatennis.nicola.GetPlayersApi/playerEjb,Local 3.x interface =com.storassa.javaee.scuolatennis.nicola.PlayerEJB resolved to intra-app EJB PlayerEJB in module scuolatennisnicola-0.0.1-SNAPSHOT,ejb-link=PlayerEJB,lookup=,mappedName=,jndi-name=,refType=Session into class com.storassa.javaee.scuolatennis.nicola.GetPlayersApi: Can not set com.storassa.javaee.scuolatennis.nicola.PlayerEJB field com.storassa.javaee.scuolatennis.nicola.GetPlayersApi.playerEjb to com.storassa.javaee.scuolatennis.nicola.GetPlayersApi
root cause
java.lang.IllegalArgumentException: Can not set com.storassa.javaee.scuolatennis.nicola.PlayerEJB field com.storassa.javaee.scuolatennis.nicola.GetPlayersApi.playerEjb to com.storassa.javaee.scuolatennis.nicola.GetPlayersApi
该消息似乎表明 servlet 已分配给 EJB,但这怎么会发生呢?还是我误解了消息?
奇怪的是,就在显示此错误消息之后,如果我再次尝试重新加载页面,则会返回一条 404 消息,就好像 servlet 是 "undeployed" 来自应用程序并且是唯一可以查看的方式同样的错误消息是重新部署应用程序。
这是 servlet:
<imports...>
/**
* Servlet implementation class GetPlayersApi
*
* The API is the following: if nothing is present retrieves all the players if
* ordered=true, retrieves all the players ordered if email=<email> retrieve the
* player with the given email
*/
@WebServlet("/api/getPlayers")
public class GetPlayersApi extends HttpServlet {
private static final long serialVersionUID = 1L;
// The list of the News to store the query in the DB
List<Player> players;
// Inject the News bean to get the data from DB
@EJB
PlayerEJB playerEjb;
/**
* @see HttpServlet#HttpServlet()
*/
public GetPlayersApi() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// get the map of the request parameters
HashMap<String, String[]> map = (HashMap<String, String[]>) request.getParameterMap();
// if no parameters are given
if (map.size() == 0)
// retrieve all the tags currently in the DB
players = playerEjb.findPlayers();
// else if ordered=true
else if (map.get("ordered") != null && map.get("ordered")[0] == "true") {
// get the Players in social ranking order
players = playerEjb.findRankingOrderedPlayers();
} else {
String email = request.getParameter("email");
Player player = playerEjb.findPlayerFromEmail(email);
if (player != null)
players.add(player);
}
// convert the result in JSON format and put them in the response
JSONArray array = new JSONArray(players);
response.getWriter().append(array.toString());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
public PlayerEJB getPlayerEJB() {
return playerEjb;
}
public void setPlayerEJB(PlayerEJB pl) {
playerEjb = pl;
}
}
这是 PlayerEJB class
@LocalBean
@Stateless
public class PlayerEJB {
// Inject the EntityManager to persist the LocationData entity
@PersistenceContext(unitName = "scuolaTennisNicolaPU")
private EntityManager em;
/**
* This method return the list of Player entities currently stored in the DB
*
* @return a List of News objects
*/
public List<Player> findPlayers() {
Query query = em.createNamedQuery("findAllPlayers");
return query.getResultList();
}
/**
* This method retrieves from the DB the persisted player with the given
* email
*
* @param email
* the email of the player to be retrieved from the DB
* @return the player with the given email that was persisted in the DB
*/
public Player findPlayerFromEmail(String email) {
// create the query
String s = "SELECT p FROM Player p WHERE p.email = '" + email + "'";
Query query = em.createQuery(s);
// query the DB
List<Player> list = (List<Player>) query.getResultList();
// if the list is not empty return the first item in the list
if (list.size() > 0)
return list.get(0);
else
return null;
}
/**
* This method return the list of Player entities currently stored in the DB
* in social ranking order
*
* @return a List of News objects
*/
public List<Player> findRankingOrderedPlayers() {
Query query = em.createNamedQuery("findAllPlayersInRankingOrder");
return query.getResultList();
}
/**
* This method remove all the Player entities currently stored in the DB
*/
public void removePlayers() {
Query query = em.createNamedQuery("removeAllPlayers");
query.executeUpdate();
}
/**
* This method remove the Player entities currently stored in the DB with a
* given name and surname;
*
* @param name
* the name of the player to be deleted
* @param surname
* the surname of the player to be deleted
*/
public void removePlayersWithName(String name, String surname) {
// create the query
String s = "DELETE FROM Player p WHERE p.name = '" + name + "' AND p.surname = '" + surname + "'";
Query query = em.createQuery(s);
query.executeUpdate();
}
/**
* This method remove the Player entities currently stored in the DB with a
* given name and surname;
*
* @param name
* the name of the players to be deleted
* @param surname
* the surname of the players to be deleted
*/
public void removePlayersWithName(String[] name, String[] surname) {
if (name.length != surname.length)
throw new IllegalArgumentException("The two arrays arae not of the same length");
// create the query
for (int i = 0; i < name.length; i++) {
String s = "DELETE FROM Player p WHERE p.name = '" + name[i] + "' AND p.surname = '" + surname[i] + "'";
Query query = em.createQuery(s);
query.executeUpdate();
}
}
/**
* This method remove the Player entities currently stored in the DB with a
* given name and surname;
*
* @param name
* the name of the players to be deleted
* @param surname
* the surname of the players to be deleted
*/
public void updatePlayersWithEmail(Player player) {
if (player == null)
throw new IllegalArgumentException("Argument cannot be null");
String[] parts = { "p.name", "p.surname", "p.password", "p.age", "p.officialRanking", "p.phone", "p.email", "p.emailChallenger", "p.socialRanking",
"p.role" };
for (int i = 0; i < parts.length; i++) {
String queryString = "UPDATE Player p SET " + parts[i] + "WHERE p.email = '" + player.getEmail();
Query query = em.createQuery(queryString);
query.executeUpdate();
}
}
/**
* This method persist a Player entity
*
* @param data
* The Player entity to be persisted
* @return the same Player entity that has just been persisted
*/
public Player createPlayer(Player data) {
em.persist(data);
return data;
}
}
根据对 OP 的评论,我们已将问题缩小到 @PersistenceContext EntityManager
未在 PlayerEJB
中注入。
没有其他信息,很难说出确切的问题是什么,但可能是以下情况之一:
- 确保 unitName
scuolaTennisNicolaPU
对应于 META-INF/persistence.xml
中定义的 persistenceUnit,例如:
<persistence-unit name="scuolaTennisNicolaPU">
- 早些时候在日志中查看注入
EntityManager
的问题是什么,这是根本问题,而不是 EJB 无法注入 Servlet 的事实。
- 确保您的 EJB 与位于
META-INF
目录中的 beans.xml
一起打包。
如果 none 这些东西解决了您的问题,则需要其他信息,请尝试更新您的问题:
- 较早的异常消息表明
EntityManager
无法注入 PlayerEJB
的原因。
- 您的
persistence.xml
配置
我有一个 servlet,用于检索存储在 JavaEE 数据库中的用户。
当我调用 servlet 时,我从 Glassfish4 收到以下错误
type: Exception report
message: Internal Server Error
description: The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Error instantiating servlet class com.storassa.javaee.scuolatennis.nicola.GetPlayersApi
root cause
com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class: class com.storassa.javaee.scuolatennis.nicola.GetPlayersApi
root cause
com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Local ejb-ref name=com.storassa.javaee.scuolatennis.nicola.GetPlayersApi/playerEjb,Local 3.x interface =com.storassa.javaee.scuolatennis.nicola.PlayerEJB resolved to intra-app EJB PlayerEJB in module scuolatennisnicola-0.0.1-SNAPSHOT,ejb-link=PlayerEJB,lookup=,mappedName=,jndi-name=,refType=Session into class com.storassa.javaee.scuolatennis.nicola.GetPlayersApi: Can not set com.storassa.javaee.scuolatennis.nicola.PlayerEJB field com.storassa.javaee.scuolatennis.nicola.GetPlayersApi.playerEjb to com.storassa.javaee.scuolatennis.nicola.GetPlayersApi
root cause
java.lang.IllegalArgumentException: Can not set com.storassa.javaee.scuolatennis.nicola.PlayerEJB field com.storassa.javaee.scuolatennis.nicola.GetPlayersApi.playerEjb to com.storassa.javaee.scuolatennis.nicola.GetPlayersApi
该消息似乎表明 servlet 已分配给 EJB,但这怎么会发生呢?还是我误解了消息?
奇怪的是,就在显示此错误消息之后,如果我再次尝试重新加载页面,则会返回一条 404 消息,就好像 servlet 是 "undeployed" 来自应用程序并且是唯一可以查看的方式同样的错误消息是重新部署应用程序。 这是 servlet:
<imports...>
/**
* Servlet implementation class GetPlayersApi
*
* The API is the following: if nothing is present retrieves all the players if
* ordered=true, retrieves all the players ordered if email=<email> retrieve the
* player with the given email
*/
@WebServlet("/api/getPlayers")
public class GetPlayersApi extends HttpServlet {
private static final long serialVersionUID = 1L;
// The list of the News to store the query in the DB
List<Player> players;
// Inject the News bean to get the data from DB
@EJB
PlayerEJB playerEjb;
/**
* @see HttpServlet#HttpServlet()
*/
public GetPlayersApi() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// get the map of the request parameters
HashMap<String, String[]> map = (HashMap<String, String[]>) request.getParameterMap();
// if no parameters are given
if (map.size() == 0)
// retrieve all the tags currently in the DB
players = playerEjb.findPlayers();
// else if ordered=true
else if (map.get("ordered") != null && map.get("ordered")[0] == "true") {
// get the Players in social ranking order
players = playerEjb.findRankingOrderedPlayers();
} else {
String email = request.getParameter("email");
Player player = playerEjb.findPlayerFromEmail(email);
if (player != null)
players.add(player);
}
// convert the result in JSON format and put them in the response
JSONArray array = new JSONArray(players);
response.getWriter().append(array.toString());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
public PlayerEJB getPlayerEJB() {
return playerEjb;
}
public void setPlayerEJB(PlayerEJB pl) {
playerEjb = pl;
}
}
这是 PlayerEJB class
@LocalBean
@Stateless
public class PlayerEJB {
// Inject the EntityManager to persist the LocationData entity
@PersistenceContext(unitName = "scuolaTennisNicolaPU")
private EntityManager em;
/**
* This method return the list of Player entities currently stored in the DB
*
* @return a List of News objects
*/
public List<Player> findPlayers() {
Query query = em.createNamedQuery("findAllPlayers");
return query.getResultList();
}
/**
* This method retrieves from the DB the persisted player with the given
* email
*
* @param email
* the email of the player to be retrieved from the DB
* @return the player with the given email that was persisted in the DB
*/
public Player findPlayerFromEmail(String email) {
// create the query
String s = "SELECT p FROM Player p WHERE p.email = '" + email + "'";
Query query = em.createQuery(s);
// query the DB
List<Player> list = (List<Player>) query.getResultList();
// if the list is not empty return the first item in the list
if (list.size() > 0)
return list.get(0);
else
return null;
}
/**
* This method return the list of Player entities currently stored in the DB
* in social ranking order
*
* @return a List of News objects
*/
public List<Player> findRankingOrderedPlayers() {
Query query = em.createNamedQuery("findAllPlayersInRankingOrder");
return query.getResultList();
}
/**
* This method remove all the Player entities currently stored in the DB
*/
public void removePlayers() {
Query query = em.createNamedQuery("removeAllPlayers");
query.executeUpdate();
}
/**
* This method remove the Player entities currently stored in the DB with a
* given name and surname;
*
* @param name
* the name of the player to be deleted
* @param surname
* the surname of the player to be deleted
*/
public void removePlayersWithName(String name, String surname) {
// create the query
String s = "DELETE FROM Player p WHERE p.name = '" + name + "' AND p.surname = '" + surname + "'";
Query query = em.createQuery(s);
query.executeUpdate();
}
/**
* This method remove the Player entities currently stored in the DB with a
* given name and surname;
*
* @param name
* the name of the players to be deleted
* @param surname
* the surname of the players to be deleted
*/
public void removePlayersWithName(String[] name, String[] surname) {
if (name.length != surname.length)
throw new IllegalArgumentException("The two arrays arae not of the same length");
// create the query
for (int i = 0; i < name.length; i++) {
String s = "DELETE FROM Player p WHERE p.name = '" + name[i] + "' AND p.surname = '" + surname[i] + "'";
Query query = em.createQuery(s);
query.executeUpdate();
}
}
/**
* This method remove the Player entities currently stored in the DB with a
* given name and surname;
*
* @param name
* the name of the players to be deleted
* @param surname
* the surname of the players to be deleted
*/
public void updatePlayersWithEmail(Player player) {
if (player == null)
throw new IllegalArgumentException("Argument cannot be null");
String[] parts = { "p.name", "p.surname", "p.password", "p.age", "p.officialRanking", "p.phone", "p.email", "p.emailChallenger", "p.socialRanking",
"p.role" };
for (int i = 0; i < parts.length; i++) {
String queryString = "UPDATE Player p SET " + parts[i] + "WHERE p.email = '" + player.getEmail();
Query query = em.createQuery(queryString);
query.executeUpdate();
}
}
/**
* This method persist a Player entity
*
* @param data
* The Player entity to be persisted
* @return the same Player entity that has just been persisted
*/
public Player createPlayer(Player data) {
em.persist(data);
return data;
}
}
根据对 OP 的评论,我们已将问题缩小到 @PersistenceContext EntityManager
未在 PlayerEJB
中注入。
没有其他信息,很难说出确切的问题是什么,但可能是以下情况之一:
- 确保 unitName
scuolaTennisNicolaPU
对应于META-INF/persistence.xml
中定义的 persistenceUnit,例如:
<persistence-unit name="scuolaTennisNicolaPU">
- 早些时候在日志中查看注入
EntityManager
的问题是什么,这是根本问题,而不是 EJB 无法注入 Servlet 的事实。 - 确保您的 EJB 与位于
META-INF
目录中的beans.xml
一起打包。
如果 none 这些东西解决了您的问题,则需要其他信息,请尝试更新您的问题:
- 较早的异常消息表明
EntityManager
无法注入PlayerEJB
的原因。 - 您的
persistence.xml
配置