我正在通过maven和嵌入式玻璃鱼容器在某些EJBS上运行一些单元测试。我的一个测试工作正常,但是后续尝试测试不同的EJB会导致同样的错误:
java.lang.ClassCastException: $Proxy81 cannot be cast to
接下来是我试图测试的任何bean。我相信我的设置很好,因为正如我所说,我的一个豆子可以正常测试。
工作代码示例:
@Stateful
public class LayoutManagerBean implements LayoutManager {
private final Log LOG = LogFactory.getLog(LayoutManagerBean.class);
public List<Menu> getMenus(User currentUser) {
...
}
}
@Local
public interface LayoutManager {
public List<Menu> getMenus(User user);
}
测试:
public class LayoutManagerTest {
private static EJBContainer ejbContainer;
private static Context ctx;
@BeforeClass
public static void setUp() {
ejbContainer = EJBContainer.createEJBContainer();
ctx = ejbContainer.getContext();
}
@AfterClass
public static void tearDown() {
ejbContainer.close();
}
@Test
public void getMenus() {
LayoutManager manager = null;
try {
manager = (LayoutManager) ctx.lookup("java:global/classes/LayoutManagerBean!uk.co.monkeypower.openchurch.core.layout.beans.LayoutManager");
} catch (NamingException e) {
System.out.println("Failed to lookup the gosh darned bean!");
}
assertNotNull(manager);
//Menu[] menus = manager.getMenus();
//assertTrue(menus.length > 1);
}
}
失败的一个例子:
@Singleton
public class OpenChurchPortalContext implements PortalContext {
private Set<PortletMode> portletModes = Collections.emptySet();
private Set<WindowState> windowStates = Collections.emptySet();
private Properties portalProperties = new Properties();
public OpenChurchPortalContext() {
portletModes.add(PortletMode.VIEW);
portletModes.add(PortletMode.HELP);
portletModes.add(PortletMode.EDIT);
portletModes.add(new PortletMode("ABOUT"));
windowStates.add(WindowState.MAXIMIZED);
windowStates.add(WindowState.MINIMIZED);
windowStates.add(WindowState.NORMAL);
}
...
}
测试:
public class OpenChurchPortalContextTest {
private static EJBContainer ejbContainer;
private static Context ctx;
@BeforeClass
public static void setUp() {
ejbContainer = EJBContainer.createEJBContainer();
ctx = ejbContainer.getContext();
}
@AfterClass
public static void tearDown() {
ejbContainer.close();
}
@Test
public void test() {
OpenChurchPortalContext context = null;
try {
context = (OpenChurchPortalContext) ctx.lookup("java:global/classes/OpenChurchPortalContext");
} catch (NamingException e) {
System.out.println("Failed to find the bean in the emebedded jobber");
}
assertNotNull(context);
Set<PortletMode> modes = (Set<PortletMode>) context.getSupportedPortletModes();
assertTrue(modes.size() > 1);
Set<WindowState> states = (Set<WindowState>) context.getSupportedWindowStates();
assertTrue(states.size() > 1);
}
}
关于为什么这可能不起作用的任何想法?
答案 0 :(得分:1)
如果您代理的是某个类,而不是接口,则通常会遇到此问题。假设这条线路失败了:
context = (OpenChurchPortalContext) ctx.lookup("java:global/classes/OpenChurchPortalContext");
OpenChurchPortalContext是一个类,但它由代理类包装以实现EJB特定的功能。此代理类不是OpenChurchPortalContext的子类,因此您将获得ClassCastException。
你没有得到第一个例子,因为LayoutManager是界面。
LayoutManager manager = null; // INTERFACE, so it works
try {
manager = (LayoutManager) ctx.lookup("java:global/classes/LayoutManagerBean!uk.co.monkeypower.openchurch.core.layout.beans.LayoutManager");
} catch (NamingException e) {
System.out.println("Failed to lookup the gosh darned bean!");
}
首先,您可以测试以确定这是否真的是您的问题,将上下文更改为PortalContext而不是OpenChurchPortalContext:
PortalContext context = null;
try {
context = (PortalContext) ctx.lookup("java:global/classes/OpenChurchPortalContext");
} catch (NamingException e) {
System.out.println("Failed to find the bean in the emebedded jobber");
}
如果你的问题确实是代理,那么上面的代码应该可行。如果是这种情况,您有两种可能的解决方案:
答案 1 :(得分:1)
您的singleton EJB通过实现PortalContext接口具有默认的本地业务接口。测试客户端应仅通过其业务接口知道它,并且客户端不应直接引用实际的bean类(OpenChurchPortalContext)。因此,修复方法是通过其业务接口PortalContext查找它。