为什么我们在Glassfish 3.1.1中的无状态会话Bean的jndi查找中得到java.lang.ClassCastException:$Proxy

为什么我们在Glassfish 3.1.1中的无状态会话Bean的jndi查找中得到java.lang.ClassCastException:$Proxy,glassfish,jndi,lookup,classcastexception,stateless-session-bean,Glassfish,Jndi,Lookup,Classcastexception,Stateless Session Bean,在实用程序类中查找本地Stateles会话Bean实例时遇到问题。我们总是得到一个ClassCastException:$ProxyXYZ(XYZ是任意数字) 我们正在使用GlassFish3.1.1、JPA2、EJB3和JSF2 所有内容都打包在ear归档中 我们还在项目中使用Bean验证,因此在我们的一个验证程序类中,我们尝试获取无状态会话Bean的实例。验证器的定义如下: public class ValidadorParametroGlobal implements Constraint

在实用程序类中查找本地Stateles会话Bean实例时遇到问题。我们总是得到一个ClassCastException:$ProxyXYZ(XYZ是任意数字)

我们正在使用GlassFish3.1.1、JPA2、EJB3和JSF2

所有内容都打包在ear归档中

我们还在项目中使用Bean验证,因此在我们的一个验证程序类中,我们尝试获取无状态会话Bean的实例。验证器的定义如下:

public class ValidadorParametroGlobal implements ConstraintValidator<ValidacionParametroGlobal, ParametroGlobal> {

    @Override
    public void initialize(final ValidacionParametroGlobal constraintAnnotation) {
        try {

            //Lookup works, jndi name is correct, but cast fails
            ParametroGlobalBOImpl pgbo =
                    (ParametroGlobalBOImpl) new InitialContext().lookup(
                    "java:global/esipren-ear/esipren-ejb/ParametroGlobalBOImpl!" +
                    "ec.gob.mf.esipren2.bo.entidad.ParametroGlobalBOLocal");
            LOG.info(pgbo);
        } catch (NamingException ex) {
            LOG.error("No se pudo recuperar el bo de parametro global en el validador");
            throw new IllegalStateException("No se puede ejecutar la validación", ex);
        }
        LOG.debug("Inicializando validador");
    }
    ... MORE CODE
}
public class ValidadorParametroGlobal implements ConstraintValidator<ValidacionParametroGlobal, ParametroGlobal> {

    @Override
    public void initialize(final ValidacionParametroGlobal constraintAnnotation) {
        try {
            ParametroGlobalBOLocal pgbo =
                    (ParametroGlobalBOLocal) new InitialContext().lookup(
                    "java:global/esipren-ear/esipren-ejb/ParametroGlobalBOImpl!" +
                    "ec.gob.mf.esipren2.bo.entidad.ParametroGlobalBOLocal");
            LOG.info(pgbo);
        } catch (NamingException ex) {
            LOG.error("No se pudo recuperar el bo de parametro global en el validador");
            throw new IllegalStateException("No se puede ejecutar la validación", ex);
        }
        LOG.debug("Inicializando validador");
    }
    ... MORE CODE
}
查找过程运行良好,因为我们获得了代理类的InstanceC,但无法将其强制转换为会话Bean,当执行此验证器时,我们会得到以下异常:

java.lang.ClassCastException: $Proxy1519
    at     ec.gob.mf.esipren2.validacion.ValidadorParametroGlobal.initialize(ValidadorParametroGlobal.java:64)
    at ec.gob.mf.esipren2.validacion.ValidadorParametroGlobal.initialize(ValidadorParametroGlobal.java:41)
    at org.hibernate.validator.engine.ConstraintTree.initializeConstraint(ConstraintTree.java:302)
    at org.hibernate.validator.engine.ConstraintTree.createAndInitializeValidator(ConstraintTree.java:212)
at org.hibernate.validator.engine.ConstraintTree.getInitializedValidator(ConstraintTree.java:189)
    at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree|#]

            [#|2011-10-28T11:46:10.814-0500|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=19;_ThreadName=Thread-4;|.java:135)
    at org.hibernate.validator.metadata.MetaConstraint.validateConstraint(MetaConstraint.java:121)
    at org.hibernate.validator.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:327)
    at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForRedefinedDefaultGroup(ValidatorImpl.java:273)
    at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:256)
    at org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:210)
    at org.hibernate.validator.engine.ValidatorImpl.validate(ValidatorImpl.java:119)
    at ec.gob.mf.esipren2.validacion.BeanValidationEventListener.validate(BeanValidationEventListener.java:56)
