简体   繁体   English

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

[英]Lookup JNDI names outside of java:comp/env on Tomcat?

I am working with an application originally designed for IBM WebSphere, but I want to also host it on Tomcat. 我正在使用最初为IBM WebSphere设计的应用程序,但我也希望将其托管在Tomcat上。 The application cannot be changed, and is doing a new InitialContext().lookup("servername") , which works on WebSphere. 该应用程序无法更改,并且正在执行一个new InitialContext().lookup("servername") ,它可以在WebSphere上运行。

But on Tomcat, when I specify <Environment> names in the application specific context xml they are prefixed with java:comp/env , and the names aren't found by the above lookup. 但是在Tomcat上,当我在特定于应用程序的上下文xml中指定<Environment>名称时,它们以java:comp/env为前缀,并且上述查找找不到这些名称。

It will run in a container, so there's no problem to update server.xml if I have to, and of course, the application specific context xml. 它将在容器中运行,因此,如果需要,并且当然是针对应用程序的特定上下文xml,则更新server.xml也没有问题。

How can I get Tomcat to return a string on lookup("servername") ? 如何获得Tomcat在lookup("servername")上返回字符串?

It looks like Tomcat is hard-coded to behave in this way. 看起来Tomcat已硬编码为以这种方式运行。

But it doesn't have to stay that way. 但这并不一定要坚持下去。 Join the Tomcat user's mailing list and ask if there is a particular reason why things are the way they are. 加入Tomcat用户的邮件列表 ,询问是否有某种特定的原因。 If there are no specific reasons to limit environment entries to the java:comp/env namespace, then I suspect a code change (probably involving a new configuration option) is definitely possible. 如果没有特殊原因将环境条目限制为java:comp/env命名空间,那么我怀疑代码更改(可能涉及新的配置选项)肯定是可能的。

As a hack, I created this InitialContextFactory, which simply delegates the looking up of String names to System.getenv() (Environment variables). 作为一种技巧,我创建了这个InitialContextFactory,它只是将对String名称的查找委托给System.getenv() (环境变量)。 This is very insecure, and will break apps which use naming properly, so I wouldn't recommend this for Production or outside of specific use cases. 这是非常不安全的,会破坏正确使用命名的应用程序,因此我不建议在生产环境或特定用例之外使用此功能。 Or to any one at all really. 或真的对任何一个人。

Nevertheless, by using this, I was able to get (String) new InitialContext().lookup("servername") to return a specific value blah via set servername=blah at the command line. 然而,通过使用这个,我能得到(String) new InitialContext().lookup("servername")返回一个特定的值blah通过set 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; }

        };

    }

}

Compile the class, and add it to the CLASSPATH and system properties, by adding these lines to setenv.bat (create in %CATALINA_HOME%/bin/ ): 通过将以setenv.bat添加到setenv.bat (在%CATALINA_HOME%/bin/创建),编译该类并将其添加到CLASSPATH和系统属性中:

set CLASSPATH=C:\path\to\compiled\class
set CATALINA_OPTS=-Djava.naming.factory.initial=EnvironmentInitialContextFactory

I'm revisiting this (I'm the asker). 我正在重新审视(我是问问者)。 Inspired by this answer , I decided to implement a ServletContextListener instead. 受此答案的启发,我决定改为实现ServletContextListener

In summary, you can't make Tomcat put the environment resources outside of java:comp/env/ but you can read them from there and reassign them "wherever". 总之,您不能使Tomcat将环境资源放置在java:comp/env/之外,但是您可以从那里读取它们,然后在“任何地方”重新分配它们。

When the ServletContext is initialized, my listener just rebinds them: 初始化ServletContext后,我的侦听器将它们重新绑定:

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        Context ctx = new InitialContext();
        ctx.bind("servername", ctx.lookup("java:comp/env/servername"));
    }

This is a much better solution - it doesn't fiddle with anything outside of the deployment context. 这是一个更好的解决方案-它不会摆弄部署上下文之外的任何内容。

It's probably also possible to just rebind all names in the comp/env/ namespace, to make a more generic listener. 也可以只重新绑定comp/env/名称空间中的所有名称,以创建更通用的侦听器。 For now I am just binding the single names as there are few used by the app. 目前,我仅绑定单个名称,因为该应用程序使用的名称很少。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Tomcat 中的 jndi 资源没有 java:/comp/env/ 前缀 - jndi resource in Tomcat without java:/comp/env/ prefix InitialContext 查找(“java:comp/env”)失败 - InitialContext lookup(“java:comp/env”) fails 在单元测试中,SerialContext中的“ java:comp / env”的Tomcat -Hudson-查找失败 - Tomcat -Hudson- Lookup failed for 'java:comp/env' in SerialContext in Unit tests glassfish-4 + spring jndi名称java:comp / env / jdbc / - glassfish-4 + spring jndi name java:comp/env/jdbc/ 如何在 Glassfish 4.1 中设置 java:comp/env/foo JNDI 变量? - How to set a java:comp/env/foo JNDI variable in Glassfish 4.1? 访问不带java:comp / env前缀的JNDI DataSource - Accessing a JNDI DataSource without the java:comp/env prefix Java JNDI查找名称兼容的Tomcat&Weblogic - Java JNDI lookup name compatible Tomcat & Weblogic java:comp / env未绑定 - java:comp/env is not bound 不使用web.xml时如何将JDBC数据源绑定到JNDI上下文“ java:comp / env / jdbc” - How to bind a JDBC datasource to JNDI context “java:comp/env/jdbc” when not to use web.xml 无法在Liberty中实例化java:comp / env / HRONLINEFSDEV2 JNDI名称引用的对象 - The object referenced by the java:comp/env/HRONLINEFSDEV2 JNDI name could not be instantiated in Liberty
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM