在Tomcat上查找java:comp/env之外的JNDI名称?

在Tomcat上查找java:comp/env之外的JNDI名称?,java,tomcat,jndi,Java,Tomcat,Jndi,我正在使用一个最初为IBMWebSphere设计的应用程序,但我也想将其托管在Tomcat上。该应用程序无法更改,正在执行新的InitialContext().lookup(“servername”),该操作可在WebSphere上运行 但是在Tomcat上,当我在特定于应用程序的上下文xml中指定名称时,它们的前缀是java:comp/env,而上述查找没有找到这些名称 它将在一个容器中运行,因此如果有必要,可以更新server.xml,当然也可以更新特定于应用程序的上下文xml 如何让Tom

我正在使用一个最初为IBMWebSphere设计的应用程序,但我也想将其托管在Tomcat上。该应用程序无法更改,正在执行
新的InitialContext().lookup(“servername”)
,该操作可在WebSphere上运行

但是在Tomcat上,当我在特定于应用程序的上下文xml中指定
名称时,它们的前缀是
java:comp/env
,而上述查找没有找到这些名称

它将在一个容器中运行,因此如果有必要,可以更新
server.xml
,当然也可以更新特定于应用程序的上下文xml


如何让Tomcat在
查找(“服务器名”)
时返回字符串?

看起来Tomcat的行为是硬编码的


但它不必一直这样。加入团队,询问事情之所以如此,是否有特殊原因。如果没有具体原因将环境条目限制在
java:comp/env
名称空间中,那么我怀疑代码更改(可能涉及新的配置选项)肯定是可能的。

看起来Tomcat是硬编码的,以这种方式工作


但它不必一直这样。加入团队,询问事情之所以如此,是否有特殊原因。如果没有具体的理由将环境条目限制在
java:comp/env
命名空间中,那么我怀疑代码更改(可能涉及新的配置选项)是绝对可能的。

作为一种黑客行为,我创建了这个InitialContextFactory,它只是将字符串名称的查找委托给
System.getenv()
(环境变量)。这是非常不安全的,并且会破坏正确使用命名的应用程序,所以我不建议将其用于生产或特定用例之外。或者对任何人来说真的

然而,通过使用它,我能够通过命令行上的
设置servername=blah
获取
(String)new InitialContext().lookup(“servername”)
以返回特定值
blah

import java.util.Hashtable;

import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;

public class EnvironmentInitialContextFactory implements InitialContextFactory {


    public Context getInitialContext(Hashtable<?,?> environment) throws NamingException {

        return new Context() {

            public Object lookup(String name) throws NamingException {

                return System.getenv(name);

            }

            public Object lookup(Name name) throws NamingException { return null; }
            public void bind(Name name, Object obj) throws NamingException {}
            public void bind(String name, Object obj) throws NamingException {}
            public void rebind(Name name, Object obj) throws NamingException {}
            public void rebind(String name, Object obj) throws NamingException {}
            public void unbind(Name name) throws NamingException {}
            public void unbind(String name) throws NamingException {}
            public void rename(Name oldName, Name newName) throws NamingException {}
            public void rename(String oldName, String newName) throws NamingException {}
            public NamingEnumeration<NameClassPair> list(Name name) throws NamingException { return null; }
            public NamingEnumeration<NameClassPair> list(String name) throws NamingException { return null; }
            public NamingEnumeration<Binding> listBindings(Name name) throws NamingException { return null; }
            public NamingEnumeration<Binding> listBindings(String name) throws NamingException { return null; }
            public void destroySubcontext(Name name) throws NamingException {}
            public void destroySubcontext(String name) throws NamingException {}
            public Context createSubcontext(Name name) throws NamingException { return null; }            
            public Context createSubcontext(String name) throws NamingException { return null; }
            public Object lookupLink(Name name) throws NamingException { return null; }
            public Object lookupLink(String name) throws NamingException { return null; }
            public NameParser getNameParser(Name name) throws NamingException { return null; }
            public NameParser getNameParser(String name) throws NamingException { return null; }
            public Name composeName(Name name, Name prefix) throws NamingException { return null; }
            public String composeName(String name, String prefix) throws NamingException { return null; }
            public Object addToEnvironment(String propName, Object propVal) throws NamingException { return null; }
            public Object removeFromEnvironment(String propName) throws NamingException { return null; }
            public Hashtable<?, ?> getEnvironment() throws NamingException { return null; }
            public void close() throws NamingException {}
            public String getNameInNamespace() throws NamingException { return null; }

        };

    }

}

作为黑客,我创建了这个InitialContextFactory,它只是将字符串名称的查找委托给
System.getenv()
(环境变量)。这是非常不安全的,并且会破坏正确使用命名的应用程序,所以我不建议将其用于生产或特定用例之外。或者对任何人来说真的

然而,通过使用它,我能够通过命令行上的
设置servername=blah
获取
(String)new InitialContext().lookup(“servername”)
以返回特定值
blah

