對于EJB主要指(SessionBean)大體上有三種客戶端,即本地客戶端,遠程客戶端和web服務客戶端。
所謂本地客戶端,就是其必須與所要訪問的的Bean在同一個JVM中,對于遠程客戶端無此限制,可以在同一個JVM中,也可以不在同一個JVM中。Web服務客戶端也可以以兩種方式來訪問Bean,但僅限于無狀態會話Bean,消息驅動Bean則不可以。而對于客戶端的形式,則無要求,可以是web客戶端,普通java應用客戶端或其他的Bean。
本次討論的是EJB的遠程客戶端,且客戶端與Bean在不同的JVM中的調用方式。環境為兩個xp,MyEclipse6.0,JBoss5。還是簡單的Hello World的例子。不是Hello fancy !呼呼 !
1.首先寫遠程接口如下:
package test; import javax.ejb.Remote; @Remote public interface HelloWorldRemote { public String sayHello(String name); }
|
2.寫Bean類實現遠程接口:
package test; import javax.ejb.Stateless; @Stateless public class HelloWorld implements HelloWorldRemote{
public String sayHello(String name){ return "Hello ,"+name; } }
|
3.利用MyEclipse打包,將遠程接口和Bean類打成helloworld.jar
4.部署EJB,即將helloworld.jar直接copy到D:\jboss5\server\default\deploy下。
5.寫客戶端代碼如下:
package client;import java.io.IOException; import java.io.InputStream; import java.util.Properties; import javax.naming.InitialContext; import javax.naming.NamingException; import test.HelloWorldRemote; /** * * javac -d . *.java ---編譯命令 * * java -Djava.ext.dirs=D:\clientLib TestHello ---運行命令, -Djava.ext.dirs=D:\clientLib指定了外部jar包目錄 * * * @author rainsunneau * */ public class TestHello { public static void main(String[] args){ ClassLoader loader = TestHello.class.getClassLoader(); InputStream in = loader.getResourceAsStream("context-config.properties"); Properties props = new Properties(); try { props.load(in); try { InitialContext ctx = new InitialContext(props); HelloWorldRemote hello = (HelloWorldRemote)ctx.lookup("HelloWorld/remote"); System.out.println(hello.sayHello("fancy!")); } catch (NamingException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } } |
6.創建JNDI配置文件context-config.properties如下:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=192.168.1.108:1099 java.naming.factory.pakgs=org.jboss.naming:org.jnp.interfaces
|
7.在IDE中直接運行客戶端測試程序,輸出如下:
8.將客戶端程序連同配置文件一同打包,并連同所需jar包,放到另外一臺xp上測試。
java -Djava.ext.dirs=D:\clientlib client.TestHello |
結果拋如下異常:
javax.naming.CommunicationException [java.rmi.ConnectException: Connection refused to host。。。 |
根據前輩的帖子指點:
客戶端程序向服務端請求一個對象的時候,返回的stub對象里面包含了服務器的hostname,客戶端的后續操作根據這個
hostname來連接服務器端。
解決方式如下:
(1).修改hostname. vi /etc/hosts 將 127.0.0.1 改為真實地址,如:192.168.100.72。 這樣客戶端就能得到真實的ip了。 |
(2)在啟動jboss時顯示指定hostname. 如:nohup ./run.sh --host="192.168.100.72" & |
我用了(2),因為我的是xp嗎。第一種方式對應到windows/system32/drivers/etc/hosts文件,怎么修改都不好用。
第二種方式可行:啟動JBoss命令如下:
run -b192.168.1.108 或 run --host=192.168.1.108。
|
結果在另一臺xp上看到:
至此終于實現了跨JVM遠程訪問EJB。
【編輯推薦】
- Java虛擬機(JVM)中的內存設置詳解
- JVM的垃圾回收機制詳解和調優
- 基于JVM的語言正在開始流行
- Java技術:嵌入式LINUX中的JVM研究
- 使用JRuby生成JVM代碼