一,环境配置
JDK:至于JDK就不做详细解释,想必不说大家都会
Eclipse:从网站上下载即可,我常用eclipse-jee-juno-win32.zip此版本
JBoss7.1:本文下载地址:http://download.jboss.org/jbossa ... -as-7.1.1.Final.zip
二,JBoss安装
将下载好的压缩包直接解压即可完成安装,为了避免莫名其妙的错误,解压缩的路径最好不要带空格,如“Program Files”。目录结构如下:
三,JBoss Tools安装
(1)在Eclipse中安装JBoss Tools3.3.1
在http://www.jboss.org/tools/download/installation/update_3_3 找到在线安装的路径:http://download.jboss.org/jbosstools/updates/development/indigo/)
步骤:【eclipse】→【帮助】→【Install New Software】→【Add】→【Name】:JBossTools→【Location】:http://download.jboss.org/jbosstools/updates/development/indigo/
【全选】然后一直【下一步】、【同意】
注意:如果上述方法安装出错的话。可以按照下述的第四种安装方法进行离线安装:
下载地址是:http://www.jboss.org/tools/download/stable/3_3_Final.html
本文下载的版本是:http://sourceforge.net/projects/ ... 4_23-57-15-H211.zip
步骤:【eclipse】→【帮助】→【Install New Software】→【Add】→【Archive】找到下载的.zip文件。
(2)参照同样的方法安装JBossTools Aop
在http://www.jboss.org/tools/download/installation/update_3_3 找到在线安装的路径:http://download.jboss.org/jbosst ... indigo/soa-tooling/
步骤:【eclipse】→【帮助】→【Install New Software】→【Add】→【Name】:JBossTools→【Location】:http://download.jboss.org/jbosst ... indigo/soa-tooling/
【全选】然后一直【下一步】、【同意】,安装时可能会报错,但是安装错误方式去掉选项即可,安装核心包就行,常见错误有GWT和Maven的错误,去掉复选框就行
四,eclipse里面配置JBoss
【文件】→【新建】→【其他】→【Server】→【Server】
(找到JBoss Community,选择JBoss AS 7.1)→【Next】
(找到Home Directory)→【Browse…】→
(选择JBoss解压的位置,即JBOSS_HOME配置的文件夹路径)→
(找到JRE,选择你安装的JRE)→【Next】→【Next】→【Finish】
以上步骤完毕后,在Servers视图内会有JBoss服务器出现。
点击该视图内的启动按钮,JBoss服务器开始启动
浏览器可以访问http://localhost:8080/,就算配置成功
五,第一个EJB工程
【文件】→【新建】→【其他】→【EJB】→【EJB Project】→【下一步】→【下一步】→【下一步】(选择Generate ejb-jar.xml deployment descriptor)→【完成】
生成的目录结构
ejbModule目录为我们要写JAVA源代码的目录。即EJB写在这里。
在ejbModule目录上右键【新建】→【其他】(找到EJB,并且选择Session Bean(EJB 3.x))→【下一步】
输入:包名(com.ejb)、EJB类名(HelloWorld),State type部分:选择Stateless 然后选择Remote →【完成】
自动生成代码如下:
package com.ejb; import javax.ejb.Remote; @Remote public interface HelloWorldRemote { }
package com.ejb; import javax.ejb.LocalBean; import javax.ejb.Stateless; /** * Session Bean implementation class HelloWorld */ @Stateless @LocalBean public class HelloWorld implements HelloWorldRemote { /** * Default constructor. */ public HelloWorld() { // TODO Auto-generated constructor stub } }
在接口中添加如下代码:
public String SayHello(String MyName);
在实现类里面添加如下代码:
public String SayHello(String MyName) { return "My Name is:"+MyName+".This is my first EJB Project"; }
六、部署EJB
在工程上右键→【导出】→【EJB JAR file】在Destination处:→【Browse…】→ 选择JBoss服务器的部署目录:JBOSS解压文件夹\standalone\deployments\ 然后→【完成】。在控制台视图会出现详细部署信息
七、客户端代码
1、新建一个普通Java Project工程:
2、加入JBOSS运行库:JBoss EJB3 Libraries
3、加入jboss-client.jar文件
5、新建一个客户端类:类名(HelloWorldTest)
import java.util.Hashtable; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import cn.ejb.HelloWorldRemote; public class HelloWorldTest { public static void main(String[] args) { Properties jndiProperties = new Properties(); // Hashtable jndiProperties = new Hashtable(); jndiProperties.put("jboss.naming.client.ejb.context", true); jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); try { Context context = new InitialContext(jndiProperties); final String appName = ""; final String moduleName = "HelloWorldEJB"; final String distinctName = ""; Object obj = context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/HelloWorld!cn.ejb.HelloWorldRemote"); System.out.println(obj); HelloWorldRemote hwr = (HelloWorldRemote) obj; String say = hwr.SayHello("小奎"); System.out.println(say); } catch (NamingException e) { e.printStackTrace(); } } }
6、在classath下添加“jboss-ejb-client.properties”文件。其内容如下:
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false remote.connections=default remote.connection.default.host=localhost remote.connection.default.port = 4447 remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
八,测试项目
测试项目有两种
一种是第六步中的部署方式,到处jar包,然后放在jboss的部署目录中,然后直接运行jboss-as-7.1.1.Final\bin\standalone.bat,再运行客户端的Test类即可
一种是在Eclipse中部署HelloWorldEJB项目即可,在HelloWorldEJB上右键 Run as——Run on Server——选中JBoss7.1——finish,结构图如下
运行内容成功如下代码即可:
10:01:21,932 INFO [org.jboss.as.messaging] (MSC service thread 1-1) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/topic/test 10:01:22,024 INFO [org.jboss.as.server.deployment] (MSC service thread 1-5) JBAS015876: Starting deployment of "HelloWorldEJB.jar" 10:01:22,674 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-2) JNDI bindings for session bean named HelloWorld in deployment unit deployment "HelloWorldEJB.jar" are as follows: java:global/HelloWorldEJB/HelloWorld!cn.ejb.HelloWorldRemote java:app/HelloWorldEJB/HelloWorld!cn.ejb.HelloWorldRemote java:module/HelloWorld!cn.ejb.HelloWorldRemote java:jboss/exported/HelloWorldEJB/HelloWorld!cn.ejb.HelloWorldRemote java:global/HelloWorldEJB/HelloWorld!cn.ejb.HelloWorld java:app/HelloWorldEJB/HelloWorld!cn.ejb.HelloWorld java:module/HelloWorld!cn.ejb.HelloWorld 10:01:23,274 INFO [org.jboss.as] (MSC service thread 1-6) JBAS015951: Admin console listening on http://127.0.0.1:9990 10:01:23,277 INFO [org.jboss.as] (MSC service thread 1-6) JBAS015874: JBoss AS 7.1.1.Final "Brontes" started in 15073ms - Started 217 of 298 services (80 services are passive or on-demand) 10:01:23,597 INFO [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "HelloWorldEJB.jar"
然后在客户端项目中的测试类中进行测试运行,成功代码如下
2013-3-28 10:04:38 org.jboss.ejb.client.EJBClient <clinit> INFO: JBoss EJB Client version 1.0.5.Final Proxy for remote EJB StatelessEJBLocator{appName='', moduleName='HelloWorldEJB', distinctName='', beanName='HelloWorld', view='interface cn.ejb.HelloWorldRemote'} 2013-3-28 10:04:39 org.xnio.Xnio <clinit> INFO: XNIO Version 3.0.3.GA 2013-3-28 10:04:39 org.xnio.nio.NioXnio <clinit> INFO: XNIO NIO Implementation Version 3.0.3.GA 2013-3-28 10:04:39 org.jboss.remoting3.EndpointImpl <clinit> INFO: JBoss Remoting version 3.2.3.GA 2013-3-28 10:04:39 org.jboss.ejb.client.remoting.VersionReceiver handleMessage INFO: Received server version 1 and marshalling strategies [river] 2013-3-28 10:04:39 org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate INFO: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@426295eb, receiver=Remoting connection EJB receiver [connection=Remoting connection <40110c31>,channel=jboss.ejb,nodename=wingfly]} on channel Channel ID f8641159 (outbound) of Remoting connection 69e328e0 to localhost/127.0.0.1:4447 2013-3-28 10:04:39 org.jboss.ejb.client.remoting.ChannelAssociation$ResponseReceiver handleMessage WARN: Unsupported message received with header 0xffffffff My Name is:小奎. this is my first project
九,常见错误分析
(1) 检查JBoss7.1服务器有没有启动,项目是否部署成功
2013-3-28 10:07:35 org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector setupEJBReceivers WARN: Could not register a EJB receiver for connection to remote://localhost:4447 java.lang.RuntimeException: Operation failed with status WAITING at org.jboss.ejb.client.remoting.IoFutureHelper.get(IoFutureHelper.java:93) at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.setupEJBReceivers(ConfigBasedEJBClientContextSelector.java:121) at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.<init>(ConfigBasedEJBClientContextSelector.java:78) at org.jboss.ejb.client.EJBClientContext.<clinit>(EJBClientContext.java:77) at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:120) at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104) at com.sun.proxy.$Proxy0.SayHello(Unknown Source) at cn.ejb.test.HelloWorldTest.main(HelloWorldTest.java:27) Exception in thread "main" java.lang.IllegalStateException: No EJB receiver available for handling [appName:,modulename:HelloWorldEJB,distinctname:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@303bc257 at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:584) at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:119) at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181) at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136) at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121) at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104) at com.sun.proxy.$Proxy0.SayHello(Unknown Source) at cn.ejb.test.HelloWorldTest.main(HelloWorldTest.java:27)
(2) 服务启动,检查项目是否部署成功
在测试类jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");的下面加入一行代码然后在试一下
jndiProps.put("jboss.naming.client.ejb.context", true);
检查是否加入配置文件jboss-ejb-client.properties
2013-3-28 10:21:59 org.jboss.ejb.client.EJBClient <clinit> INFO: JBoss EJB Client version 1.0.5.Final Proxy for remote EJB StatelessEJBLocator{appName='', moduleName='HelloWorldEJB', distinctName='', beanName='HelloWorld', view='interface cn.ejb.HelloWorldRemote'} Exception in thread "main" java.lang.IllegalStateException: No EJB receiver available for handling [appName:,modulename:HelloWorldEJB,distinctname:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@5b6df84b at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:584) at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:119) at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181) at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136) at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121) at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104) at com.sun.proxy.$Proxy0.SayHello(Unknown Source) at cn.ejb.test.HelloWorldTest.main(HelloWorldTest.java:27)
十、注意事项
(1) JBossAS 7的 JNDI端口是4447, AS6以前的端口号是1099
(2) JBoss7中的格式有变动
staless的格式是
ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>
stateful的格式是
ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>?stateful