`
zhangzcz1999
  • 浏览: 147574 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

[转] 在JBoss服务器上开发 EJB3 应用的碰壁过程

阅读更多
[原创] 在JBoss服务器上开发 EJB3 应用的碰壁过程
我的JBoss服务器安装在 D:\jboss420GA 目录下。
为了开发Entity Bean映射Oracle的Table,我配置OracleDS数据源:
1、从 D:\jboss420GA\docs\examples\jca 将配置文件 oracle-ds.xml 复制到 D:\jboss420GA\server\default\deploy 下。
2、编辑修改oracle-ds.xml的内容:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
     <jndi-name>OracleDS</jndi-name>
     <connection-url>jdbc:oracle:thin:@localhost:1521:lw</connection-url>
     <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
     <user-name>scott</user-name>
     <password>tiger</password>
     <exception-sorter-class-name>
         org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter
     </exception-sorter-class-name>
     <metadata>
          <type-mapping>Oracle9i</type-mapping>
     </metadata>
</local-tx-datasource>
</datasources>

3、将Oracle的JDBC驱动程序 ojdbc14.jar 或 classes12.jar 复制到 D:\jboss420GA\server\default\lib 文件夹下。

4、在Netbeans IDE 中激活“运行环境”视图,选择“服务器”----“JBoss Application Server”,启动。启动过程中NetbeansIDE的输出窗口显示如下内容:


14:28:21,328 INFO   [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=OracleDS' to JNDI name 'java:OracleDS'
14:28:21,406 INFO   [TomcatDeployer] deploy, ctxPath=/jmx-console, warUrl=.../deploy/jmx-console.war/
14:28:21,953 INFO   [EARDeployer] Init J2EE application: file:/K:/J2ee/jboss-4.2.0.GA/server/default/deploy/EJB3Leaning.ear
......

注意粗体字内容,说明数据源配置文件没有问题。

5、编写Servlet测试数据源是否有效:新建Web项目,建立测试数据源的Servlet,其内容如下:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {

         response.setContentType("text/html;charset=UTF-8");
         PrintWriter out = response.getWriter();
         DataSource ds;
         try {
             ds = getOracleDS();
             Connection conn=ds.getConnection();
             Statement sta=conn.createStatement();
             ResultSet rs= sta.executeQuery("select * from Employee");
             while ( rs.next() ) {
                 out.println(rs.getString(2)+"<br>");
             }
             rs.close();
             conn.close();
         } catch (Exception ex) {
             ex.printStackTrace();
         }
         out.close();

}

private DataSource getOracleDS() throws NamingException {
         Context c = new InitialContext();
         return (DataSource) c.lookup("java:comp/env/OracleDS");
     }

运行,调用此Servlet,页面上成功列出了 Employee 表中所有雇员的名字。

说明,数据源配置正确。

6、创建“企业应用程序”项目,在EJB模块中,利用“通过数据库创建实体类”向导,选择OracleDS数据源,创建Employee表及其关联表映射的实体类,并同时创建持久化单元。持久化单元定义文件persistence.xml 内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="testEJB-ejbPU" transaction-type="JTA">
    <jta-data-source>OracleDS</jta-data-source>
    <properties/>
</persistence-unit>
</persistence>

7、部署EJB:在项目名称上右键点击,但后选择“部署项目”菜单项。注意观察JBoss服务器的输出信息。发现有如下错误信息:
15:04:55,437 INFO [PersistenceUnitDeployment] Starting persistence unit persistence.units:ear=testEJB.ear,unitName=testEJB-ejbPU
15:04:55,718 WARN [ServiceController] Problem starting service persistence.units:ear=testEJB.ear,unitName=testEJB-ejbPU
javax.naming.NameNotFoundException: OracleDS not bound
        at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
        at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
        at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
        at org.jnp.server.NamingServer.lookup(NamingServer.java:296)
        at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)

......

数据源配置没问题,但是发布EJB的时候就报数据源绑定错误。

为什么?!

这个问题困扰了我好几天,终于在 WikiJBoss 找到了答案。原来需要在数据原配置文件oracle-ds.xml中加入不使用Java上下文的选项:
<use-java-context>false</use-java-context>


WikiJBoss的原文摘录如下:
<use-java-context> - A boolean indicating if the jndi-name should be prefixed with java: which causes the DataSource to only be accessible from within the jboss server vm. The default is true.
Configuring a DataSource for remote usage
As of jboss-4.0.0 there is support for accessing a DataSource from a remote client. The one change that is necessary for the client to be able to lookup the DataSource from JNDI is to specify use-java-context=false as shown here:

<datasources>
  <local-tx-datasource>
    <jndi-name>GenericDS</jndi-name>
    <use-java-context>false</use-java-context>
    <connection-url>...</connection-url>
...

This results in the DataSource being bound under the JNDI name "GenericDS" instead of the default of "java:/GenericDS" which restricts the lookup to the same VM as the jboss server.

因此,作此修改后,前面测试数据源配置是否有效的Servlet就要做适当修改为:
private DataSource getOracleDS() throws NamingException {
         Context c = new InitialContext();
         return (DataSource) c.lookup("OracleDS");
     }
搞明白这些问题后,实体部署已经没问题了。


8、设计会话Bean:采用NetbeansIDE提供的“创建实体类的会话Bean”向导,创建Emp实体类的会话Bean,生成远程接口,然后部署到JBoss服务器上,过程正常。

9、编写Servlet,通过远程接口调用会话Bean:Servlet的主要代码如下:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        EmpFacadeRemote dao=lookupEmpFacade();
        List l=dao.findAll();
        for (int i=0; i<l.size(); i++){
            Emp e=(Emp)l.get(i);
            out.println(e.getEname()+"<br>");
        }
        out.close();
}

private EmpFacadeRemote lookupEmpFacade() {
        try {
            Context c = new InitialContext();
            return (EmpFacadeRemote) c.lookup("java:comp/env/ejb/EmpFacade");
        }
        catch(NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE,"exception caught" ,ne);
            throw new RuntimeException(ne);
        }
}

然后部署项目,运行项目,当Servlet被调用时,报错:
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception

java.lang.RuntimeException: javax.naming.NameNotFoundException: ejb not bound

 com.pqf.servlet.ListEmp.lookupEmpFacade(ListEmp.java:81)
 com.pqf.servlet.ListEmp.processRequest(ListEmp.java:38)
 com.pqf.servlet.ListEmp.doPost(ListEmp.java:64)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
 org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

root cause

javax.naming.NameNotFoundException: ejb not bound
 org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
 org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
 org.jnp.server.NamingServer.getObject(NamingServer.java:543)
 org.jnp.server.NamingServer.lookup(NamingServer.java:267)
 org.jnp.server.NamingServer.lookup(NamingServer.java:270)
 org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)
 org.jnp.interfaces.NamingContext.lookup(NamingContext.java:716)
 org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
 javax.naming.InitialContext.lookup(InitialContext.java:392)
 com.pqf.servlet.ListEmp.lookupEmpFacade(ListEmp.java:77)
 com.pqf.servlet.ListEmp.processRequest(ListEmp.java:38)
 com.pqf.servlet.ListEmp.doPost(ListEmp.java:64)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

 org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)


又是为何?

(完)
分享到:
评论
1 楼 meteormatt 2009-12-16  
这个帖子很有价值.
可惜我现在看不懂.

相关推荐

Global site tag (gtag.js) - Google Analytics