at ec.gob.mf.esipren2.persistencia.dao.jpa.JpaGenericDAOImpl.crear(JpaGenericDAOImpl.java:113)
    ... 95 more
    |#]
我们还以这种方式定义了validator类:

public class ValidadorParametroGlobal implements ConstraintValidator<ValidacionParametroGlobal, ParametroGlobal> {

    @Override
    public void initialize(final ValidacionParametroGlobal constraintAnnotation) {
        try {

            //Lookup works, jndi name is correct, but cast fails
            ParametroGlobalBOImpl pgbo =
                    (ParametroGlobalBOImpl) new InitialContext().lookup(
                    "java:global/esipren-ear/esipren-ejb/ParametroGlobalBOImpl!" +
                    "ec.gob.mf.esipren2.bo.entidad.ParametroGlobalBOLocal");
            LOG.info(pgbo);
        } catch (NamingException ex) {
            LOG.error("No se pudo recuperar el bo de parametro global en el validador");
            throw new IllegalStateException("No se puede ejecutar la validación", ex);
        }
        LOG.debug("Inicializando validador");
    }
    ... MORE CODE
}
public class ValidadorParametroGlobal implements ConstraintValidator<ValidacionParametroGlobal, ParametroGlobal> {

    @Override
    public void initialize(final ValidacionParametroGlobal constraintAnnotation) {
        try {
            ParametroGlobalBOLocal pgbo =
                    (ParametroGlobalBOLocal) new InitialContext().lookup(
                    "java:global/esipren-ear/esipren-ejb/ParametroGlobalBOImpl!" +
                    "ec.gob.mf.esipren2.bo.entidad.ParametroGlobalBOLocal");
            LOG.info(pgbo);
        } catch (NamingException ex) {
            LOG.error("No se pudo recuperar el bo de parametro global en el validador");
            throw new IllegalStateException("No se puede ejecutar la validación", ex);
        }
        LOG.debug("Inicializando validador");
    }
    ... MORE CODE
}
公共类ValidadorParametoGlobal实现ConstraintValidator{
@凌驾
public void initialize(最终有效性参数全局约束旋转){
试一试{
参数全局局部pgbo=
(ParameterGlobalBoLocal)新建InitialContext()。查找(
“java:global/esipren-ear/esipren-ejb/ParametroGlobalBOImpl!”+
“ec.gob.mf.esipren2.bo.entidad.ParametroGlobalBOLocal”);
日志信息(pgbo);
}捕获(NamingException-ex){
日志错误(“无全球参数有效性评估报告”);
抛出新的非法国家例外(“没有其他例外”,例如);
}
LOG.debug(“Inicializando validador”);
}
…更多代码
}
但是我们得到了同样的错误


有什么想法吗?

在glassfish 3.1.1中获取本地或远程ejb引用的一种方法是通过Bean定位器(请参阅)

我的Beanlocator是(请参阅getBean方法,它需要两个参数:Ejb的本地或远程类和可移植Ejb名称):

同样的方法也可以用于获取远程ejb引用

public String despachar1() {
    String result;
    try {

        ParametroGlobalBORemote prboRemote = BeanLocator.getBean(ParametroGlobalBORemote.class,
                "java:global/esipren-ear/esipren-ejb/ParametroGlobalBOImpl!" +
                "ec.gob.mf.esipren2.bo.entidad.ParametroGlobalBORemote");
        prboRemote.buscarTodos();
        result = "Something";
    } catch (NamingException ex) {
        ex.printStackTrace();
        result = "error";
    }
    return result;    }
最后,这可能会引起你的兴趣

http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#StandaloneRemoteEJB
http://www.java.net/node/703676#comment-797861
http://www.jguru.com/faq/view.jsp?EID=734137
致意
Juan

作为第一个答案的总结。出现此问题是因为您强制转换到EJB本身,并且必须强制转换到EJB的业务接口。在这里学习FAQ之后,我也遇到了同样的问题。幸运的是,java.net上的同事帮了我的忙。非常感谢他们

http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#StandaloneRemoteEJB
http://www.java.net/node/703676#comment-797861
http://www.jguru.com/faq/view.jsp?EID=734137