当前位置: 首页 > 知识库问答 >
问题:

java.lang.ClassCastException:铸造EJB时抛出com.sun.proxy.$Proxy

柯奕
2023-03-14

我在使用远程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);
}

用户视图Bean.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)不会更改此行为。该查找在以下文件中完成:

Lookup.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?statefulSystem.out.println("User Lookup name is:"name);返回名称;}

    ...
}

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]

共有1个答案

笪成周
2023-03-14

当您进行JNDI查找时,您查找远程接口。

所以把你的演员阵容改成

bean = (UserViewBeanRemote) context.lookup(lookupName);

应该做这个伎俩。

 类似资料:
  • 我目前在辅导一个高中生AP Java,她问了我一个关于“双选”的问题。我以前从未听说过这个术语,但显然她的老师希望她在即将到来的期末考试中知道这个术语。 她的老师提供的例子是,如果你想将一个整数转换成一个字符串,你必须执行以下操作才能避免编译器错误: 问题是:你想在现实生活中什么时候这样做? 老师只提供了导致运行时错误的示例。此外,我从来不知道有一个术语,但这样做似乎是个坏主意,因为只有当两种类型

  • 问题内容: 在Objective-C中,我经常绕过块。我经常使用它们来实现有助于避免将内容存储到实例变量中的模式,从而避免线程/定时问题。 例如,我将它们分配给过孔,以便在动画结束时执行该块。(Objective-C可以将块视为对象;您也可以这样做和。) 但是,尝试在Swift和Objective-C中同时使用这些模式似乎很困难。( 编辑: 我们可以看到该语言仍在不断变化:已经对代码进行了修改,因

  • 在抽象工厂模式中,我使用泛型。我有一个扩展Serializable的BaseEntity接口,Employee类实现了BaseEntity。在抽象类中,我有一个getJavaObj方法 是一种方法,它接受并返回

  • 在最近的一个问题中,有人提到,当使用printf打印指针值时,调用方必须将指针强制转换为void*,如下所示: 为了我的生命,我不知道为什么。我发现这个问题,几乎是一样的。这个问题的答案是正确的——它解释了整数和指针的长度不一定相同。 当然,这是正确的,但是当我已经有了指针,就像上面的例子一样,为什么我要从转换到?什么时候int*与void*不同?事实上,什么时候生成的机器代码不同于简单的? 更新

  • 另外,每当调用paint方法并再次绘制相同的屏幕时,Java是否会进行任何优化?例如,如果您只在屏幕上移动一个元素,那么通常只需要更新该元素。似乎每次调用paint方法时,java都会重新绘制和处理整个屏幕。对我来说,这一切似乎都是不必要的处理密集。 示例代码: