尝试使用Simple-JNDI

时间:2018-08-18 18:08:49

标签: java unit-testing jndi hsqldb in-memory-database

出于单元测试的目的,我试图将JNDI设置为不使用Tomcat即可连接到HSQLDB。为此,我正在使用Simple-JNDI,并遵循此website

所以首先我创建了一个将初始化JNDI数据源的类:

import org.hsqldb.jdbc.JDBCDataSource;    
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JndiDataSource {
    public void Initialize() throws NamingException {
        // Create initial context
        System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.osjava.sj.MemoryContextFactory");
        System.setProperty("org.osjava.sj.jndi.shared", "true");
        InitialContext ic = new InitialContext();

        ic.createSubcontext("java:/comp/env/jdbc");

        // Construct DataSource
        JDBCDataSource ds = new JDBCDataSource();
        ds.setDatabase("jdbc:hsqldb:hsql://localhost/xdb");
        ds.setUser("SA");
        ds.setPassword("");

        // Put datasource in JNDI context
        ic.bind("java:/comp/env/jdbc/myDS", ds);
    }
}

然后在单元测试中,我打电话给Initialize(),只是尝试查找数据源。

import org.junit.jupiter.api.Test;    
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class JndiDataSourceTest {
    @Test
    public void testInitialize() throws NamingException {
        JndiDataSource jds = new JndiDataSource();
        jds.Initialize();

        InitialContext ic = new InitialContext();
        DataSource ds = (DataSource)ic.lookup("java:/comp/env/jdbc/myDS");
    }
}

不幸的是,当我尝试调试此单元测试时,它在查找上失败,(DataSource)ic.lookup("java:/comp/env/jdbc/myDS");调试器说,

javax.naming.NameNotFoundException: java:/comp/env/jdbc/myDS

所以问题是,我在做什么错了?

2 个答案:

答案 0 :(得分:0)

可能是一个简单的错字-恕我直言,它应该是org.osjava.sj。内存 .MemoryContextFactory

答案 1 :(得分:0)

Simple-JNDI 0.17.0的问题在于org.osjava.sj.MemoryContextFactory不考虑系统属性。因此,每次致电

O(t)

初始化了一个新的MemoryContext,它与先前已初始化的MemoryContext不共享任何东西。

我认为我应该改变这种行为。在此之前,有两种解决方案。

第一

在jpath中将以下内容添加到类路径中:

new InitialContext()

因此您可以省去系统属性。

第二

更容易出错的方法。使用需要环境配置的构造函数:

java.naming.factory.initial = org.osjava.sj.MemoryContextFactory
org.osjava.sj.jndi.shared = true

每次实例化一个新的InitialContext时,都必须为构造函数提供以下环境:

InitialContext(Hashtable<?, ?> environment)

我也建议您设置

    System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.osjava.sj.MemoryContextFactory");

    Hashtable env = new Hashtable();
    env.put("org.osjava.sj.jndi.shared", "true");

    InitialContext ic = new InitialContext(env);

    ic.createSubcontext("java:/comp/env/jdbc");

    JDBCDataSource ds = new JDBCDataSource();
    ds.setDatabase("jdbc:hsqldb:hsql://localhost/xdb");
    ds.setUser("SA");
    ds.setPassword("");

    ic.bind("java:/comp/env/jdbc/myDS", ds);

    // And elsewhere

    Hashtable env = new Hashtable();
    env.put("org.osjava.sj.jndi.shared", "true");
    InitialContext ic2 = new InitialContext(env);
    DataSource dataSource = (DataSource) ic2.lookup("java:/comp/env/jdbc/myDS");
    assertNotNull(dataSource);

Simple-JNDI 0.17.0优于0.11.4.1。参见here