??xml version="1.0" encoding="utf-8" standalone="yes"?> 2.@Remote/@Local可以定义在接口,也可以在实现cd义?/p> 3.如果一个EJB实现了多个接口,必须指定那些接口是remoteQ哪些是local?/p> 4.另一U定?/p> @Remote(value={EjbInterface01.class,EjbInterface02.class}) 当属性ؓvalue而且只定义一个属性时Qvalue可以省略只写倹{?/p> 5.直接在接口里面定义,那么实现cd不用再定义了?/p> 2.本地客户端也不需要依赖包Q相x口和cd义;client包)。就是web应用在运行时自然处在服务器里面,那些依赖包都有了?/p> 如果把Jbossall-client.jar也拷到本地客L来,则会出错。因为在部vweb目Ӟmyeclipse会将jar包部|到web目下Web-root\web-inf\lib文g夹下?/p> 引v重复出现错误?/p> Q?本地客户端: Q1Q创Z个web目Q与jboss部|在同一个JQӞ当中?/p> Q2Q添加服务器端项目的依赖或手动添加接口的jar包 Q3Q在index.jsp改编码?/p> 本地客户端也可以使用q程调用方式Q?/p> 本地客户端的本地调用方式没成功: 有待以后多些见识解决或偶遇高人指炏V?/p>
不大清楚Q本地调用还需要JQDQ吗Q?/p> 后来发现Q原来是UserManagerBean中的@Local,@Remote必须明确写上接口的类型,才可以。修改代码如下:
@Local(value={EjbInterface03.class,EjbInterface04.class}) <%
Hashtable env=new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL,"localhost:1099");
env.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
InitialContext cxt=new InitialContext(env);
UserManager us=(UserManager)cxt.lookup("UserManagerBean/remote");
User u=new User();
u.setUsername("persia");
u.setPassword("p");
us.addUser(u);
out.println("user--perisa已经创徏?/span>"+u.getId());
%>
00:18:28,661 ERROR [[jsp]] Servlet.service() for servlet jsp threw exception
java.lang.IllegalArgumentException: Wrong target. class com.persia.ejb.UserManagerBean for public void com.persia.ejb.UserManagerBean.addUser(com.persia.ejb.User)
at org.jboss.aop.joinpoint.MethodInvocation.handleErrors(MethodInvocation.java:141)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:116)
at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:240)
at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:210)
at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:84)
at $Proxy94.addUser(Unknown Source)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:97)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:336)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
at java.lang.Thread.run(Thread.java:619)
<%
Hashtable env=new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL,"localhost:1099");
env.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
InitialContext cxt=new InitialContext(env);
UserManager us=(UserManager)cxt.lookup("UserManagerBean/local");
User u=new User();
u.setUsername("persia");
u.setPassword("p");
us.addUser(u);
out.println("user--perisa已经创徏?/span>"+u.getId());
%>
package cn.study.ejb;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Stateless
@Remote(UserManager.class)
@Local(UserManager.class)
public class UserManagerBean implements UserManager
{
public void addUser(User user)
{
System.out.println(user.getUsername() + "已经被成功保存!");
user.setId(13);
}
}
]]>
有状态和无状态的会话bean都在客户端生不同的代理实例
不同的是在服务器端,有状态的每次lookup都是新的独立的beanQ而无状态的是单例bean?/p>
public class StatelessEjbClient { /** * @param args * @throws NamingException */ public static void main(String[] args) throws NamingException { Hashtable env=new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory"); env.put(Context.PROVIDER_URL,"localhost"); env.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces"); InitialContext cxt=new InitialContext(env); //W一ơ会?/span> StatelessEjb se1=(StatelessEjb)cxt.lookup("StatelessEjbBean/remote"); System.out.println("刚开?/span>"+se1.getCount()); se1.compute(1); System.out.println(se1.getCount()); se1.compute(1); System.out.println(se1.getCount()); se1.compute(1); System.out.println(se1.getCount()); se1.compute(1); System.out.println(se1.getCount()); //W二ơ会?/span> StatelessEjb se2=(StatelessEjb)cxt.lookup("StatelessEjbBean/remote"); System.out.println("刚开?/span>"+se2.getCount()); se2.compute(1); System.out.println(se2.getCount()); se2.compute(1); System.out.println(se2.getCount()); se2.compute(1); System.out.println(se2.getCount()); se2.compute(1); System.out.println(se2.getCount()); se2.compute(1); System.out.println(se2.getCount()); System.out.println("ejb1==ejb2"+(se1==se2)); } }
W一ơ运行结?/p>
刚开?
1
2
3
4
刚开?
5
6
7
8
9
ejb1==ejb2false
而第二次却不是递增了:
刚开?
10
11
12
13
刚开?3
14
14
14
14
14
ejb1==ejb2false
2.new EJB project创徏目
3.创徏EJB—》new interfaceQ然后new class实现c,xxxBean命名?/p>
4.注解配置EJBQxxxBeancdQ@stateful或@stateless和@remote或@local
5.部vEJB。查看JBOSS\SERVER\DEFAULT\DEPLOY里面部v的EJB.
6.开发EJB客户端:
Q?Qnew java project
Q?Q通过接口调用Q将接口--》导出jar包到客户端目录下Qjar包名随便P然后d为项目liberies时点add jar。用该接口时再导入该包)?/p>
Q?Q将接口jar包添加到目的类路径下。将JBOSS\client下的jar包也d到客L目里面。(可以先在myeclipse里定义一个库?gt;java?gt;build path?gt;user liberyQ?/p>
Q?Qnew class--》初始化上下?JNDI里面的initial context)—》context.lookup(“EJB名称/remote?--》调用方法?/p>
Q?Q在客户端配|JNDIQ告诉context:EJB在哪里。在c\径下面(srcQ目录下djndi.properties?/p>
java.naming.factory.initial = org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url = localhost
Q?Q运行客L?/p>
我实际运行时用jndi.properties文g不能q行成功Q提CCannot instantiate class: org.jnp.interfaces.NamingContextFactoryQ网上的解决Ҏ是添加jbossall-client.jar但是我添了没效果。于是换成在java文g里面讄Q成功。怀疑是我的jndi.properties文g写法有问题,有待验证?/p>
Hashtable env=new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL,"localhost:1099");
env.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
InitialContext cxt=new InitialContext(env);
Q?Qsession beanQstateless和stateful session beanQ?/p>
会话beanQ从客户端获得EJB对象开始,然后调用EJBҎQ直到客L释放EJB对象为止。客L通过JNDI查找EJB对象。若每次会话查找同一对象Ӟ则返回不同对象?/p>
对象的状态由它的实例变量的值决定的?/p>
有状态session beanQ可以区分不同的客户端,q保持他们的信息。主要是Ҏjsessionid来L认不同的客户?/font>q维护他们的状态?/p>
stateful session bean q程调用的时候,客户端得到的是一个客L代理对象Q不同的客户端获得不同的实例Q同时分配一个o牌)。通过令牌来区分不同的客户端。每ơ查找服务器新创Z个给客户端?/p>
stateless session bean 不对其状态做理。不是哪个客户端,得到的对象可能都是同一个实例(单例方式理Q。不能区分是哪个客户端。性能比stateful好。每ơ查找,服务器都q回同一个实例?/p>
Q?Qmessage driven bean ZJMS
2.实体bean
entity bean。EJB2的时候分为BMP(bean理持久化实体bean---自己理CRUD操作Q和CMPQ容器管理持久化实体bean--由容器管理CRUD操作Q?/p>
在EJB3中都是CMP?/p>
2.本地客户端:客户端和它调用的EJB对象在同一个(JBOSSQJVMq程当中。两个IQ怺调用?/p>
3.webservice客户?/p>
同一台机器上一个JVM和JBOSS
q行JBOSS需要一个JVMq程Q运行一个javac需要JVMq程?/p>
q程讉KQ传值方式:
本地讉K方式Q传地址方式Q无需序列化。(cMSSH方式Q?/p>
webservice只能讉K无状态会话bean的接口?/p>
q程调用Q客L的bean参数实际上是一个参数值的拯Q对他修改不会媄响到bean。但本地调用来说Q对bean的参数是个引用,修改媄响bean?/p>
_粒度的数据讉KQ?/p>
q程调用速度比较慢,量减少Ҏ的调用,可能在一个方法完成所以数据的传输?/p>
Q?Qsession beanQstateless和stateful session beanQ?/p>
会话beanQ从客户端获得EJB对象开始,然后调用EJBҎQ直到客L释放EJB对象为止。客L通过JNDI查找EJB对象。若每次会话查找同一对象Ӟ则返回不同对象?/p>
对象的状态由它的实例变量的值决定的?/p>
有状态session beanQ可以区分不同的客户端,q保持他们的信息。主要是Ҏjsessionid来L认不同的客户?/font>q维护他们的状态?/p>
stateful session bean q程调用的时候,客户端得到的是一个客L代理对象Q不同的客户端获得不同的实例Q同时分配一个o牌)。通过令牌来区分不同的客户端。每ơ查找服务器新创Z个给客户端?/p>
stateless session bean 不对其状态做理。不是哪个客户端,得到的对象可能都是同一个实例(单例方式理Q。不能区分是哪个客户端。性能比stateful好。每ơ查找,服务器都q回同一个实例?/p>
Q?Qmessage driven bean ZJMS
2.实体bean
entity bean。EJB2的时候分为BMP(bean理持久化实体bean---自己理CRUD操作Q和CMPQ容器管理持久化实体bean--由容器管理CRUD操作Q?/p>
在EJB3中都是CMP?/p>
工具QmyeclipseQ,jboss服务器?/font>
1.new--(myeclipse-j2EE projects)—EJB Project
2.new—ejb3 session bean
3.配置persistence.xml的持久化单元?/p>
Q?Q?nbsp; 配置数据?/p>
拷D:\DevelopTool\jboss-4.2.2.GA\docs\examples\jca里面的mysql-ds.xml到D:\DevelopTool\jboss-4.2.2.GA\server\default\deploy里面Q做修改?/p>
Q?Q拷数据库jar包到D:\DevelopTool\jboss-4.2.2.GA\server\default\lib里面
Q?Q在目属性里面添加额外的jar包:数据库驱动和D:\DevelopTool\jboss-4.2.2.GA\client\jbossall-client.jar?/p>