Java反射:创建新的接口实例,给出Java .lang. classcastexception



我有一个EAR项目结构:

耳朵

  • TestDependency.jar

    • MyInterface.class;
  • TestEJBModule.jar

    • ExternalObject.class(实现MyInterface);
  • TestWar

    • SingletonBean
  • MyTestClass(实现MyInterface);

在单例bean中,我需要使用类名动态实例化ExternalObject类,但我得到

Caused by: javax.ejb.EJBException: java.lang.ClassCastException: com.bsssrl.testejbmodule.ExternalObject cannot be cast to com.bsssrl.MyInterface

代码是:

    Class localclass = Class.forName("com.bsssrl.test.testwar.MyTestClass");
    Object olocal = localclass.newInstance();
    MyInterface local = (MyInterface) olocal;
    LOG.log(Level.INFO, "Test local.getString()   : {0}",local.getString());
    LOG.log(Level.INFO, "Test local.getAlfa()     : {0}",local.getAlfa());

Class exclass = Class.forName("com.bsssrl.testejbmodule.ExternalObject");
Object oex = exclass.newInstance();
if(MyInterface.class.isAssignableFrom(exclass)){
   MyInterface extern = (MyInterface) oex;
   LOG.log(Level.INFO, "Test extern.getString()  : {0}",extern.getString());
   LOG.log(Level.INFO, "Test extern.getAlfa()    : {0}",extern.getAlfa());
}else{
       LOG.log(Level.SEVERE, "Class {0} not implement MyInterface",exclass);
}

类是:

public class ExternalObject implements MyInterface{
public Alfa alfa;
@Override
public String getString() {
    return "from external object in EJB module";
}
@Override
public Alfa getAlfa() {
    return alfa;
}
@Override
public void setAlfa(Alfa a) {
    this.alfa = a;
}
}

第一段代码工作,但第二段代码启动ClassCastException;我想我的classloader有问题。

我怎么解决它?

PS:我用的是wildfly-9.0.2.Final

如果在兼容类之间出现类强制转换异常,这总是意味着它们被不同的类加载器加载(很可能,一个在WAR中,另一个在EAR中),或者有多个可用的类版本,而错误的(不兼容的)版本正在被选中。对于JBoss/Wildfly来说,后者尤其容易发生,因为它有一个混乱的类加载策略。

要测试前者,请尝试将类加载器设置为显式加载MyInterface的类加载器:

Class.forName("com.bsssrl.testejbmodule.ExternalObject", true, MyInterface.class.getClassLoader())

我得到了一个ClassCastException

IService iService=(IService) classS.newInstance();

urlClassLoader=URLClassLoader.newInstance(new URL[] {new URL(urlStr)}); 

,然后添加cast类加载器作为newInstance的参数,这就为我解决了问题:

urlClassLoader=URLClassLoader.newInstance(new URL[] {new URL(urlStr)},IService.class.getClassLoader());

相关内容

  • 没有找到相关文章

最新更新