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下都可以,这是最后才知道的,刚开始没这么放)
服务器端:
- @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;
- }
@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类进行客户端访问
- 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();
- }
- }
- }
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.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
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:
- <%@ 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>
<%@ 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进去
此时却出现问题了!
- 2010 - 5 - 6 0 : 06 : 45 org.apache.catalina.core.StandardWrapperValve invoke
- 严 重: Servlet.service() for servlet jsp threw exception
- javax.naming.NameNotFoundException: Name UserDaoImpl is not bound in this Context
- at org.apache.naming.NamingContext.lookup(NamingContext.java:770 )
- at org.apache.naming.NamingContext.lookup(NamingContext.java:153 )
- at org.apache.naming.SelectorContext.lookup(SelectorContext.java:137 )
- at javax.naming.InitialContext.lookup(InitialContext.java:392 )
- at org.apache.jsp.index_jsp._jspService(index_jsp.java:79 )
- 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:393 )
- at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320 )
- at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266 )
- 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.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233 )
- at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175 )
- at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128 )
- at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102 )
- at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109 )
- at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263 )
- at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844 )
- at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584 )
- at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447 )
- 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还真是要求苛刻啊