JNDI 路径 Tomcat 与 Jboss

Posted

技术标签:

【中文标题】JNDI 路径 Tomcat 与 Jboss【英文标题】:JNDI path Tomcat vs. Jboss 【发布时间】:2011-11-05 15:45:09 【问题描述】:

我有 DataSource,它在 Tomcat 6 上的 context.xml 中配置为 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);
            

一切正常。现在我将此代码导出到 Jboss AP 6。我将我的数据源及其连接池配置为同名的 local-tx 数据源。

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

 dataSource = (DataSource) new InitialContext().lookup("java:/MyDataSource");

谁能解释我为什么要在 Jboss 下的 JNDI 路径中省略“comp/env”?

【问题讨论】:

您能否也为您的web.xmljboss-web.xml 添加条目? @CoolBeans,我没有更多条目了。 @denny.lesnik:好的。下一个问题是您的数据源 xml (*-ds.xml) 中是否将 <use-java-context> 参数设置为 true? 你看过***.com/questions/47676/…吗? 【参考方案1】:

您可以在数据源定义中添加“jndi-name”标签:

jndi-name - 数据源应绑定到的 JNDI 名称。

您可以在 JBoss wiki 上找到数据源文档:ConfigDataSources

【讨论】:

【参考方案2】:

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

第 1 步:声明和查找资源引用

选项 1

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

<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>

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

dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/MyDataSource");

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

选项 2

或者,从 Java EE 5 (Servlet 2.5) 开始,使用 @Resource 注释可以在您的代码中更轻松地完成此操作。这消除了在 Web 部署描述符 (web.xml) 中配置资源引用的需要,并避免了执行显式 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


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

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

然后,您需要使用应用服务器的专有方法将资源引用映射到您在服务器上创建的物理数据源,例如,使用 JBoss 的自定义部署描述符 (@987654330 @):

<?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>

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

<Resource name="jdbc/MyDataSource" . . . />

【讨论】:

我认为&lt;ResourceLink&gt;&lt;resource-ref&gt; 的更合适的替代品。 &lt;Resource&gt; 只会定义一个全新的资源,而不是引用和重命名全局资源。

以上是关于JNDI 路径 Tomcat 与 Jboss的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat,Jboss,Weblogic通过jndi连接数据库

JNDI 在 JMS 中使用 JBoss 查找错误

如何使用 HikariCP 在 Jboss 中配置 JNDI 数据源?

Jboss7.1 MDB - 本地 JNDI 参考与全球 JNDI 参考

骆驼路由输入端点的 JBoss 嵌入式 MQ 的 jndi 查找问题

JBoss 中的 JNDI 绑定(LiveCycle 统包)