java.lang.ClassCastException:$Proxy96不能强制转换为ticket.app.DatesFacade

java.lang.ClassCastException:$Proxy96不能强制转换为ticket.app.DatesFacade,java,jsf,junit,hudson,Java,Jsf,Junit,Hudson,为了在代码上运行一些代码MetricsSonar和Cobertura,我正在将一些代码输入运行在UbuntuBox上的Hudson服务器。该项目使用Glassfish3.1,使用Maven3,用Java、JSF2.0编写,并使用OracleXE数据库 尝试在JUnit测试中创建外观实例时抛出错误。当我从Netbeans运行测试时,测试运行良好,但当Hudson在其上进行自动构建时,我会出现以下错误: java.lang.ClassCastException: $Proxy96 canno

为了在代码上运行一些代码MetricsSonar和Cobertura,我正在将一些代码输入运行在UbuntuBox上的Hudson服务器。该项目使用Glassfish3.1,使用Maven3,用Java、JSF2.0编写,并使用OracleXE数据库

尝试在JUnit测试中创建外观实例时抛出错误。当我从Netbeans运行测试时,测试运行良好,但当Hudson在其上进行自动构建时,我会出现以下错误:

    java.lang.ClassCastException: $Proxy96 cannot be cast to ticket.app.DatesFacade
    at ticket.app.EventsControllerTest.setUp(EventsControllerTest.java:60)
    at junit.framework.TestCase.runBare(TestCase.java:128)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:120)
    at junit.framework.TestSuite.runTest(TestSuite.java:230)
    at junit.framework.TestSuite.run(TestSuite.java:225)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:207)
    at org.apache.maven.surefire.junit.JUnit3Provider.executeTestSet(JUnit3Provider.java:107)
    at org.apache.maven.surefire.junit.JUnit3Provider.invoke(JUnit3Provider.java:79)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
    at $Proxy0.invoke(Unknown Source)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:145)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:87)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
Hudson服务器不是由JBoss运行的,而是由Tomcat运行的。我之所以添加这个细节,是因为当我搜索这个错误时,除了JBoss错误之外,我什么也没有发现,这说明WAR和EAR文件中都引用了facade

编辑:这就是我当前创建Facade实例的方式,当通过Netbeans GF3.1运行测试时,它可以正常工作:

        Map properties = new HashMap();
    properties.put(EJBContainer.MODULES, new File("target/classes"));
    properties.put("org.glassfish.ejb.embedded.glassfish.configuration.file", "server/config/domain.xml");
    properties.put("oracle.jdbc.OracleDriver", "server/lib/ojdbc14.jar");
    ejbContainer = EJBContainer.createEJBContainer(properties);
    ctx = ejbContainer.getContext();

    EventsFacade instance = (EventsFacade)ctx.lookup("java:global/classes/EventsFacade");
编辑:我的事件摘要:

@Stateful
public class EventsFacade extends AbstractFacade<Events> {
    @PersistenceContext(unitName = "tickets_AppTicket_war_1.0-SNAPSHOTPU")
    private EntityManager em;

    protected EntityManager getEntityManager() {
        return em;
    }

    public EventsFacade() {
        super(Events.class);
    }
}

这通常意味着,当对象周围有代理且代理基于接口时,您是通过对象的类引用对象,而不是通过对象的接口引用对象

解决方案是通过对象的接口引用对象。我猜EventsFacade有一个本地和/或远程接口。试着用那个。如果它没有一个接口-制作一个,这是一个很好的实践。定义接口中的所有公共方法

更新:看起来,这可能是您正在使用的嵌入式glassfish的一个问题。由于无法使用调试器对此进行调试,因此可以使用java.lang.reflect.Proxy.getInvocationHandlerobject来跟踪问题。然后列出返回对象的所有字段。您现在必须删除强制转换,并将其作为对象从上下文中获取。比如:

Object ic = Proxy.getInvocationHandler(facade);
Field[] fields = ic.getClass().getDeclaredFields();
for (Field field : fields) {
    field.setAccessible(true);
    System.out.println(field.getName() + "=" + field.get(ic);
}

这通常意味着,当对象周围有代理且代理基于接口时,您是通过对象的类引用对象,而不是通过对象的接口引用对象

解决方案是通过对象的接口引用对象。我猜EventsFacade有一个本地和/或远程接口。试着用那个。如果它没有一个接口-制作一个,这是一个很好的实践。定义接口中的所有公共方法

更新:看起来,这可能是您正在使用的嵌入式glassfish的一个问题。由于无法使用调试器对此进行调试,因此可以使用java.lang.reflect.Proxy.getInvocationHandlerobject来跟踪问题。然后列出返回对象的所有字段。您现在必须删除强制转换,并将其作为对象从上下文中获取。比如:

Object ic = Proxy.getInvocationHandler(facade);
Field[] fields = ic.getClass().getDeclaredFields();
for (Field field : fields) {
    field.setAccessible(true);
    System.out.println(field.getName() + "=" + field.get(ic);
}

实体外观实现oracle.jbo.Entity接口,对吗?我对facade的调用如下:eventsfacadeinstance=EventsFacadectx.lookupjava:global/classes/EventsFacade;如果我通过接口引用它,我将如何进行调用?@ninn-嗯,我不知道你的类是什么。但是如果接口是实体,那么您应该使用它。或者找到从代理获取原始对象的机制。调用是否类似于:EventsFacade instance=EventsFacadectx.lookuporacle.jbo.Entity;其中ctx是EJBContainer的上下文?@ninn-将此添加到原始问题中。这里不太可读。@ninn-好吧,如果您在tomcat上运行它,这意味着您根本没有EJB提供程序?您是否可以尝试使用嵌入式glassfish:Entity Facades实现oracle.jbo.Entity接口?我对facade的调用如下:eventsfacadeinstance=EventsFacadectx.lookupjava:global/classes/EventsFacade;如果我通过接口引用它,我将如何进行调用?@ninn-嗯,我不知道你的类是什么。但是如果接口是实体,那么您应该使用它。或者找到从代理获取原始对象的机制。调用是否类似于:EventsFacade instance=EventsFacadectx.lookuporacle.jbo.Entity;其中ctx是EJBContainer的上下文?@ninn-将此添加到原始问题中。这里不太可读。@ninn-好吧,如果您在tomcat上运行它,这意味着您根本没有EJB提供程序?你能试着使用嵌入的glassfish:现在是AbstractFacade定义:@Bozho-刚刚发布lol,现在是AbstractFacade定义:@Bozho-刚刚发布lol吗
public class EventsFacade extends AbstractFacade<Events> implements EventsInterface<Events> {
Field Name == intfClass
Field == interface ticket.app.EventsInterface
Field Name == containerId
Field == 85313541807800321
Field Name == delegate
Field == com.sun.ejb.containers.EJBLocalObjectInvocationHandler@72b0f2b2
Field Name == isOptionalLocalBusinessView
Field == false
Object ic = Proxy.getInvocationHandler(facade);
Field[] fields = ic.getClass().getDeclaredFields();
for (Field field : fields) {
    field.setAccessible(true);
    System.out.println(field.getName() + "=" + field.get(ic);
}