Tomcat客户端访问EJB远程方法异常解决(无法找到UserDaoImpl/Remote)

Tomcat客户端访问EJB远程方法错误解决(无法找到UserDaoImpl/Remote)

昨天做的一个EJB测试项目,搞得我郁闷坏了。

Jboss5.0.1GA

Tomcat6.0

Jdk 1.6

新建EJB服务器端为JAVAEE5.0项目

WEB客户端也是JAVAEE5.0项目(默认包含javaee.jar这个包,跟jboss-javaee.jar基本相同,两者任意一个放到tomcat/lib下都可以,这是最后才知道的,刚开始没这么放)

 

 

服务器端:

Java 代码
  1. @Stateless   
  2. @Remote ({UserDao. class })  
  3. public   class  UserDaoImpl  implements  UserDao {  
  4.     /**  
  5.      * unitName="ejb" 是 调用persistence.xml中的ejb这个数据源  
  6.      * 如果persistence.xml里只有一个数据源配置,则无需显示调用unitName="ejb"  
  7.      */   
  8.     @PersistenceContext (unitName= "ejb" )  
  9.     private  EntityManager em;  
  10.       
  11.     @SuppressWarnings ( "unchecked" )  
  12.     public  List<User> getAll(){  
  13.         Query query = em.createQuery("from User u order by u.id desc" );  
  14.         List<User> users = query.setMaxResults(100 ).setFirstResult( 0 ).getResultList();  
  15.         em.clear();  
  16.         System.out.println("getAll has been called!! ! " );  
  17.         return  users;  
  18.     }  
@Stateless
@Remote({UserDao.class})
public class UserDaoImpl implements UserDao {
	/**
	 * unitName="ejb" 是调用persistence.xml中的ejb这个数据源
	 * 如果persistence.xml里只有一个数据源配置,则无需显示调用unitName="ejb"
	 */
	@PersistenceContext(unitName="ejb")
	private EntityManager em;
	
	@SuppressWarnings("unchecked")
	public List<User> getAll(){
		Query query = em.createQuery("from User u order by u.id desc");
		List<User> users = query.setMaxResults(100).setFirstResult(0).getResultList();
		em.clear();
		System.out.println("getAll has been called!! ! ");
		return users;
	}


服务器启动后,可以看到控制台提示UserDaoImpl/remote已经绑定到服务器。

客户端端1:
普通的JAVA类进行客户端访问

Java 代码
  1. public   class  EJBClient {  
  2.       
  3.     public   static   void  main(String[] args)  throws  Exception{  
  4.         try {  
  5.             //默认情况下去类路径src下寻找jndi.properties,也可以显示的写出来   
  6.             InitialContext ctx = new  InitialContext();  
  7.             UserDao userDao=(UserDao)ctx.lookup("UserDaoImpl/remote" );  
  8.             List<User> users = userDao.getAll();  
  9.             System.out.println(users.get(0 ).getUsername());  
  10.         }catch (Exception e){  
  11.             e.printStackTrace();  
  12.         }  
  13.     }  
  14. }  
public class EJBClient {
	
	public static void main(String[] args) throws Exception{
		try{
			//默认情况下去类路径src下寻找jndi.properties,也可以显示的写出来
			InitialContext ctx = new InitialContext();
			UserDao userDao=(UserDao)ctx.lookup("UserDaoImpl/remote");
			List<User> users = userDao.getAll();
			System.out.println(users.get(0).getUsername());
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}


在src下放置jndi.properties:

Java 代码
  1. java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory  
  2. java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces   
  3. java.naming.provider.url=jnp://localhost:1099   
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces 
java.naming.provider.url=jnp://localhost:1099


此时,客户端可以正常访问远程方法!

客户端端2:
新建一个web项目,把jboss中的client包里的所有jar包都拷贝到项目中。
新建一个JSP页面,将客户端1中的代码复制进去
index.jsp:

Java 代码
  1. <%@ page language= "java"  pageEncoding= "UTF-8" %>  
  2. <%@page   import = "javax.naming.InitialContext,java.util.*,dao.UserDao,entity.User" %>  
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >  
  4. <html>  
  5.   <head>  
  6.     <title>My JSP 'index.jsp'  starting page</title>  
  7.   </head>  
  8.     
  9.   <body>  
  10.    <%  
  11.         InitialContext ctx = new  InitialContext();  
  12.         System.out.println(ctx.getEnvironment());  
  13.         UserDao userDao=(UserDao)ctx.lookup("UserDaoImpl/remote" );  
  14.         List<User> users = userDao.getAll();  
  15.         System.out.println(users.get(0 ).getUsername());  
  16.    %>  
  17.     <a href="test.do" >测试servlet</a>  
  18.   </body>  
  19. </html>  
<%@ page language="java" pageEncoding="UTF-8"%>
<%@page import="javax.naming.InitialContext,java.util.*,dao.UserDao,entity.User"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  
  <body>
   <%
	   	InitialContext ctx = new InitialContext();
		System.out.println(ctx.getEnvironment());
		UserDao userDao=(UserDao)ctx.lookup("UserDaoImpl/remote");
		List<User> users = userDao.getAll();
		System.out.println(users.get(0).getUsername());
   %>
   	<a href="test.do">测试servlet</a>
  </body>
</html>


同样在src下放jndi.properties进去
此时却出现问题了!

Java 代码
  1. 2010 - 5 - 6   0 : 06 : 45  org.apache.catalina.core.StandardWrapperValve invoke  
  2. 严 重: Servlet.service() for  servlet jsp threw exception  
  3. javax.naming.NameNotFoundException: Name UserDaoImpl is not bound in this  Context  
  4.     at org.apache.naming.NamingContext.lookup(NamingContext.java:770 )  
  5.     at org.apache.naming.NamingContext.lookup(NamingContext.java:153 )  
  6.     at org.apache.naming.SelectorContext.lookup(SelectorContext.java:137 )  
  7.     at javax.naming.InitialContext.lookup(InitialContext.java:392 )  
  8.     at org.apache.jsp.index_jsp._jspService(index_jsp.java:79 )  
  9.     at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70 )  
  10.     at javax.servlet.http.HttpServlet.service(HttpServlet.java:803 )  
  11.     at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393 )  
  12.     at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320 )  
  13.     at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266 )  
  14.     at javax.servlet.http.HttpServlet.service(HttpServlet.java:803 )  
  15.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290 )  
  16.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206 )  
  17.     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233 )  
  18.     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175 )  
  19.     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128 )  
  20.     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102 )  
  21.     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109 )  
  22.     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263 )  
  23.     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844 )  
  24.     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584 )  
  25.     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447 )  
  26.     at java.lang.Thread.run(Thread.java:619 )

 

 

经过前辈们的指导,显示的把远程调用配置信息写到代码里就可以找到remote方法了:

[code='java']

<%
           Properties props = new Properties(); 
        props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory"); 
        props.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces"); 
        props.setProperty("java.naming.provider.url","jnp://localhost:1099"); 

         InitialContext ctx = new InitialContext(props);
        System.out.println(ctx.getEnvironment());
        UserDao userDao=(UserDao)ctx.lookup("UserDaoImpl/remote");
        List<User> users = userDao.getAll();
        System.out.println(users.get(0).getUsername());
   %>

[/code]

但是问题又出现了 :

Tomcat启动提示无法加载jboss-javaee.jar包。后来把这个jar包放到tomcat/lib文件夹下就可以解决此问题,一切正常了。(其实只需要这个包里的security包,把它拉出来即可)。


这个问题出现的比较怪异,解决方法也令人蛋疼,看来EJB还真是要求苛刻啊