【问题标题】:resource reference in EJB3EJB3 中的资源引用
【发布时间】:2013-04-10 21:20:23
【问题描述】:

这可能是一个常见问题,我正在尝试为 Websphere 7.0 中的数据源创建一个带有资源引用的无状态会话 EJB 3.0。

以下代码正在运行:

package com;
import javax.ejb.Stateless;
import javax.annotation.Resource;
import javax.sql.DataSource;
@Stateless
public class Test1 implements Test1Remote {
 @Resource DataSource ds;
 public Test1() {}
 public boolean testDs() {
  boolean valid = true;
  try {
   ds.getConnection();
  } catch (Exception e) {
   e.printStackTrace();
   valid = true;
  }
  return valid;
 }
}


<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd
    xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee 
    http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd" version="1.0">

    <session name="Test1">
     <interface class="com.Test1Remote" binding-name="Test1"/>
     <resource-ref name="com.Test1/ds" binding-name="jdbc/myDataSource"></resource-ref>
    </session>
</ejb-jar-bnd>

以下代码不起作用并给我异常

javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".

但不确定当需要在 EJB 之外的 initialContext 中查找数据源时如何进行。

package com;
import javax.ejb.Stateless;
@Stateless
public class Test1 implements Test1Remote {
    public Test1() {
    }
    public boolean testDs(){
     boolean valid = true;
     try {
         MyConnection ds = new MyConnection();
         ds.getConnection();
     } catch (Exception e) {
        e.printStackTrace();
        valid = true;
    }
    return valid;
    }
}

package com;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;


public class MyConnection{
    private DataSource ds;
    public Object getConnection() throws Exception  {
 try {
    final InitialContextinitCtx = new InitialContext();
    ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/myDataSource");
    return ds.getConnection();
    } catch (NamingException e) {
     e.printStackTrace();
     throw e;
    } catch (SQLException e) {
     e.printStackTrace();
     throw e;
    }
 }
}

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd
    xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee 
    http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd" version="1.0">

    <session name="Test1">
     <interface class="com.Test1Remote" binding-name="Test1"/>
    </session>
</ejb-jar-bnd>

如果我在数据源查找中不使用“java:comp/env/”,那么它可以正常工作,但这不是一个好习惯。

更新:感谢您的回复。我的目标是将现有的 EJB 2.1 替换为 EJB 3.0。当前的 EJB 2.1 的设计类似于代码 sn-p 2,所以我编写了这个测试。 EJB 2.1 使用在 ejb 外部定义的资源运行(但在 ejb-jar.xml 中声明了资源引用)。如果我不遵循相同的方法,那么它将产生我想要避免的巨大影响。

【问题讨论】:

    标签: websphere ejb-3.0 resourcereference


    【解决方案1】:

    @Resource 替换为@Resource(name="jdbc/myDataSource"),它应该可以工作。

    【讨论】:

    • 带注释的代码运行良好,问题在于第二个 sn-p 代码在 EJB 之外查找数据源...
    • 是的,更改注解将确保 JNDI 名称是您在其他代码 sn-p 中所期望的。
    • 很抱歉,我不确定您要我在哪里替换注释。在代码 sn-p 2 中,我只使用了@Stateless 注解。如果可能,您能提供代码吗?
    • 如果您想完全摆脱注入,那么您需要创建一个 ejb-jar.xml 部署描述符并在那里声明资源引用(就像您在 EJB 2.1 中所做的那样)。
    【解决方案2】:

    您必须使用驻留在服务器中的资源的 JNDI 名称(即:java:comp/env/jdbc/myDataSource)。 JNDI 名称是资源的唯一标识符。无论是独立的 java 还是容器驱动的 java,都没有其他办法。如果您使用的是 EJB,那么您可以使用注释并引用资源,但仍然会在您提到 JNDI 名称的绑定文件中查找该资源。无论哪种方式,您都必须使用资源的 JNDI 名称。

    答案已更新

    如果您使用的是 EJB,那么只需使用注释来访问资源,就像您第一次所做的那样。你正在做的是一个不好的做法。因为 EJB 是在容器中加载和维护的。没有保证 DataSource POJO 将在 EJB 调用它之前由类加载器加载。两者都有不同的生命周期。所以让容器为你注入资源。这是正确的做法。因此,EJB 依赖于 POJO 是一种不好的做法。在 Java EE 中不推荐使用。

    【讨论】:

    • 感谢您的回复。我同意我必须使用 JNDI 名称,但不知道如何在我拥有的第二个 sn-p 代码中使用它。
    • 如果您使用的是 EJB,那么只需使用注释来访问资源,就像您第一次所做的那样。你正在做的是一个不好的做法。因为 EJB 是在容器中加载和维护的。没有保证 DataSource POJO 将在 EJB 调用它之前由类加载器加载。两者都有不同的生命周期。所以让容器为你注入资源。这是正确的做法。因此,EJB 依赖于 POJO 是一种不好的做法。不推荐在 J2EE 中使用。问候,拉维。
    猜你喜欢
    • 1970-01-01
    • 2011-03-30
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多