JNDI路径Tomcat与Jboss

dan*_*nik 15 java jboss tomcat jndi jdbc

我有DataSource,它在context.xml中的T​​omcat 6上配置为MyDataSource.我正在通过以下方式获取它:

      DataSource dataSource;
            try {
                dataSource = (DataSource) new InitialContext().lookup("java:comp/env/MyDataSource");
            } catch (NamingException e) {
                throw new DaoConfigurationException(
                    "DataSource '" + url + "' is missing in JNDI.", e);
            }
Run Code Online (Sandbox Code Playgroud)

一切正常.现在我将此代码导出到Jboss AP 6.我将我的dataSource及其连接池配置为local-tx dataSource,名称相同.

当我执行上面的代码时,我收到了NamingException异常.经过一番调查后,我发现在Jboss下调用我的DataSource的正确方法是

 dataSource = (DataSource) new InitialContext().lookup("java:/MyDataSource");
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释一下我为什么要在Jboss下的JNDI路径中省略"comp/env"?

she*_*ley 26

用于定义数据源的可移植方法是使用资源引用.资源引用使您能够相对于应用程序命名上下文(java:comp/env)定义数据源的JNDI名称,然后将该逻辑引用映射到应用程序服务器中定义的物理资源,其JNDI名称是应用程序服务器供应商专有的.这种方法使您的代码和程序集可以移植到任何兼容的应用程序服务器.

第1步:声明和查找资源参考

选项1

这可以通过resource-ref在Web部署描述符(WEB-INF/web.xml)中声明一个来完成:

<resource-ref>
    <description>My Data Source.</description>
    <res-ref-name>jdbc/MyDataSource</res-ref-name> 
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
Run Code Online (Sandbox Code Playgroud)

在代码中,您可以使用JNDI名称查找此资源java:comp/env/jdbc/MyDataSource:

dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/MyDataSource");
Run Code Online (Sandbox Code Playgroud)

无论部署应用程序的服务器如何,此JNDI名称都不会更改.

选项2

或者,从Java EE 5(Servlet 2.5)开始,使用@Resource注释可以在代码中更轻松地完成此操作.这消除了在Web部署描述符(web.xml)中配置resource-ref的需要,并且无需执行显式JNDI查找:

public class MyServlet extends HttpServlet {

    @Resource(name = "jdbc/MyDataSource")
    private DataSource dataSource;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // dataSource may be accessed directly here since the container will automatically
        // inject an instance of the data source when the servlet is initialized

}
Run Code Online (Sandbox Code Playgroud)

此方法与前一个选项具有相同的结果,但会减少程序集中的样板代码和配置.

第2步:将资源引用映射到数据源

然后,您将需要使用应用程序服务器的专有方法将资源引用映射到您在服务器上创建的物理数据源,例如,使用JBoss的自定义部署描述符(WEB-INF/jboss-web.xml):

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <resource-ref>
        <res-ref-name>jdbc/MyDataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <jndi-name>java:/MyDataSource</jndi-name>
    </resource-ref>
</jboss-web>
Run Code Online (Sandbox Code Playgroud)

或者,例如,使用Tomcat context.xml:

<Resource name="jdbc/MyDataSource" . . . />
Run Code Online (Sandbox Code Playgroud)