轻松启动独立JNDI服务器(并注册一些资源)
出于测试目的,我正在寻找一种简单的方法来启动独立的 JNDI服务器,并以编程方式将我的javax.sql.DataSource绑定到"java:/comp/env/jdbc/mydatasource"
。
服务器应该将自己绑定到某个URL,例如:“java.naming.provider.url = jnp:// localhost:1099”(不一定是JNP),这样我就可以从另一个进程查找我的数据源。 我不关心我必须使用哪个JNDI服务器实现(但我不想启动一个成熟的JavaEE服务器)。
这应该很容易,但令我惊讶的是,我找不到任何(工作)教程。
JDK包含RMI注册表的JNDI提供程序 。 这意味着您可以将RMI注册表用作JNDI服务器。 所以,只需启动rmiregistry ,将java.naming.factory.initial设置为com.sun.jndi.rmi.registry.RegistryContextFactory ,就可以了。
RMI注册表具有平面命名空间, 因此您将无法绑定到java:/ comp / env / jdbc / mydatasource,但您将能够绑定到某些东西,因此它将接受java:/ comp / env / jdbc / mydatasource,但会将其视为单个组件名称(感谢@EJP)。
我写了一个小应用程序来演示如何执行此操作: https : //bitbucket.org/twic/jndiserver/src
我仍然不知道JNP服务器应该如何工作。
我研究了约翰的代码,现在工作得很好。
在这个版本中,我使用的是JBoss5.1.0.GA的库,请参阅下面的jar列表:
- jboss-5.1.0.GA \客户\ jbossall-client.jar中
- jboss-5.1.0.GA \服务器\最小\ LIB \ jnpserver.jar
- jboss-5.1.0.GA \服务器\最小\ LIB \ log4j.jar
- jboss-remote-naming-1.0.1.Final.jar(从http://search.maven.com下载)
这是新代码:
import java.net.InetAddress; import java.util.Hashtable; import java.util.concurrent.Callable; import javax.naming.Context; import javax.naming.InitialContext; import org.jnp.server.Main; import org.jnp.server.NamingBeanImpl; public class StandaloneJNDIServer implements Callable
要获得良好的日志记录,请使用此log4j属性:
log4j.rootLogger=TRACE, A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
要使用独立JNDI服务器,请使用此客户端类:
import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; /** * * @author fabiojm - Fábio José de Moraes * */ public class Lookup { public Lookup(){ } @SuppressWarnings("unchecked") public static void main(String[] args) { final Hashtable _properties = new Hashtable(); _properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); _properties.put("java.naming.provider.url", "jnp://10.10.10.200:5400"); try{ final Context _context = new InitialContext(_properties); System.out.println(_context); System.out.println(_context.lookup("java:comp")); System.out.println(_context.lookup("java:jdbc")); }catch(Exception _e){ _e.printStackTrace(); } } }
这是一个改编自JBoss遥控样本的代码片段。 样本中的代码(版本2.5.4.SP2)不再有效。 虽然修复很简单,但我花了更多的时间来考虑解决这个问题。 叹。 无论如何,也许有人可以受益。
package org.jboss.remoting.samples.detection.jndi.custom; import java.net.InetAddress; import java.util.concurrent.Callable; import org.jnp.server.Main; import org.jnp.server.NamingBeanImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class StandaloneJNDIServer implements Callable
我知道我已经迟到了,但我最终还是像这样一起黑客攻击
InitialContext ctx = new InitialContext(); // check if we have a JNDI binding for "jdbc". If we do not, we are // running locally (ie through JUnit, etc) boolean isJndiBound = true; try { ctx.lookup("jdbc"); } catch(NameNotFoundException ex) { isJndiBound = false; } if(!isJndiBound) { // Create the "jdbc" sub-context (ie the directory) ctx.createSubcontext("jdbc"); //parse the jetty-web.xml file Map dataSourceProperties = JettyWebParser.parse(); //add the data sources to the sub-context for(String key : dataSourceProperties.keySet()) { DataSource ds = dataSourceProperties.get(key); ctx.bind(key, ds); } }
你考虑过使用Mocks吗? 如果我没记错,您可以使用Interfaces与JNDI进行交互。 我知道我以前至少曾经嘲笑过他们一次。
作为后备,你可以使用Tomcat。 它不是一个完整的J2EE impl,它启动速度很快,并且很容易配置JNDI资源。 DataSource设置已有详细记录。 这是次优的,但应该有效。
你暗示你发现了非工作教程; 这可能意味着你已经看过这些:
- J2EE还是J2SE? JNDI适用于两者
- 使用jnpserver.jar的独立JNDI服务器
我快点走了,但无法让这个工作。 但是,坚持不懈可能会有所作为。
对于本地,一个进程独立的jar purpouses我会使用spring-test包:
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); SQLServerConnectionPoolDataSource myDS = new SQLServerConnectionPoolDataSource(); //setup... builder.bind("java:comp/env/jdbc/myDS", myDS); builder.activate();
启动日志:
22:33:41.607 [main] INFO org.springframework.mock.jndi.SimpleNamingContextBuilder - Static JNDI binding: [java:comp/env/jdbc/myDS] = [SQLServerConnectionPoolDataSource:1] 22:33:41.615 [main] INFO org.springframework.mock.jndi.SimpleNamingContextBuilder - Activating simple JNDI environment
我最近一直在寻找类似的简单启动器解决方案。 “Sun Microsystems的文件系统服务提供商”对我很有帮助。 请参阅https://docs.oracle.com/javase/jndi/tutorial/basics/prepare/initial.html 。
RMI注册表的问题是您需要一个查看器 – 在这里您只需要查看文件内容。
您可能需要fscontext-4.2.jar – 我是从http://www.java2s.com/Code/Jar/f/Downloadfscontext42jar.htm获得的。
- 在persistence.xml中引用Tomcat JNDI数据源
- 防止JBoss 7上的JNDI数据源的Oracle连接自动提交(Jeeves DBMS)
- 如何将JRBeanCollectionDataSource传递给iReport?
- 带有mysql DataSource的javax.naming.NoInitialContextException
- 如何使用一个DataSource以编程方式更改Spring中的数据库?
- 如何将PostgreSQL数据源添加到WildFly 9.0?
- 使用javamail API发送带附件的电子邮件
- Spring中具有多个事务管理器的多个DataSource
- 动态数据源路由