new InitialContext() 的无限递归
infinite recursion on new InitialContext()
我正在尝试为 Java SE 控制台应用程序设置 JNDI。
我有以下代码:
public class FooMain {
public static void main (String args[]) throws NamingException {
Context context = new InitialContext();
context.bind("foo", "bar");
}
}
…上下文工厂定义为:
public class MyContextFactory implements InitialContextFactory {
private static Hashtable store = new Hashtable();
@Override
public Context getInitialContext(Hashtable environment) throws NamingException {
return new InitialContext() {
@Override
public void bind(String name, Object obj) {
store.put(name, obj);
}
@Override
public Object lookup(String name) {
return store.get(name);
}
};
}
}
当我调用我的 FooMain
class 时使用:
java -Djava.naming.factory.initial=MyContextFactory -cp ... FooMain
我得到了无限递归和最终的 Whosebug 异常:
Exception in thread "main" java.lang.WhosebugError
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.naming.internal.VersionHelper12.getContextClassLoader(VersionHelper12.java:185)
at com.sun.naming.internal.ResourceManager.getApplicationResources(ResourceManager.java:549)
at com.sun.naming.internal.ResourceManager.getInitialEnvironment(ResourceManager.java:244)
at javax.naming.InitialContext.init(InitialContext.java:240)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
at MyContextFactory.<init>(MyContextFactory.java:20)
at MyContextFactory.getInitialContext(MyContextFactory.java:20)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
at MyContextFactory.<init>(MyContextFactory.java:20)
at MyContextFactory.getInitialContext(MyContextFactory.java:20)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
at MyContextFactory.<init>(MyContextFactory.java:20)
at MyContextFactory.getInitialContext(MyContextFactory.java:20)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
...
我可以通过创建一个 "environment" 哈希表,将 MyContextFactory
class 的名称放在那里(在 "java.naming.factory.initial" 键下)然后创建InitialContext 使用接受 Hashtable 环境的构造函数:
Context context = new InitialContext(environment);
但我的问题是:如何使用无参数构造函数并在调用 JVM 时使用“-Djava.naming.factory.initial”提供工厂名称 class 来完成这项工作?
感谢 Jim Garrison 的建议,这里是答案。
问题的症结在于MyContext
class.
的构造函数中调用了super(true);
class MyContext extends InitialContext {
private Hashtable store;
public MyContext(Hashtable store) throws NamingException {
super(true);
this.store = store;
}
@Override
public void bind(String name, Object obj) {
store.put(name, obj);
}
@Override
public Object lookup(String name) {
return store.get(name);
}
}
public class FooMain {
private static final int ANSWER = 42;
private static final String JNDI_NAME = "/config/theAnswerToEverything";
public static void main (String args[]) throws NamingException {
Context context = new InitialContext();
putInContext( JNDI_NAME, ANSWER);
int answer = retrieveFromContext(JNDI_NAME);
Assert.assertEquals(ANSWER, answer);
System.out.printf("%d\n", answer);
}
private static void putInContext(final String key, final Object value) throws NamingException {
Context context = new InitialContext();
context.bind(key, value);
}
private static int retrieveFromContext(final String key) throws NamingException {
Context context = new InitialContext();
return (int) context.lookup(key);
}
}
public class MyContextFactory implements InitialContextFactory {
private static Hashtable store = new Hashtable();
/*
Do not confuse [store] with [environment]. They serve different
purposes.
*/
@Override
public Context getInitialContext(Hashtable environment) throws NamingException {
return new MyContext(store);
}
}
从命令行调用:
$ java -Djava.naming.factory.initial=MyContextFactory -cp [actual classpath] FooMain
42
我正在尝试为 Java SE 控制台应用程序设置 JNDI。
我有以下代码:
public class FooMain {
public static void main (String args[]) throws NamingException {
Context context = new InitialContext();
context.bind("foo", "bar");
}
}
…上下文工厂定义为:
public class MyContextFactory implements InitialContextFactory {
private static Hashtable store = new Hashtable();
@Override
public Context getInitialContext(Hashtable environment) throws NamingException {
return new InitialContext() {
@Override
public void bind(String name, Object obj) {
store.put(name, obj);
}
@Override
public Object lookup(String name) {
return store.get(name);
}
};
}
}
当我调用我的 FooMain
class 时使用:
java -Djava.naming.factory.initial=MyContextFactory -cp ... FooMain
我得到了无限递归和最终的 Whosebug 异常:
Exception in thread "main" java.lang.WhosebugError
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.naming.internal.VersionHelper12.getContextClassLoader(VersionHelper12.java:185)
at com.sun.naming.internal.ResourceManager.getApplicationResources(ResourceManager.java:549)
at com.sun.naming.internal.ResourceManager.getInitialEnvironment(ResourceManager.java:244)
at javax.naming.InitialContext.init(InitialContext.java:240)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
at MyContextFactory.<init>(MyContextFactory.java:20)
at MyContextFactory.getInitialContext(MyContextFactory.java:20)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
at MyContextFactory.<init>(MyContextFactory.java:20)
at MyContextFactory.getInitialContext(MyContextFactory.java:20)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
at MyContextFactory.<init>(MyContextFactory.java:20)
at MyContextFactory.getInitialContext(MyContextFactory.java:20)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
...
我可以通过创建一个 "environment" 哈希表,将 MyContextFactory
class 的名称放在那里(在 "java.naming.factory.initial" 键下)然后创建InitialContext 使用接受 Hashtable 环境的构造函数:
Context context = new InitialContext(environment);
但我的问题是:如何使用无参数构造函数并在调用 JVM 时使用“-Djava.naming.factory.initial”提供工厂名称 class 来完成这项工作?
感谢 Jim Garrison 的建议,这里是答案。
问题的症结在于MyContext
class.
super(true);
class MyContext extends InitialContext {
private Hashtable store;
public MyContext(Hashtable store) throws NamingException {
super(true);
this.store = store;
}
@Override
public void bind(String name, Object obj) {
store.put(name, obj);
}
@Override
public Object lookup(String name) {
return store.get(name);
}
}
public class FooMain {
private static final int ANSWER = 42;
private static final String JNDI_NAME = "/config/theAnswerToEverything";
public static void main (String args[]) throws NamingException {
Context context = new InitialContext();
putInContext( JNDI_NAME, ANSWER);
int answer = retrieveFromContext(JNDI_NAME);
Assert.assertEquals(ANSWER, answer);
System.out.printf("%d\n", answer);
}
private static void putInContext(final String key, final Object value) throws NamingException {
Context context = new InitialContext();
context.bind(key, value);
}
private static int retrieveFromContext(final String key) throws NamingException {
Context context = new InitialContext();
return (int) context.lookup(key);
}
}
public class MyContextFactory implements InitialContextFactory {
private static Hashtable store = new Hashtable();
/*
Do not confuse [store] with [environment]. They serve different
purposes.
*/
@Override
public Context getInitialContext(Hashtable environment) throws NamingException {
return new MyContext(store);
}
}
从命令行调用:
$ java -Djava.naming.factory.initial=MyContextFactory -cp [actual classpath] FooMain
42