import java.util.Hashtable;

import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;

public class EnvironmentInitialContextFactory implements InitialContextFactory {


    public Context getInitialContext(Hashtable<?,?> environment) throws NamingException {

        return new Context() {

            public Object lookup(String name) throws NamingException {

                return System.getenv(name);

            }

            public Object lookup(Name name) throws NamingException { return null; }
            public void bind(Name name, Object obj) throws NamingException {}
            public void bind(String name, Object obj) throws NamingException {}
            public void rebind(Name name, Object obj) throws NamingException {}
            public void rebind(String name, Object obj) throws NamingException {}
            public void unbind(Name name) throws NamingException {}
            public void unbind(String name) throws NamingException {}
            public void rename(Name oldName, Name newName) throws NamingException {}
            public void rename(String oldName, String newName) throws NamingException {}
            public NamingEnumeration<NameClassPair> list(Name name) throws NamingException { return null; }
            public NamingEnumeration<NameClassPair> list(String name) throws NamingException { return null; }
            public NamingEnumeration<Binding> listBindings(Name name) throws NamingException { return null; }
            public NamingEnumeration<Binding> listBindings(String name) throws NamingException { return null; }
            public void destroySubcontext(Name name) throws NamingException {}
            public void destroySubcontext(String name) throws NamingException {}
            public Context createSubcontext(Name name) throws NamingException { return null; }            
            public Context createSubcontext(String name) throws NamingException { return null; }
            public Object lookupLink(Name name) throws NamingException { return null; }
            public Object lookupLink(String name) throws NamingException { return null; }
            public NameParser getNameParser(Name name) throws NamingException { return null; }
            public NameParser getNameParser(String name) throws NamingException { return null; }
            public Name composeName(Name name, Name prefix) throws NamingException { return null; }
            public String composeName(String name, String prefix) throws NamingException { return null; }
            public Object addToEnvironment(String propName, Object propVal) throws NamingException { return null; }
            public Object removeFromEnvironment(String propName) throws NamingException { return null; }
            public Hashtable<?, ?> getEnvironment() throws NamingException { return null; }
            public void close() throws NamingException {}
            public String getNameInNamespace() throws NamingException { return null; }

        };

    }

}
我正在重温这个(我是询问者)。受此启发,我决定实现一个
ServletContextListener

总之,您不能让Tomcat将环境资源放在
java:comp/env/
之外,但您可以从那里读取它们,并在“任何地方”重新分配它们

初始化ServletContext时,我的侦听器只是重新绑定它们:

@覆盖
公共void contextInitialized(ServletContextEvent ServletContextEvent){
Context ctx=新的InitialContext();
bind(“servername”,ctx.lookup(“java:comp/env/servername”);
}
这是一个更好的解决方案——它不会处理部署上下文之外的任何内容

也可能只需重新绑定
comp/env/
命名空间中的所有名称,以创建更通用的侦听器。目前,我只是绑定单个名称,因为应用程序使用的名称很少。

我正在重新讨论这个问题(我是询问者)。受此启发,我决定实现一个
ServletContextListener

总之,您不能让Tomcat将环境资源放在
java:comp/env/
之外,但您可以从那里读取它们,并在“任何地方”重新分配它们

初始化ServletContext时,我的侦听器只是重新绑定它们:

@覆盖
公共void contextInitialized(ServletContextEvent ServletContextEvent){
Context ctx=新的InitialContext();
bind(“servername”,ctx.lookup(“java:comp/env/servername”);
}
这是一个更好的解决方案——它不会处理部署上下文之外的任何内容


也可能只需重新绑定
comp/env/
命名空间中的所有名称,以创建更通用的侦听器。现在我只是绑定单个名称,因为应用程序很少使用这些名称。

。我在中看到的唯一一件事实际上是在任何JNDI名称上丢弃
java:comp/env
前缀。我看不出有什么地方添加了它。这可能是因为Tomcat提供了一个简单的JNDI上下文,而不是EJB容器提供的工业级JNDI上下文,我可能没有假设整个字符串在源代码中是连续的:)我试图实现一个自定义
InitialContextFactory
作为一种解决方法。我可以让Tomcat使用它,但我还不能让它在
java:comp/env
上返回
上下文。如果我能让它运行,我会把代码作为答案发布。奇怪。我在中看到的唯一一件事实际上是在任何JNDI名称上丢弃
java:comp/env
前缀。我看不出有什么地方添加了它。这可能是因为Tomcat提供了一个简单的JNDI上下文,而不是EJB容器提供的工业级JNDI上下文,我可能没有假设整个字符串在源代码中是连续的:)我试图实现一个自定义
InitialContextFactory
作为一种解决方法。我可以让Tomcat使用它,但我还不能让它在
java:comp/env
上返回
上下文。如果我能让它运行,我会发布代码作为答案。我