Tomcat客户端访问EJB远程方法错误解决(无法找到UserDaoImpl/Remote)昨天做的一个EJB测试项目,搞得我郁闷坏
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;}
服务器启动后,可以看到控制台提示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();}}}
在src下放置jndi.properties:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactoryjava.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>
同样在src下放jndi.properties进去
此时却出现问题了!
Java代码
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还真是要求苛刻啊
?
?
?