Java JNDI路径Tomcat与Jboss

Java JNDI路径Tomcat与Jboss,java,tomcat,jdbc,jboss,jndi,Java,Tomcat,Jdbc,Jboss,Jndi,我有一个DataSource,它在Tomcat6上的context.xml中配置为MyDataSource。 我用下面的方法获取它: DataSource dataSource; try { dataSource = (DataSource) new InitialContext().lookup("java:comp/env/MyDataSource"); } catch (NamingExceptio

我有一个DataSource,它在Tomcat6上的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);
            }
一切正常。现在我正在将此代码导出到JBossAP6。我将我的数据源及其连接池配置为同名的本地tx数据源

当我执行上面的代码时,我得到了NamingException。经过一些调查,我发现在Jboss下调用数据源的正确方法是

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

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

您可以将“jndi名称”标记添加到数据源定义中:

jndi名称—数据源应绑定到的jndi名称


您可以在JBossWiki上找到数据源文档:

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

步骤1:声明和查找资源引用 选择1 这可以通过在web部署描述符(
web-INF/web.xml
)中声明
资源引用来实现:

无论应用程序部署在哪个服务器上,此JNDI名称都不会更改

选择2 或者,从JavaEE5(Servlet2.5)开始,在代码中使用注释可以更轻松地完成这项工作。这样就无需在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的自定义部署描述符(
WEB-INF/JBoss WEB.xml
):


你也可以为你的
web.xml
jboss-web.xml
添加条目吗?@CoolBeans,我没有更多条目了。@denny.lesnik:好的。下一个问题是,您的数据源xml(*-ds.xml)中是否将
参数设置为true?您看过了吗?我认为
更合适的替代方案<代码>
将只定义一个全新的资源,而不是引用和重命名一个全局资源。
dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/MyDataSource");
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

}
<?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>
<Resource name="jdbc/MyDataSource" . . . />