2

可以创建 JNDI llookup 并且它在独立应用程序中的引用意味着没有任何应用程序服务器。

java:comp/env/jdbc

问候,

柴兔

4

3 回答 3

2

JNDI是Java平台提供的一种服务。请参考以下链接

http://www.javaworld.com/javaworld/jw-04-2002/jw-0419-jndi.html

于 2013-09-19T12:55:21.747 回答
1

您可以使用org.springframework.mock.jndi.SimpleNamingContextBuilderSpring 的类,依赖项或文件spring-mock-1.0.2.jar。例如:

  • 设置:

    SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
    builder.bind("jdbc/Oracle", ods);
    builder.activate();
    
  • 利用:

    DataSource ds = InitialContext.doLookup("jdbc/Oracle");
    
于 2016-05-18T21:11:03.813 回答
0

我通过注入 JNDI 数据源找到了更好的解决方案 (https://web.archive.org/web/20140530014804/https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit

新解决方案

如何运行需要“java:/comp/env/jdbc/keyofsomethingegdatabase”的 JUnit 测试

将以下 Jar 添加到 JUnit 测试用例的 CLASSPATH 中:

    TOMCAT_HOME/bin/tomcat-juli.jar (required by catalina.jar)
    TOMCAT_HOME/lib/catalina.jar (contains the actual factory)

在静态“for-all-tests”方法中创建您需要的绑定:

    @BeforeClass
    public static void setUpClass() throws Exception {
        ...
        // Use Apache Tomcat's Directory
        System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
        System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
        // Standard hook
        InitialContext initialContext = new InitialContext();
        // Create binding
        initialContext.createSubcontext("java:");
        initialContext.createSubcontext("java:comp");
        initialContext.createSubcontext("java:comp/env");
        initialContext.createSubcontext("java:comp/env/jdbc");
        // Construct DataSource
        OracleConnectionPoolDataSource dataSource = new OracleConnectionPoolDataSource();
        dataSource.setURL("jdbc:oracle:thin:@myserver:1521:MYSID");
        dataSource.setUser("username");
        dataSource.setPassword("password");

        initialContext.bind("java:comp/env/jdbc/mydatabase", dataSource);
        ...
    }


Then you can create this method in your Singleton class (either lookup method works):

    public Connection getConnection() throws NamingException, SQLException {
        if (dataSource == null) {
            Context initialContext = new InitialContext();
            boolean bLooksLikeChangeDirectory = false;
            if (bLooksLikeChangeDirectory) {
                Context context = (Context) initialContext.lookup("java:comp/env");
                dataSource = (DataSource) context.lookup("jdbc/mydatabase");
            } else {
                dataSource = (DataSource) initialContext.lookup("java:comp/env/jdbc/mydatabase");
            }
        }
        Connection result = dataSource.getConnection();
        return result;
    }

旧解决方案如下

这就是您如何使用独立的 JNDI(基于文件)来运行涉及:“new InitialContext() ... “lookup”的测试。这还描述了如何将 BoneCP(连接池)与 JNDI 一起使用。

您可以使用“com.sun.jndi.fscontext.RefFSContextFactory”(fscontext.jar 和 providerutil.jar)。

我希望“查找”也可以从应用程序服务器内部运行,因此如果有人可以确定是否必须使用查找(“java:comp/env/jdbc/mydbnickname”)而不是查找,那将很有用("jdbc/mydbnickname") 在应用程序服务器中运行时。

后者更可取,因为独立的 RefFSContextFactory 目录中不存在“java:comp/env”,因此您必须有一个系统属性来指定 JNDI 查找参数。

概述 您可以使用“jdbc/mydbnickname”作为“lookup”和“rebind”的参数(即没有“scheme:”)。在这种情况下,“RefFSContextFactory”使用“默认方案”,无论是什么(“file:”或“jndi:”)。在“jndi.properties”中使用以下内容(在 CLASSPATH 上)

 java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
        java.naming.provider.url=file:///u:/workdirectory
    and this in "persistence.xml" (JTA setup)
        <jta-data-source>jdbc/mydbnickname</jta-data-source>
    When you use:
        ...rebind("jdbc/mydbnickname", ...)
    and
        ...lookup("jdbc/mydbnickname")
    then the ".bindings" file (created by "rebind") is
        "u:/workdirectory/.bindings"
    and it looks like this (I have sorted it and tested it with just "lookup"):
        #This file is used by the JNDI FSContext.
        #Thu Jan 09 16:02:17 EST 2014
        jdbc/mydbnickname/ClassName=com.jolbox.bonecp.BoneCPDataSource
        jdbc/mydbnickname/FactoryName=com.jolbox.bonecp.BoneCPDataSource
        jdbc/mydbnickname/RefAddr/0/Content=oracle.jdbc.OracleDriver
        jdbc/mydbnickname/RefAddr/0/Encoding=String
        jdbc/mydbnickname/RefAddr/0/Type=driverClassName
        jdbc/mydbnickname/RefAddr/1/Content=jdbc\:oracle\:thin\:@myserver\:1521\:mysid
        jdbc/mydbnickname/RefAddr/1/Encoding=String
        jdbc/mydbnickname/RefAddr/1/Type=jdbcUrl
        jdbc/mydbnickname/RefAddr/2/Content=myusername
        jdbc/mydbnickname/RefAddr/2/Encoding=String
        jdbc/mydbnickname/RefAddr/2/Type=username
        jdbc/mydbnickname/RefAddr/3/Content=mypassword
        jdbc/mydbnickname/RefAddr/3/Encoding=String
        jdbc/mydbnickname/RefAddr/3/Type=password
    If you use
        "jndi:jdbc/mydbnickname"
    instead of
        "jdbc/mydbnickname",
    then the file created is
        u:/workdirectory/jdbc/.bindings
    and it looks like this:
        mydbnickname/ClassName=com.jolbox.bonecp.BoneCPDataSource
        mydbnickname/FactoryName=com.jolbox.bonecp.BoneCPDataSource
        mydbnickname/RefAddr/0/Content=oracle.jdbc.OracleDriver
        mydbnickname/RefAddr/0/Encoding=String
        mydbnickname/RefAddr/0/Type=driverClassName
        mydbnickname/RefAddr/1/Content=jdbc\:oracle\:thin\:@myserver\:1521\:mysid
        mydbnickname/RefAddr/1/Encoding=String
        mydbnickname/RefAddr/1/Type=jdbcUrl
        mydbnickname/RefAddr/2/Content=myusername
        mydbnickname/RefAddr/2/Encoding=String
        mydbnickname/RefAddr/2/Type=username
        mydbnickname/RefAddr/3/Content=mypassword
        mydbnickname/RefAddr/3/Encoding=String
        mydbnickname/RefAddr/3/Type=password
Rebind (in a JUnit Test)
    @BeforeClass
    public static void setUpClass() throws Throwable {
        final String sMyName = "setUpClass";
        try {
            if (Boolean.parseBoolean(System.getProperty("test.initialcontext.rebind", "true"))) {
                final InitialContext initialContext = new InitialContext();
                final String contextName = "jdbc/mydbnickname";
                final Reference contextValue = new Reference("com.jolbox.bonecp.BoneCPDataSource", "com.jolbox.bonecp.BoneCPDataSource", null);
                contextValue.add(new StringRefAddr("driverClassName", "oracle.jdbc.OracleDriver"));
                contextValue.add(new StringRefAddr("jdbcUrl", "jdbc:oracle:thin:@myserver:1521:mysid"));
                contextValue.add(new StringRefAddr("username", "myusername"));
                contextValue.add(new StringRefAddr("password", "mypassword"));
                initialContext.rebind(contextName, contextValue);
            }
        } catch (final Throwable exception) {
            Utils.getInstance().logExceptionStack(logger, Level.ERROR, sMyName, exception);
            throw exception;
        }
    }
Lookup (in production code)
    protected Connection getConnection() throws Exception {
        Connection result = null;
        // "An InitialContext instance is not synchronized against concurrent access by multiple threads"
        synchronized (this) {
            if (context == null) {
                context = new InitialContext();
            }
            final BoneCPDataSource connectionPool = (BoneCPDataSource) context.lookup("jdbc/mydbnickname"); 
            result = connectionPool.getConnection();
        }
        return result;
    }
CLASSPATH
    BoneCP Connection Pool
        <classpathentry kind="var" path="JAVA_LIB/bonecp-0.8.0.RELEASE.jar" sourcepath="/JAVA_LIB/bonecp-0.8.0.RELEASE-sources.jar"/>
        <classpathentry kind="var" path="JAVA_LIB/slf4j-api-1.7.5.jar" sourcepath="/JAVA_LIB/slf4j-api-1.7.5-sources.jar"/>
        <classpathentry kind="var" path="JAVA_LIB/guava-15.0.jar" sourcepath="/JAVA_LIB/guava-15.0-sources.jar"/>
        <classpathentry kind="var" path="JAVA_LIB/slf4j-simple-1.7.5.jar" sourcepath="/JAVA_LIB/slf4j-simple-1.7.5-sources.jar"/>
    Eclipse JPA (2.5.1)
        <classpathentry kind="var" path="JAVA_LIB/javax.persistence-2.1.0.jar"/>
        <classpathentry kind="var" path="JAVA_LIB/eclipselink-2.5.1.jar"/>
    JNDI
        <classpathentry kind="var" path="JAVA_LIB/fscontext.jar"/>
        <classpathentry kind="var" path="JAVA_LIB/providerutil.jar"/>
于 2014-01-09T05:58:08.473 回答