對EJB有遠(yuǎn)程調(diào)用和本地調(diào)用兩種模式,本地調(diào)用需要調(diào)用者和布署EJB的容器在同一個(gè)JVM中,遠(yuǎn)程調(diào)用則不管調(diào)用者和布署EJB的容器的分布情況,可能是同一個(gè)JVM,可能是同一臺(tái)電腦上的不同的JVM,也可能是分布在不同的電腦上的JVM。
下面定義了一個(gè)簡單的EJB,并嘗試了在不同環(huán)境下的調(diào)用。
1. 定義遠(yuǎn)程接口,這樣可以讓EJB實(shí)例支持遠(yuǎn)程調(diào)用
package testEJB;
import javax.ejb.Remote;
@Remote
public interface HelloRemote {
public String hi();
}
2. 實(shí)現(xiàn)無狀態(tài)會(huì)話Bean
package testEJB;
import javax.ejb.Stateless;
@Stateless
public class Hello implements HelloRemote {
public String hi() {
return "hello";
}
}
3. 將以上代碼打包到hello.jar中,然后布署到glassfish中
4. 在javaSE環(huán)境中的調(diào)用:
在JavaSE中的調(diào)用顯然屬于遠(yuǎn)程調(diào)用,相對而言比較麻煩。我們需要導(dǎo)入運(yùn)行時(shí)需要的相關(guān)jar包,javaee.jar和appserv-rt.jar,這兩個(gè)包可以在glassfish的lib文件夾中找到。
測試代碼如下:
public static void main(String args[]){
try {
Properties p = System.getProperties();
p.setProperty("org.omg.CORBA.ORBInitialHost", "glassfish運(yùn)行的IP地址");
InitialContext ic =new InitialContext();
HelloRemote sayhello = (HelloRemote) ic.lookup("java:global/hello/Hello");
String result = sayhello.hi();
System.out.println(result);
} catch (NamingException ex) {
ex.printStackTrace();
}
}
要注意上面lookup方法中的字符串參數(shù)“java:global/hello/Hello”,其中hello為模塊名,在這個(gè)例子中也就是hello.jar文件名的前一部分,Hello為EJB的名稱。
5. 在glassfish中的調(diào)用:
a) 假設(shè)存在一個(gè)web應(yīng)用與Hello EJB布署在同一個(gè)glassfish下,web應(yīng)用中有一個(gè)Servlet要訪問Hello EJB,因?yàn)閃eb應(yīng)用和Hello EJB是在一個(gè)JVM中運(yùn)行,所以可以用本地調(diào)用的方式。
因?yàn)閣eb應(yīng)用中要使用Hello EJB,所以需要導(dǎo)入hello.jar包。在hello.jar包中有Hello ejb的具體實(shí)現(xiàn),我們需要將導(dǎo)入的hello.jar中的Hello.class刪除,如果不刪除則相當(dāng)于在web應(yīng)用中又定義了一個(gè)新的無狀態(tài)會(huì)話Bean。
Servlet的代碼如下:
@WebServlet(name="Test", urlPatterns={"/test"})
public class Test extends HttpServlet {
@EJB
private HelloRemote hello;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println(hello.getClass().getName());
out.flush();
}
}
將此web應(yīng)用打包成web.war后發(fā)布到glassfish中,輸入如下URL:http://localhost:8080/web/test,沒有異常則說明訪問成功。
注意,如果沒有刪除hello.jar中的Hello.class,web.war將無法成功布署。
b) 假設(shè)web應(yīng)用與Hello ejb布署在不同的glassfish中,則還需要做一些簡單的配置,以告訴servlet容器如何找到ejb實(shí)例。
修改上面@EJB處的代碼為:
@EJB(name="hello")
private HelloRemote hello;
以上配置了name="hello",這里name的值"hello"為sun-web.xml中配置的ejb引用名。
修改sun-web.xml,代碼如下:
<sun-web-app error-url="">
<context-root>/test</context-root>
<ejb-ref>
<ejb-ref-name>hello</ejb-ref-name>
<jndi-name>corbaname:iiop:布署EJB的IP地址:3700#java:global/hello/Hello</jndi-name>
</ejb-ref>


上面的ejb-ref-name指定了在應(yīng)用中通過什么名字引用這個(gè)ejb。jndi-name指定了ejb的位置,其中最后一段"hello/Hello",指ejb布署在hello.jar中,名稱為Hello。
6. 其它布署情況
如果沒有將hello.jar單獨(dú)做為ejb應(yīng)用發(fā)布到glassfish中,而是在web應(yīng)用中通過lib直接引入hello.jar(不刪除其中的Hello.class),那么Hello EJB的全局名稱將與前面討論的不同,假設(shè)web應(yīng)用最終發(fā)布為web.war,那么Hello EJB的全局名為
java:global/web/Hello,而不是
java:global/hello/Hello,