我已经在Stack上寻找了一段时间的答案。所有的答案看起来像他们说我已经有了正确的答案,但我仍然在下面的构造函数的第一行得到一个类强制转换异常。
SEVERE: Exception while loading the app : EJB Container initialization error
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at com.domain.security.logging.ElsAbstractCrudClass.<init>(ElsAbstractCrudClass.java:54)
这是代码。看完文档之后,我仍然无法弄明白。我对仿制药和反思比较陌生,所以需要一些帮助。 TIA。
public abstract class ElsAbstractCrudClass<T> {
Class<T> entity;
public ElsAbstractCrudClass() {
[line 54] ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
Type type = genericSuperclass.getActualTypeArguments()[0];
this.entity = (Class<T>) type;
}
}
这是抽象crud类的子类(SessionLog是JPA实体):
@Stateless
public class SessionLogger extends ElsAbstractCrudClass<SessionLog> {
@PersistenceContext(unitName = "ELS_Soulard_PU")
private EntityManager em;
@EJB
DozerInstantiator di;
//SessionLog entity;
//SessionLog sessionLog = new SessionLog();
static final Logger logger = Logger.getLogger(SessionLogger.class.getSimpleName());
public SessionLogger() {
}
...
答案 0 :(得分:4)
getGenericSuperclass
返回ParameterizedType
的实例,如果不是,则返回Class
的实例。大概你有类似的东西:
class A extends B { ... }
class B extends ElsAbstractCrudClass<Person> { ... }
现在,getClass()
使用超类A.class
返回B.class
,这不是通用的......
只要运行时类不是通用的(递归地遍历类型层次结构,按照其定义替换类型参数),就可以将代码片段推广为有效。但是,除非你有几十个crud类,否则要求子类传递正确的类对象更容易:
public abstract class ElsAbstractCrudClass<T> {
final Class<T> entityClass;
public ElsAbstractCrudClass(Class<T> entityClass) {
this.entityClass = entityClass;
}
}
答案 1 :(得分:2)
您遇到此错误,因为EJB容器扩展您的无状态bean以在方法调用上包装EJB特定逻辑。所以在部署时你会有这样的事情:
ContainerSubclass extends SessionLogger {}
解决方案:
1)在构造函数中首先调用
... = getClass().getSuperClass();
...
2)或针对接口的代码,以便EJB容器通过反射创建动态代理。
答案 2 :(得分:0)
遇到麻烦的另一种方法是扩展类使用原始类型,而不是泛型类型。换句话说,这个子类将生成您的异常,因为它的超类型只是原始类型ElsAbstractCrudClass。
public class EE extends ElsAbstractCrudClass { ... }
但是这个不会因为它的超类型是通用类型ElsAbstractCrudClass
public class EE extends ElsAbstractCrudClass<String> { ... }