是否可以创建JNDI llookup,它在独立应用程序中的引用意味着没有任何应用程序服务器。
java:comp/env/jdbc
此致
Chaitu
答案 0 :(得分:1)
JNDI是Java平台提供的服务。请参阅以下链接
http://www.javaworld.com/javaworld/jw-04-2002/jw-0419-jndi.html
答案 1 :(得分:1)
您可以使用Spring的org.springframework.mock.jndi.SimpleNamingContextBuilder
类,dependency或文件spring-mock-1.0.2.jar
。 e.g:
<子>设置:子>
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
builder.bind("jdbc/Oracle", ods);
builder.activate();
<子>使用:子>
DataSource ds = InitialContext.doLookup("jdbc/Oracle");
答案 2 :(得分:0)
我找到了一个更好的解决方案Injecting JNDI datasources (https://web.archive.org/web/20140530014804/https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_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查找参数的System属性。
概述 您可以使用“jdbc / mydbnickname”作为“查找”和“重新绑定”的参数(即没有“方案:”)。 在这种情况下,“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"/>