为什么我们在 Glassfish 3.1.1 中的无状态会话 Bean 的 jndi 查找中得到 java.lang.ClassCastException: $Proxy
我们在实用程序类中查找本地 Stateles 会话 Bean 实例时遇到问题。我们总是得到 ClassCastException: $ProxyXYZ (XYZ 是任何数字)
我们使用 Glassfish 3.1.1、JPA 2、EJB 3、JSF2
一切都打包在耳朵存档中。
我们还在项目中使用 Bean Validation,因此在验证器类之一中,我们尝试获取无状态会话 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
}
会话 Bean:
@Stateless
@Local(ParametroGlobalBOLocal.class)
@Remote(ParametroGlobalBORemote.class)
public class ParametroGlobalBOImpl extends ParametroGlobalGenericBridgeImpl implements ParametroGlobalBOLocal,
ParametroGlobalBORemote {
MORE code...
}
查找过程运行良好,因为我们得到了 Proxy 类的实例,但不可能将其转换为会话 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
|#]
我们还这样定义了验证器类:
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
}
但是我们得到了同样的错误。
有什么想法吗?
We are having problems looking up a Local Stateles session Bean instance in a utility class. We always get a ClassCastException: $ProxyXYZ (XYZ is any number)
We are using Glassfish 3.1.1, JPA 2, EJB 3, JSF2
Everything is packaged in a ear archive.
We also use Bean Validation in our project, so in one of our validator class we try to get an instance of a Statateless session bean. The validator is defined this way:
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
}
The session Bean:
@Stateless
@Local(ParametroGlobalBOLocal.class)
@Remote(ParametroGlobalBORemote.class)
public class ParametroGlobalBOImpl extends ParametroGlobalGenericBridgeImpl implements ParametroGlobalBOLocal,
ParametroGlobalBORemote {
MORE code...
}
The lookup process works well because we get an Instancce of a Proxy class, but it is not posible to cast it to a Session Bean and when this validator is executed, we get this exception:
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
|#]
We also have defined the validator class this way:
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
}
But we get the same error.
Any Ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 glassfish 3.1.1 中获取本地或远程 ejb 引用的一种方法是通过 Bean 定位器(请参阅 http://www.adam-bien.com/roller/abien/entry/ejb_3_1_beanlocator_when)
我的Beanlocator 是(参见 getBean 方法,它需要两个参数:Ejb 的本地或远程类以及可移植的 ejb 名称):
因此,为了获取本地 ejb 引用:
可以使用相同的方法来获取远程 ejb 引用
最后这个您可能感兴趣
致以诚挚的问候
胡安
One way to get a local or remote ejb reference in glassfish 3.1.1 is via a Bean Locator (see http://www.adam-bien.com/roller/abien/entry/ejb_3_1_beanlocator_when)
My Beanlocator is (see the getBean method, it expects two arguments: the Ejb's Local or Remote class and the portable ejb name):
So in order to get a local ejb reference:
The same approach could be used to get a remote ejb reference
Finally this could interest you
Best regards
Juan
作为第一个答案的总结。出现该问题的原因是您强制转换为 EJB 本身,并且必须强制转换为 EJB 的业务接口。在学习常见问题解答后,我遇到了同样的麻烦 http://glassfish.java.net /javaee5/ejb/EJB_FAQ.html#POJOLocalEJB。幸运的是,java.net 上的同事帮助了我。非常感谢他们。
As a summary for the first answer. The problem occurs because you cast to a EJB itself and you have to cast to a business interface of the EJB. I ran into the same trouble after studing FAQ here http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#POJOLocalEJB. Fortunately, collegues on java.net helped me out. Thanks them a lot.