我在使用远程EJB对象时遇到麻烦。 JNDI查找成功,但强制转换为对象,以后的使用失败。 EJB接口和实现如下:
UserViewBeanRemote.java
package books.pointejb;
import java.util.List;
import javax.ejb.Remote;
import books.pointejb.User;
import books.pointejb.Book;
@Remote
public interface UserViewBeanRemote {
public boolean register(User user);
// A user can delete his/her account, note that two users with the same username cannot exist
public void delete(User user);
public boolean login(User user);
public boolean logout(User user);
// Search only by book titles
public List<Book> search(String title);
}
UserViewBean.java
package books.pointejb;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.ejb.Stateful;
import javax.management.Query;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
// import javax.ejb.Remote;
import books.pointejb.User;
import books.pointejb.Book;
/**
* Session Bean implementation class UserView
*/
@Stateful
// @Remote(UserViewBeanRemote.class)
public class UserViewBean implements UserViewBeanRemote {
@PersistenceContext
private EntityManager entityManager;
/**
* Default constructor.
*/
public UserViewBean() {
// TODO Auto-generated constructor stub
}
public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
List<T> r = new ArrayList<T>(c.size());
for(Object o: c)
r.add(clazz.cast(o));
return r;
}
@Override
public boolean register(User user) {
// We have servlets that validate these fields, so we don't validate anything here
// We check to see whether there is already a user with the same user name or not
Query query = (Query) entityManager.createQuery("SELECT u FROM users u WHERE u.username=:userName");
((javax.persistence.Query) query).setParameter("userName", user.getUsername());
// We check each returned value. If we find anything than we do not add the user
List<User> users = castList(User.class, ((javax.persistence.Query) query).getResultList());
if(users.isEmpty()) {
// The user is not present. Add this user
entityManager.persist(user);
// return "Welcome to BooksPoint " + user.getUsername() + "!";
return true;
} else {
// return "Cannot create " + user.getUsername() + ". A user with this name already exists";
return false;
}
}
@Override
public void delete(User user) {
// The account automatically exists since the user is already logged in
Query query = (Query) entityManager.createQuery("DELETE FROM users u WHERE u.username=:userName");
((javax.persistence.Query) query).setParameter("userName", user.getUsername());
// return "Your account " + user.getUsername() + " has been removed successfully!";
}
@Override
public boolean login(User user) {
// Check if we have a valid user/pass pair
Query query = (Query) entityManager.createQuery("SELECT u FROM users u WHERE u.username=:userName AND u.password=:password");
((javax.persistence.Query) query).setParameter("userName", user.getUsername());
((javax.persistence.Query) query).setParameter("password", user.getPassword());
List<User> users = castList(User.class, ((javax.persistence.Query) query).getResultList());
if(!users.isEmpty()) {
// return "Welcome " + user.getUsername() + "!";
return true;
} else {
// return "Username or password are not valid";
return false;
}
}
@Override
public boolean logout(User user) {
// This can be done in the jsp/servlet. Simply erase the session variables associated with the current user
return false;
}
@Override
public List<Book> search(String title) {
// Check all entries for names similar to title
Query query = (Query) entityManager.createQuery("SELECT * FROM books WHERE title LIKE '%:title%'");
((javax.persistence.Query) query).setParameter("title", title);
List<Book> books = castList(Book.class, ((javax.persistence.Query) query).getResultList());
// Return the books now leave the rest to the jsp
return books;
}
}
取消注释@Remote(UserViewBeanRemote.class)不会更改此行为。
查找在以下文件中完成:
查找.java
package books.point;
import javax.naming.Context;
import javax.naming.NamingException;
import books.point.clientutility.ClientUtility;
import books.pointejb.CartBean;
import books.pointejb.CartBeanRemote;
import books.pointejb.UserViewBean;
import books.pointejb.UserViewBeanRemote;
public class Lookup {
private static final String MODULE_NAME = "BooksPointEJB";
public static UserViewBean doLookupUser() {
Context context = null;
UserViewBean bean = null;
try {
// 1. Obtaining Context
context = ClientUtility.getInitialContext();
// 2. Generate JNDI Lookup name
String lookupName = getLookupNameUser();
// 3. Lookup and cast
bean = (UserViewBean) context.lookup(lookupName); // <== Exception is thrown here
} catch (NamingException e) {
e.printStackTrace();
}
return bean;
}
public static String getLookupNameUser() {
/*
* The app name is the EAR name of the deployed EJB without .ear suffix.
* Since we haven't deployed the application as a .ear, the app name for
* us will be an empty string
*/
String appName = "";
/*
* The module name is the JAR name of the deployed EJB without the .jar
* suffix.
*/
String moduleName = MODULE_NAME;
/*
* AS7 allows each deployment to have an (optional) distinct name. This
* can be an empty string if distinct name is not specified.
*/
String distinctName = "";
// The EJB bean implementation class name
String beanName = UserViewBean.class.getSimpleName();
// Fully qualified remote interface name
final String interfaceName = UserViewBeanRemote.class.getName();
// Create a look up string name
// Be very careful about the stateful flag at the end
String name = "ejb:" + appName + "/" + moduleName + "/" + distinctName
+ "/" + beanName + "!" + interfaceName + "?stateful";
//用户查找的名称:ejb:/ BooksPointEJB // UserViewBean!books.pointejb.UserViewBeanRemote?stateful
System.out.println(“用户查找名称为:” +名称);
返回名称;
}
...
}
EJB部署日志为:
12:10:22,897 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-5) JNDI bindings for session bean named UserViewBean in deployment unit deployment "BooksPoint.war" are as follows:
java:global/BooksPoint/UserViewBean!books.pointejb.UserViewBeanRemote
java:app/BooksPoint/UserViewBean!books.pointejb.UserViewBeanRemote
java:module/UserViewBean!books.pointejb.UserViewBeanRemote
java:jboss/exported/BooksPoint/UserViewBean!books.pointejb.UserViewBeanRemote
java:global/BooksPoint/UserViewBean
java:app/BooksPoint/UserViewBean
java:module/UserViewBean
我正在使用jboss-as-7.1.1.Final。为什么会引发此异常?
12:10:52,973 INFO [org.jboss.ejb.client] (http-localhost-127.0.0.1-8080-1) JBoss EJB Client version 1.0.5.Final
12:10:53,043 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/BooksPoint].[books.point.Register]] (http-localhost-127.0.0.1-8080-1) Servlet.service() for servlet books.point.Register threw exception: java.lang.ClassCastException: com.sun.proxy.$Proxy22 cannot be cast to books.pointejb.UserViewBean
at books.point.Lookup.doLookupUser(Lookup.java:24) [classes:]
at books.point.Register.doPost(Register.java:263) [classes:]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_45]
最佳答案
当您执行JNDI查找时,您将查找远程接口。
所以改变你的演员
bean = (UserViewBeanRemote) context.lookup(lookupName);
应该可以。