本地EJB接口和View之间有什么区别

时间:2016-11-23 23:33:19

标签: java-ee ejb

我认为这个问题是What is local/remote and no-interface view in EJB?

的延伸

我正在尝试移植一组EJB Jars,它们的EJB由Servlet以通用方式调用,从WebLogic到JBoss。整个系统很老,EJB是2.0。我试图通过将部署描述符更改为3.2来更新它。

这部分相对容易。

这是的部分。

参与此arranbement的EJB都实现了SessionBean接口。它们的本地和远程接口是通用的,它们继承自通用的业务接口。以下是部署描述符的示例:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         version="3.2"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd">
<module-name>WhizBangSessionEJB</module-name>
<enterprise-beans>
   <session>
        <ejb-name>WhizBangSessionEJB</ejb-name>
        <home>com.whatever.hostinterface.ServiceLogicHome</home>
        <remote>com.whatever.hostinterface.ServiceLogic</remote>
        <local-home>com.whatever.hostinterface.ServiceLogicLocalHome</local-home>
        <local>com.whatever.hostinterface.ServiceLogicLocal</local>
        <ejb-class>com.whatever.whizbang.ejbs.WhizBangSessionBean</ejb-class>
        <session-type>Stateful</session-type>
        <transaction-type>Container</transaction-type>
    </session>
 </enterprise-beans>
</ejb-jar>

我还应该在这里提一下这些接口的签名:

public interface ServiceInterface
{
// business interface methods.
}

public interface ServiceLogic extends EJBObject, ServiceInterface
{}

public interface ServiceLogicLocal extends ServiceLogic, EJBLocalObject 
{}

ServiceLogic IS-A ServiceInterface。 ServiceLogicLocal IS-A ServiceLogic,因此是IS-A ServiceInterface

使用远程接口,servlet能够实例化bean,如下所示:

Object home = ctx.lookup({JNDI of Home Interface});
EJBHome obHome = (EJBHome)PortableRemoteObject.narrow(home, EJBHome.class);
Method m = obHome.getClass().getDeclaredMethod("create", new Class[0]);
sl = (ServiceLogic) m.invoke(obHome, new Object[0]);

我的EJB可以投射到服务逻辑中。

但是这些EJB和Servlet将始终位于同一个容器中。因此指示了本地接口。这是我遇到麻烦的地方。 本地EJB不需要3.x中的Home接口。

所以我认为这样的事情应该有用。

sl = (ServiceLogicLocal)ctx.lookup({JNDI of Local Interface to Bean});

此操作失败,并出现以下错误。

java.lang.ClassCastException: com.whatever.hostinterface.ServiceLogicLocal$$$view60 cannot be cast to com.whatever.hostinterface.ServiceLogicLocal

我知道不需要Local Home界面,但我创建了它。尝试使用它并调用其create()方法,会产生相同类型的ClassCastException,因为我试图将对象的视图(代理)转换为该类型的对象。

本地EJB接口和本地EJB接口的ClientView之间的区别是什么,以及如何通过其本地接口实例化此EJB?

感谢。

2 个答案:

答案 0 :(得分:2)

默认情况下,Java EE部署单元(jar,ejb-jars,war,ear-and-their-contents)彼此隔离。换句话说,一个部署单元中的类无权访问其他部署单元中的类。

这通常是件好事。

某些Java EE实现(如JBossAS和WildFly)提供了一种覆盖此约束的机制。

如果您的EJB和接口打包在名为WhizBang.jar的jar中,那么您可以通过向其添加WEB-INF/jboss-deployment-structure.xml文件来使您的Web应用程序可以访问此jar中的类,其中包含以下内容:

<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.3">
    <deployment>
        <dependencies>
            <module name="deployment.WhizBang.jar" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>

鉴于上述情况,您可以查找EJB:

 InitialContext initialContext = new InitialContext();
 ServiceInterface serviceBean = (ServiceInterface)initialContext.lookup("java:global/WhizBangSessionEJB/WhizBangSessionEJB!com.whatever.hostinterface.ServiceLogicLocal");
 ServiceLogic remoteService = (ServiceLogic)initialContext.lookup("java:global/WhizBangSessionEJB/WhizBangSessionEJB!com.whatever.hostinterface.ServiceLogic");

我在WildFly 10.1.0.Final中使用此代码

答案 1 :(得分:0)

这适用于我的Wildfly,

虽然我必须按照提供的方式添加依赖项。

 		<!-- Business Interfaces of the server EJB. -->
		<dependency>
			<groupId>com.sample.ejb</groupId>
			<artifactId>sample-engine-ejb</artifactId>
			<type>ejb</type>
			<version>1.0</version>
			<scope>provided</scope>
		</dependency>

谢谢!