【问题标题】:Using multiple Contexts in J2EE to connect to different data sources (Websphere)在 J2EE 中使用多个上下文连接到不同的数据源(Websphere)
【发布时间】:2018-01-16 11:43:17
【问题描述】:

我有一个需要连接到两个数据库的 Java EE 应用程序。一个是内存数据库 (H2),一个是常规的 Oracle 数据库。

我可以在 Websphere Application Server 中设置到 Oracle 数据库的连接,在 ibm-web-bnd.xml 中放置一个引用,然后使用以下代码访问它:

DataSource dataSource = null;
try 
{
    InitialContext ctx = new InitialContext();
    // comp/env is for component-environment bindings, such as web application bindings
    // this allows us to change the name later in the binding (in the ibm-web-bnd.xml file), instead of here in the code.

    dataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/refDB");
}
catch (NamingException e)
{
    e.printStackTrace();
}

return dataSource.getConnection();

这很好 - InitialContext 返回我需要的 WAS 上下文,可以找到数据源,一切都很好。

但是,我还希望能够从同一个应用程序访问 H2 数据库。按照我在pluralsight上找到的教程,似乎这样做的方法是导入tomcat jar,然后即时创建上下文:

System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");

InitialContext ctx = new InitialContext();

//"java:comp/env/jdbc/CacheDb" is the context that needs creating here.
ctx.createSubcontext("java:");
ctx.createSubcontext("java:comp");
ctx.createSubcontext("java:comp/env");
ctx.createSubcontext("java:comp/env/jdbc");

JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL("jdbc:h2:mem:cachedb;DB_CLOSE_DELAY=-1"); // don't delete the database when the last connection closes

ctx.bind("java:comp/env/jdbc/CacheDb", dataSource);

如果它是应用程序中唯一的连接代码,此代码也可以工作。

如果我有一个应用程序在某个时候调用了两者,我会收到如下错误:

SystemErr R javax.naming.NoInitialContextException: 找不到 InitialContextFactory org.apache.naming.java.javaURLContextFactory.

然后我想,好吧,也许 System.setProperty 代码导致错误的上下文用于 Oracle 查找 - 所以我尝试在获取 Oracle 连接的 InitialContext 之前使用以下代码专门指定 WAS 上下文:

System.setProperty(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "com.ibm.websphere.naming");

但是,在配置 H2 数据库上下文时,这给了我同样的错误。

谁能解释我做错了什么,或者为我指出正确的解决方案?谢谢

【问题讨论】:

  • 上下文已经存在,因此您不需要创建子上下文。不能像配置 Oracle 数据库一样配置 h2 数据库吗?
  • 我没试过。我遵循的教程没有说,但没有说为什么。我不知道你会怎么做,因为它在内存中(由代码创建,而不是存在于应用程序之外) - 所以我无法建立与 WAS 控制台的连接(可以吗?)
  • 其实,非常好的问题。我没有在 WebSphere 中使用过 h2,所以我不知道。只要它找到所有类,我想它应该可以工作。但作为替代方案,您至少应该不需要创建已经存在的子上下文。您可以删除这些行 (ctx.createSubcontext) 并查看是否可以将数据源绑定到上下文?
  • 另外,为InitialContext 工厂设置哪些类可能会搞砸。无需更改系统属性就可以得到特定的InitialContext
  • 我不知道。 new InitialContext() 有一个采用哈希表的覆盖

标签: jakarta-ee websphere application-server


【解决方案1】:

我假设您使用的是传统的 WebSphere Application Server,而不是 Liberty。两者都可以像任何其他 JDBC 兼容数据库一样通过 DataSource 访问 h2 数据库。听起来您已经为 Oracle 配置了 jdbc 提供程序和 DataSource。您只需要按照IBM KnowledgeCenter topic 中的说明为 h2 创建和配置用户定义的 jdbc 提供程序和关联的数据源。由于您在 web.xml 中配置资源引用,因此让应用服务器为您完成工作,并简单地将两个数据源注入您的应用程序,例如

@Resource(lookup="jdbc/refDB")
DataSource oracleDS;
@Resource(lookup="jdbc/CacheDb")
DataSource h2DS;

您不需要在 JNDI 中进行直接查找(也不应该),也不必担心 InitialContext。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    相关资源
    最近更新 更多